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
This commit is contained in:
kd-11 2016-08-03 22:33:52 +03:00 committed by raven02
parent 9a081369c8
commit 47a9c8d731
3 changed files with 33 additions and 17 deletions

View File

@ -295,7 +295,11 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
} }
else 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()) 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_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";
{
finalize += "\tgl_FragDepth = r1.z;\n";
}
}
else
{
if (shader.temporary_registers.find({ "h2" }) != shader.temporary_registers.end())
{
finalize += "\tgl_FragDepth = h2.z;\n";
}
} }
} }

View File

@ -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); 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; 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; VkFilter min_filter;
VkSamplerMipmapMode mip_mode; VkSamplerMipmapMode mip_mode;
std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(rsx::method_registers.fragment_textures[i].min_filter()); 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<vk::sampler>( m_sampler_to_clean.push_back(std::make_unique<vk::sampler>(
*m_device, *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()), 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(), 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()) 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); 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);
} }
} }

View File

@ -192,9 +192,9 @@ namespace vk
VkImageType image_type; VkImageType image_type;
VkImageViewType image_view_type; VkImageViewType image_view_type;
u16 height; u16 height = 0;
u16 depth; u16 depth = 0;
u8 layer; u8 layer = 0;
switch (tex.get_extended_texture_dimension()) switch (tex.get_extended_texture_dimension())
{ {
case rsx::texture_dimension_extended::texture_dimension_1d: case rsx::texture_dimension_extended::texture_dimension_1d:
@ -221,6 +221,7 @@ namespace vk
case rsx::texture_dimension_extended::texture_dimension_3d: case rsx::texture_dimension_extended::texture_dimension_3d:
image_type = VK_IMAGE_TYPE_3D; image_type = VK_IMAGE_TYPE_3D;
image_view_type = VK_IMAGE_VIEW_TYPE_3D; image_view_type = VK_IMAGE_VIEW_TYPE_3D;
height = tex.height();
depth = tex.depth(); depth = tex.depth();
layer = 1; layer = 1;
break; break;
@ -229,6 +230,13 @@ namespace vk
bool is_cubemap = tex.get_extended_texture_dimension() == rsx::texture_dimension_extended::texture_dimension_cubemap; 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); 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::image>(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, cto.uploaded_texture = std::make_unique<vk::image>(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image_type, image_type,
vk_format, vk_format,