diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index 0644e2dff6..e77875d69a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -123,6 +123,8 @@ namespace void D3D12GSRender::clear_surface(u32 arg) { + if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) return; + std::chrono::time_point start_duration = std::chrono::system_clock::now(); std::chrono::time_point rtt_duration_start = std::chrono::system_clock::now(); diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index eea02008a4..72dea64d18 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -453,6 +453,7 @@ void GLGSRender::on_exit() void nv4097_clear_surface(u32 arg, GLGSRender* renderer) { //LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg); + if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) return; if ((arg & 0xf3) == 0) { diff --git a/rpcs3/Emu/RSX/GL/gl_render_targets.cpp b/rpcs3/Emu/RSX/GL/gl_render_targets.cpp index 8a61bed026..346dd99038 100644 --- a/rpcs3/Emu/RSX/GL/gl_render_targets.cpp +++ b/rpcs3/Emu/RSX/GL/gl_render_targets.cpp @@ -19,6 +19,12 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma case rsx::surface_color_format::a8r8g8b8: return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; + //These formats discard their alpha component (always 1) + case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; @@ -30,13 +36,14 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma return{ ::gl::texture::type::f32, ::gl::texture::format::rgba, true, 4, 4 }; case rsx::surface_color_format::b8: - case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: - case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: - case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + return{ ::gl::texture::type::ubyte, ::gl::texture::format::red, false, 1, 1 }; + case rsx::surface_color_format::g8b8: + return{ ::gl::texture::type::ubyte, ::gl::texture::format::rg, false, 2, 1 }; + case rsx::surface_color_format::x32: - case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: - case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + return{ ::gl::texture::type::f32, ::gl::texture::format::red, false, 1, 4 }; + case rsx::surface_color_format::a8b8g8r8: default: LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index 5123f3a901..fe878ee9a6 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -149,6 +149,7 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask) return { map_table[remap_r], map_table[remap_g], map_table[remap_b], map_table[remap_a] }; } + case CELL_GCM_TEXTURE_D8R8G8B8: case CELL_GCM_TEXTURE_D1R5G5B5: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; @@ -163,7 +164,7 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask) case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO }; - case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_A8R8G8B8: { VkComponentSwizzle map_table[] = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 73919ceb96..d416c178ee 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -44,7 +44,7 @@ namespace vk case CELL_GCM_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; case CELL_GCM_GEQUAL: - return VK_COMPARE_OP_EQUAL; + return VK_COMPARE_OP_GREATER_OR_EQUAL; case CELL_GCM_EQUAL: return VK_COMPARE_OP_EQUAL; case CELL_GCM_ALWAYS: @@ -54,38 +54,51 @@ namespace vk } } - VkFormat get_compatible_surface_format(rsx::surface_color_format color_format) + std::pair get_compatible_surface_format(rsx::surface_color_format color_format) { switch (color_format) { case rsx::surface_color_format::r5g6b5: - return VK_FORMAT_R5G6B5_UNORM_PACK16; + return std::make_pair(VK_FORMAT_R5G6B5_UNORM_PACK16, vk::default_component_map()); case rsx::surface_color_format::a8r8g8b8: - return VK_FORMAT_B8G8R8A8_UNORM; + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map()); - case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: - LOG_ERROR(RSX, "Format 0x%X may be buggy.", color_format); - return VK_FORMAT_B8G8R8A8_UNORM; - - case rsx::surface_color_format::w16z16y16x16: - return VK_FORMAT_R16G16B16A16_SFLOAT; - - case rsx::surface_color_format::w32z32y32x32: - return VK_FORMAT_R32G32B32A32_SFLOAT; - - case rsx::surface_color_format::b8: - case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: - case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: - case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: - case rsx::surface_color_format::g8b8: - case rsx::surface_color_format::x32: case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: case rsx::surface_color_format::a8b8g8r8: + { + VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha); + } + + case rsx::surface_color_format::w16z16y16x16: + return std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, vk::default_component_map()); + + case rsx::surface_color_format::w32z32y32x32: + return std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, vk::default_component_map()); + + case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: + { + VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha); + } + + case rsx::surface_color_format::b8: + return std::make_pair(VK_FORMAT_R8_UNORM, vk::default_component_map()); + + case rsx::surface_color_format::g8b8: + return std::make_pair(VK_FORMAT_R8G8_UNORM, vk::default_component_map()); + + case rsx::surface_color_format::x32: + return std::make_pair(VK_FORMAT_R32_SFLOAT, vk::default_component_map()); + default: LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); - return VK_FORMAT_B8G8R8A8_UNORM; + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map()); } } @@ -546,7 +559,7 @@ namespace void VKGSRender::end() { size_t idx = vk::get_render_pass_location( - vk::get_compatible_surface_format(m_surface.color_format), + vk::get_compatible_surface_format(m_surface.color_format).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])).size()); VkRenderPass current_render_pass = m_render_passes[idx]; @@ -666,8 +679,8 @@ void VKGSRender::clear_surface(u32 mask) { //TODO: Build clear commands into current renderpass descriptor set if (!(mask & 0xF3)) return; - if (m_current_present_image== 0xFFFF) return; + if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) return; init_buffers(); @@ -875,7 +888,7 @@ bool VKGSRender::load_program() properties.ds.depthTestEnable = VK_FALSE; size_t idx = vk::get_render_pass_location( - vk::get_compatible_surface_format(m_surface.color_format), + vk::get_compatible_surface_format(m_surface.color_format).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])).size()); properties.render_pass = m_render_passes[idx]; @@ -1085,7 +1098,7 @@ void VKGSRender::prepare_rtts() fbo_images.push_back(std::make_unique(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres)); } - size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(m_surface.color_format), vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)draw_buffers.size()); + size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(m_surface.color_format).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)draw_buffers.size()); VkRenderPass current_render_pass = m_render_passes[idx]; m_framebuffer_to_clean.push_back(std::make_unique(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images))); diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 3a64404897..f8d3d2e53b 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -66,7 +66,7 @@ namespace vk void copy_scaled_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_width, u32 src_height, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect); VkFormat get_compatible_sampler_format(u32 format); - VkFormat get_compatible_surface_format(rsx::surface_color_format color_format); + std::pair get_compatible_surface_format(rsx::surface_color_format color_format); size_t get_render_pass_location(VkFormat color_surface_format, VkFormat depth_stencil_format, u8 color_surface_count); struct memory_type_mapping @@ -336,6 +336,7 @@ namespace vk struct image { VkImage value; + VkComponentMapping native_layout = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}; VkImageCreateInfo info = {}; std::shared_ptr memory; @@ -569,7 +570,7 @@ namespace vk info.minFilter = min_filter; info.mipmapMode = mipmap_mode; info.compareOp = VK_COMPARE_OP_NEVER; - info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; + info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; CHECK_RESULT(vkCreateSampler(m_device, &info, nullptr, &value)); } diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 3d282589fb..56dfde49d6 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -17,7 +17,8 @@ namespace rsx static std::unique_ptr create_new_surface(u32 address, surface_color_format format, size_t width, size_t height, vk::render_device &device, vk::command_buffer *cmd, const vk::gpu_formats_support &support, const vk::memory_type_mapping &mem_mapping) { - VkFormat requested_format = vk::get_compatible_surface_format(format); + auto fmt = vk::get_compatible_surface_format(format); + VkFormat requested_format = fmt.first; std::unique_ptr rtt; rtt.reset(new vk::image(device, mem_mapping.device_local, @@ -42,6 +43,7 @@ namespace rsx vkCmdClearColorImage(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)); + rtt->native_layout = fmt.second; return rtt; } @@ -93,7 +95,7 @@ namespace rsx static bool rtt_has_format_width_height(const std::unique_ptr &rtt, surface_color_format format, size_t width, size_t height) { - VkFormat fmt = vk::get_compatible_surface_format(format); + VkFormat fmt = vk::get_compatible_surface_format(format).first; if (rtt->info.format == fmt && rtt->info.extent.width == width && diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 6bac1c1db4..e9f16b0fc4 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -159,7 +159,7 @@ namespace vk if (rtt_texture = m_rtts.get_texture_from_render_target_if_applicable(texaddr)) { m_temporary_image_view.push_back(std::make_unique(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format, - vk::default_component_map(), + rtt_texture->native_layout, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT))); return m_temporary_image_view.back().get(); } diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index 26a63c3443..32c84527e4 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -125,9 +125,13 @@ static const reg_info reg_table[] = { "gl_ClipDistance[1]", false, "dst_reg5", ".z", false }, { "gl_ClipDistance[2]", false, "dst_reg5", ".w", false }, { "gl_PointSize", false, "dst_reg6", ".x", false }, - { "gl_ClipDistance[3]", false, "dst_reg6", ".y", false }, - { "gl_ClipDistance[4]", false, "dst_reg6", ".z", false }, - { "gl_ClipDistance[5]", false, "dst_reg6", ".w", false }, + + //Disable user clip planes until they are properly handled + + //{ "gl_ClipDistance[3]", false, "dst_reg6", ".y", false }, + //{ "gl_ClipDistance[4]", false, "dst_reg6", ".z", false }, + //{ "gl_ClipDistance[5]", false, "dst_reg6", ".w", false }, + { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false }, { "tc2", true, "dst_reg9", "", false },