summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan/vk_rasterizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan/vk_rasterizer.cpp')
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp94
1 files changed, 84 insertions, 10 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index cd0b255a0..3791f7287 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -369,6 +369,9 @@ void RasterizerVulkan::Clear(u32 layer_count) {
return;
}
+ // Only log the clear depth value - there's no depth or stencil members in ClearSurface
+ LOG_INFO(Render_Vulkan, "Clear depth value: {}", regs.clear_depth);
+
std::scoped_lock lock{texture_cache.mutex};
texture_cache.UpdateRenderTargets(true);
const Framebuffer* const framebuffer = texture_cache.GetFramebuffer();
@@ -974,7 +977,8 @@ void RasterizerVulkan::UpdateDynamicStates() {
bool hasFloat = std::any_of(
regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(),
[](const auto& attrib) {
- return attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::Float;
+ return attrib.type ==
+ Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::Float;
});
// For AMD drivers, disable logic_op if a float attribute is present.
@@ -1286,8 +1290,33 @@ void RasterizerVulkan::UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& r
if (!state_tracker.TouchDepthWriteEnable()) {
return;
}
- scheduler.Record([enable = regs.depth_write_enabled](vk::CommandBuffer cmdbuf) {
- cmdbuf.SetDepthWriteEnableEXT(enable);
+
+ // Check if we're likely in a reversed depth scenario (clear depth near 0)
+ const bool likely_reversed_depth = (regs.clear_depth < 0.5f);
+
+ // Get the original depth write enable state
+ bool depth_write_enable = regs.depth_write_enabled != 0;
+ bool modified = false;
+
+ // Only force enable depth writes when:
+ // 1. We're using reversed depth (clear_depth < 0.5)
+ // 2. Depth testing is enabled
+ // 3. Original depth writes are disabled
+ // This selectively fixes the issue without affecting other games
+ if (likely_reversed_depth && regs.depth_test_enable && !depth_write_enable) {
+ depth_write_enable = true;
+ modified = true;
+ LOG_INFO(Render_Vulkan, "Reversed depth buffer with disabled depth writes detected, "
+ "enabling depth writes for improved visibility");
+ }
+
+ // Log when depth write is being modified
+ LOG_INFO(Render_Vulkan, "Depth write set to: {} ({}){}",
+ depth_write_enable ? "enabled" : "disabled", regs.depth_write_enabled ? "1" : "0",
+ modified ? " -> modified" : "");
+
+ scheduler.Record([depth_write_enable](vk::CommandBuffer cmdbuf) {
+ cmdbuf.SetDepthWriteEnableEXT(depth_write_enable);
});
}
@@ -1371,7 +1400,27 @@ void RasterizerVulkan::UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& reg
if (!state_tracker.TouchDepthCompareOp()) {
return;
}
- scheduler.Record([func = regs.depth_test_func](vk::CommandBuffer cmdbuf) {
+
+ // Get the original depth comparison function requested by the game
+ auto original_func = regs.depth_test_func;
+ auto func_to_use = original_func;
+
+ // Check for clear depth - we'll use this to determine how to handle depth
+ const bool likely_reversed_depth = (regs.clear_depth < 0.5f);
+
+ // For reversed depth (clear_depth near 0), ALWAYS use GREATER_OR_EQUAL
+ // For normal depth (clear_depth near 1), ALWAYS use LESS_OR_EQUAL
+ if (likely_reversed_depth) {
+ func_to_use =
+ Maxwell::ComparisonOp::GreaterEqual_GL; // Maxwell::ComparisonOp::GreaterEqual_GL;
+ LOG_INFO(Render_Vulkan,
+ "Reversed depth buffer detected, using GREATER_OR_EQUAL for improved visibility");
+ } else {
+ func_to_use = regs.depth_test_func;
+ }
+
+ // Use the modified depth comparison function
+ scheduler.Record([func = func_to_use](vk::CommandBuffer cmdbuf) {
cmdbuf.SetDepthCompareOpEXT(MaxwellToVK::ComparisonOp(func));
});
}
@@ -1476,13 +1525,38 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) {
std::array<VkColorBlendEquationEXT, Maxwell::NumRenderTargets> setup_blends{};
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
const auto blend_setup = [&]<typename T>(const T& guest_blend) {
+ // Check if we're likely in a reversed depth scenario (clear depth near 0),
+ // which would indicate we're in Civilization 7 where models have transparency
+ // issues
+ const bool likely_reversed_depth = (regs.clear_depth < 0.5f);
+
auto& host_blend = setup_blends[index];
- host_blend.srcColorBlendFactor = MaxwellToVK::BlendFactor(guest_blend.color_source);
- host_blend.dstColorBlendFactor = MaxwellToVK::BlendFactor(guest_blend.color_dest);
- host_blend.colorBlendOp = MaxwellToVK::BlendEquation(guest_blend.color_op);
- host_blend.srcAlphaBlendFactor = MaxwellToVK::BlendFactor(guest_blend.alpha_source);
- host_blend.dstAlphaBlendFactor = MaxwellToVK::BlendFactor(guest_blend.alpha_dest);
- host_blend.alphaBlendOp = MaxwellToVK::BlendEquation(guest_blend.alpha_op);
+
+ if (likely_reversed_depth) {
+ // For reversed depth scenarios (likely Civilization 7), force ONE/ZERO blend
+ // factors to ensure models render as fully opaque
+ host_blend.srcColorBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.color_source);
+ host_blend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ host_blend.colorBlendOp = MaxwellToVK::BlendEquation(guest_blend.color_op);
+ host_blend.srcAlphaBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.alpha_source);
+ host_blend.dstAlphaBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.alpha_dest);
+ host_blend.alphaBlendOp = MaxwellToVK::BlendEquation(guest_blend.alpha_op);
+ } else {
+ // For normal depth scenarios, use the game's requested blend factors
+ host_blend.srcColorBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.color_source);
+ host_blend.dstColorBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.color_dest);
+ host_blend.colorBlendOp = MaxwellToVK::BlendEquation(guest_blend.color_op);
+ host_blend.srcAlphaBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.alpha_source);
+ host_blend.dstAlphaBlendFactor =
+ MaxwellToVK::BlendFactor(guest_blend.alpha_dest);
+ host_blend.alphaBlendOp = MaxwellToVK::BlendEquation(guest_blend.alpha_op);
+ }
};
if (!regs.blend_per_target_enabled) {
blend_setup(regs.blend);