diff --git a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h index 544bfed522..59d1e4b751 100644 --- a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h +++ b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h @@ -69,7 +69,12 @@ public: template size_t alloc(size_t size) { - if (!can_alloc(size)) fmt::throw_exception("Working buffer not big enough" HERE); + if (!can_alloc(size)) + { + fmt::throw_exception("Working buffer not big enough, buffer_length=%d allocated=%d requested=%d guard=%d largest_pool=%d" HERE, + m_size, m_current_allocated_size, size, m_min_guard_size, m_largest_allocated_pool); + } + size_t alloc_size = align(size, Alignement); size_t aligned_put_pos = align(m_put_pos, Alignement); diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 3123fe0c26..54bdabea78 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -487,7 +487,7 @@ void GLGSRender::on_init_thread() LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)); LOG_NOTICE(RSX, "%s", (const char*)glGetString(GL_VENDOR)); - auto gl_caps = gl::get_driver_caps(); + auto& gl_caps = gl::get_driver_caps(); if (!gl_caps.ARB_texture_buffer_supported) { @@ -499,6 +499,11 @@ void GLGSRender::on_init_thread() fmt::throw_exception("Failed to initialize OpenGL renderer. ARB_direct_state_access or EXT_direct_state_access is required but not supported by your GPU"); } + if (!gl_caps.ARB_depth_buffer_float_supported && g_cfg.video.force_high_precision_z_buffer) + { + LOG_WARNING(RSX, "High precision Z buffer requested but your GPU does not support GL_ARB_depth_buffer_float. Option ignored."); + } + //Use industry standard resource alignment values as defaults m_uniform_buffer_offset_align = 256; m_min_texbuffer_alignment = 256; diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 2ababf9054..9ccabb4a3f 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -78,11 +78,12 @@ namespace gl bool ARB_buffer_storage_supported = false; bool ARB_texture_buffer_supported = false; bool ARB_shader_draw_parameters_supported = false; + bool ARB_depth_buffer_float_supported = false; bool initialized = false; void initialize() { - int find_count = 5; + int find_count = 6; int ext_count = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &ext_count); @@ -127,6 +128,13 @@ namespace gl find_count --; continue; } + + if (ext_name == "GL_ARB_depth_buffer_float") + { + ARB_depth_buffer_float_supported = true; + find_count--; + continue; + } } //Workaround for intel drivers which have terrible capability reporting @@ -1137,7 +1145,7 @@ namespace gl uint_10_10_10_2 = GL_UNSIGNED_INT_10_10_10_2, uint_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV, uint_24_8 = GL_UNSIGNED_INT_24_8, - float32z_s8int = GL_DEPTH32F_STENCIL8, + float32_uint8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV, sbyte = GL_BYTE, sshort = GL_SHORT, diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 4c7502c231..e83e160761 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -57,8 +57,8 @@ depth_format rsx::internals::surface_depth_format_to_gl(rsx::surface_depth_forma default: LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", (u32)depth_format); case rsx::surface_depth_format::z24s8: - if (g_cfg.video.force_high_precision_z_buffer) - return{ ::gl::texture::type::float32z_s8int, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth32f_stencil8 }; + if (g_cfg.video.force_high_precision_z_buffer && ::gl::get_driver_caps().ARB_depth_buffer_float_supported) + return{ ::gl::texture::type::float32_uint8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth32f_stencil8 }; else return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth24_stencil8 }; } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 270b4ffb77..afb9438da9 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -959,6 +959,22 @@ void VKGSRender::end() vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline); vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_sets, 0, nullptr); + if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil)) + { + if (ds->dirty) + { + //Clear this surface before drawing on it + VkClearValue depth_clear_value; + depth_clear_value.depthStencil.depth = 1.f; + depth_clear_value.depthStencil.stencil = 255; + + VkClearRect clear_rect = { 0, 0, m_framebuffer_to_clean.back()->width(), m_framebuffer_to_clean.back()->height(), 0, 1 }; + VkClearAttachment clear_desc = { ds->attachment_aspect_flag, 0, depth_clear_value }; + vkCmdClearAttachments(*m_current_command_buffer, 1, &clear_desc, 1, &clear_rect); + ds->dirty = false; + } + } + std::optional > index_info = std::get<2>(upload_info); if (!index_info) @@ -1141,6 +1157,12 @@ void VKGSRender::clear_surface(u32 mask) vkCmdClearAttachments(*m_current_command_buffer, (u32)clear_descriptors.size(), clear_descriptors.data(), (u32)clear_regions.size(), clear_regions.data()); vkCmdEndRenderPass(*m_current_command_buffer); + + if (mask & 0x3) + { + if (std::get<0>(m_rtts.m_bound_depth_stencil) != 0) + std::get<1>(m_rtts.m_bound_depth_stencil)->dirty = false; + } } void VKGSRender::sync_at_semaphore_release() diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 68f8e5f26c..09d07fa3b9 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -11,6 +11,7 @@ namespace vk { struct render_target : public image { + bool dirty = false; u16 native_pitch = 0; VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT; @@ -143,19 +144,9 @@ namespace rsx static void invalidate_rtt_surface_contents(vk::command_buffer*, vk::render_target*) {} - static void invalidate_depth_surface_contents(vk::command_buffer* pcmd, vk::render_target *ds) + static void invalidate_depth_surface_contents(vk::command_buffer* /*pcmd*/, vk::render_target *ds) { - VkImageLayout old_layout = ds->current_layout; - VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, ds->attachment_aspect_flag); - change_image_layout(*pcmd, ds, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range); - - //Clear the surface before drawing on it - VkClearDepthStencilValue clear_depth = {}; - clear_depth.depth = 1.f; - clear_depth.stencil = 255; - - vkCmdClearDepthStencilImage(*pcmd, ds->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_depth, 1, &range); - change_image_layout(*pcmd, ds, old_layout, range); + ds->dirty = true; } static bool rtt_has_format_width_height(const std::unique_ptr &rtt, surface_color_format format, size_t width, size_t height)