From 47a9c8d731b346837013a84d30fd8c5793e4adc9 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 3 Aug 2016 22:33:52 +0300 Subject: [PATCH] vk/gl: bug fixes (#2018) * vk: use null sampler for invalid/broken texture configurations * gl: Do not consider 32_BIT_EXPORTS flag for depth writes --- rpcs3/Emu/RSX/GL/rsx_gl_cache.cpp | 24 +++++++++++------------- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 12 +++++++++++- rpcs3/Emu/RSX/VK/VKTextureCache.h | 14 +++++++++++--- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_cache.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_cache.cpp index bf47b97616..663644aed5 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_cache.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_cache.cpp @@ -295,7 +295,11 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader, } else { - finalize += "\tocol = h0;\n"; + if (shader.temporary_registers.find({ "h0" }) != shader.temporary_registers.end()) + { + //Some shaders only write to gl_FragDepth and ignore color output + finalize += "\tocol = h0;\n"; + } if (shader.temporary_registers.find({ "h4" }) != shader.temporary_registers.end()) { @@ -316,19 +320,13 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader, if (state.ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) { - if (state.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) + //@NOTE: Checking for CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS to determine whether to read 16f or 32f depth is incorrect (always seems to be r1.z) + //Resogun shows this behaviour as well as Naruto UNS2 + //See also D3D12FragmentProgramDecompiler.cpp + + if (shader.temporary_registers.find({ "r1" }) != shader.temporary_registers.end()) { - if (shader.temporary_registers.find({ "r1" }) != shader.temporary_registers.end()) - { - finalize += "\tgl_FragDepth = r1.z;\n"; - } - } - else - { - if (shader.temporary_registers.find({ "h2" }) != shader.temporary_registers.end()) - { - finalize += "\tgl_FragDepth = h2.z;\n"; - } + finalize += "\tgl_FragDepth = r1.z;\n"; } } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 7ba33ce625..a8a3c7334d 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -631,11 +631,20 @@ void VKGSRender::end() m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets); continue; } - vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, rsx::method_registers.fragment_textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get()); + + vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, rsx::method_registers.fragment_textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get()); + + if (!texture0) + { + LOG_ERROR(RSX, "Texture upload failed to texture index %d. Binding null sampler.", i); + m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets); + continue; + } VkFilter min_filter; VkSamplerMipmapMode mip_mode; std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(rsx::method_registers.fragment_textures[i].min_filter()); + m_sampler_to_clean.push_back(std::make_unique( *m_device, vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_s()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_t()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_r()), @@ -643,6 +652,7 @@ void VKGSRender::end() rsx::method_registers.fragment_textures[i].bias(), vk::max_aniso(rsx::method_registers.fragment_textures[i].max_aniso()), rsx::method_registers.fragment_textures[i].min_lod(), rsx::method_registers.fragment_textures[i].max_lod(), min_filter, vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter()), mip_mode, vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color()) )); + m_program->bind_uniform({ m_sampler_to_clean.back()->value, texture0->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets); } } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 45304825a4..aede466763 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -192,9 +192,9 @@ namespace vk VkImageType image_type; VkImageViewType image_view_type; - u16 height; - u16 depth; - u8 layer; + u16 height = 0; + u16 depth = 0; + u8 layer = 0; switch (tex.get_extended_texture_dimension()) { case rsx::texture_dimension_extended::texture_dimension_1d: @@ -221,6 +221,7 @@ namespace vk case rsx::texture_dimension_extended::texture_dimension_3d: image_type = VK_IMAGE_TYPE_3D; image_view_type = VK_IMAGE_VIEW_TYPE_3D; + height = tex.height(); depth = tex.depth(); layer = 1; break; @@ -229,6 +230,13 @@ namespace vk bool is_cubemap = tex.get_extended_texture_dimension() == rsx::texture_dimension_extended::texture_dimension_cubemap; VkImageSubresourceRange subresource_range = vk::get_image_subresource_range(0, 0, is_cubemap ? 6 : 1, tex.get_exact_mipmap_count(), VK_IMAGE_ASPECT_COLOR_BIT); + //If for some reason invalid dimensions are requested, fail + if (!height || !depth || !layer || !tex.width()) + { + LOG_ERROR(RSX, "Texture upload requested but invalid texture dimensions passed"); + return nullptr; + } + cto.uploaded_texture = std::make_unique(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image_type, vk_format,