Explorar el Código

Merge pull request #7070 from FernandoS27/want-you-bad

Vulkan Rasterizer: Correct DepthBias/PolygonOffset on Vulkan.
Ameer J hace 4 años
padre
commit
494e34af6a

+ 3 - 0
src/video_core/dirty_flags.h

@@ -38,6 +38,9 @@ enum : u8 {
 
     Shaders,
 
+    // Special entries
+    DepthBiasGlobal,
+
     LastCommonEntry,
 };
 

+ 14 - 2
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@@ -627,9 +627,21 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
     if (!state_tracker.TouchDepthBias()) {
         return;
     }
-    scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp,
+    float units = regs.polygon_offset_units / 2.0f;
+    const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM ||
+                        regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM ||
+                        regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM ||
+                        regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM;
+    if (is_d24 && !device.SupportsD24DepthBuffer()) {
+        // the base formulas can be obtained from here:
+        //   https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
+        const double rescale_factor =
+            static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
+        units = static_cast<float>(static_cast<double>(units) * rescale_factor);
+    }
+    scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp,
                       factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) {
-        cmdbuf.SetDepthBias(constant, clamp, factor / 2.0f);
+        cmdbuf.SetDepthBias(constant, clamp, factor);
     });
 }
 

+ 2 - 1
src/video_core/renderer_vulkan/vk_state_tracker.h

@@ -79,7 +79,8 @@ public:
     }
 
     bool TouchDepthBias() {
-        return Exchange(Dirty::DepthBias, false);
+        return Exchange(Dirty::DepthBias, false) ||
+               Exchange(VideoCommon::Dirty::DepthBiasGlobal, false);
     }
 
     bool TouchBlendConstants() {

+ 3 - 0
src/video_core/texture_cache/texture_cache.h

@@ -221,6 +221,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
         BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
     }
     const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
+
     PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
 
     for (size_t index = 0; index < NUM_RT; ++index) {
@@ -230,6 +231,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
         maxwell3d.regs.render_area.width,
         maxwell3d.regs.render_area.height,
     };
+
+    flags[Dirty::DepthBiasGlobal] = true;
 }
 
 template <class P>

+ 4 - 0
src/video_core/vulkan_common/vulkan_device.cpp

@@ -623,6 +623,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
         is_float16_supported = false;
     }
 
+    supports_d24_depth =
+        IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
+                          VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal);
+
     graphics_queue = logical.GetQueue(graphics_family);
     present_queue = logical.GetQueue(present_family);
 }

+ 5 - 0
src/video_core/vulkan_common/vulkan_device.h

@@ -332,6 +332,10 @@ public:
         return sets_per_pool;
     }
 
+    bool SupportsD24DepthBuffer() const {
+        return supports_d24_depth;
+    }
+
 private:
     /// Checks if the physical device is suitable.
     void CheckSuitability(bool requires_swapchain) const;
@@ -425,6 +429,7 @@ private:
     bool has_broken_cube_compatibility{};   ///< Has broken cube compatiblity bit
     bool has_renderdoc{};                   ///< Has RenderDoc attached
     bool has_nsight_graphics{};             ///< Has Nsight Graphics attached
+    bool supports_d24_depth{};              ///< Supports D24 depth buffers.
 
     // Telemetry parameters
     std::string vendor_name;                       ///< Device's driver name.