Browse Source

[TEST] depth clip enable implementation

temporary-branch
CamilleLaVey 5 days ago
parent
commit
1f41d809b0
  1. 71
      src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
  2. 5
      src/video_core/renderer_vulkan/fixed_pipeline_state.h
  3. 10
      src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
  4. 5
      src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
  5. 29
      src/video_core/renderer_vulkan/vk_rasterizer.cpp
  6. 4
      src/video_core/vulkan_common/vulkan_device.cpp
  7. 6
      src/video_core/vulkan_common/vulkan_device.h

71
src/video_core/renderer_vulkan/fixed_pipeline_state.cpp

@ -11,7 +11,6 @@
#include <ranges>
#include "common/cityhash.h"
#include "common/common_types.h"
#include "common/logging.h"
#include "common/settings.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
@ -89,27 +88,6 @@ bool ComputeAttachment0DualSourceBlend(const Maxwell& regs) {
: uses_dual_source(regs.blend);
}
const char* GeometryClipName(Maxwell::ViewportClipControl::GeometryClip clip) {
switch (clip) {
case Maxwell::ViewportClipControl::GeometryClip::WZero:
return "WZero";
case Maxwell::ViewportClipControl::GeometryClip::Passthrough:
return "Passthrough";
case Maxwell::ViewportClipControl::GeometryClip::FrustumXY:
return "FrustumXY";
case Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ:
return "FrustumXYZ";
case Maxwell::ViewportClipControl::GeometryClip::WZeroNoZCull:
return "WZeroNoZCull";
case Maxwell::ViewportClipControl::GeometryClip::FrustumZ:
return "FrustumZ";
case Maxwell::ViewportClipControl::GeometryClip::WZeroTriFillOrClip:
return "WZeroTriFillOrClip";
default:
return "Unknown";
}
}
void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
[](const auto& layout) {
@ -127,29 +105,6 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
const Maxwell& regs = maxwell3d.regs;
const auto topology_ = maxwell3d.draw_manager.draw_state.topology;
{
const auto& clip = regs.viewport_clip_control;
const u32 clip_key = (static_cast<u32>(clip.geometry_clip.Value()) << 8) |
(static_cast<u32>(clip.geometry_guardband_z.Value()) << 6) |
(static_cast<u32>(clip.geometry_guardband.Value()) << 5) |
(clip.pixel_max_z.Value() << 2) | (clip.pixel_min_z.Value() << 1) |
clip.depth_0_to_1.Value();
static u32 last_clip_key = ~0U;
if (clip_key != last_clip_key) {
last_clip_key = clip_key;
LOG_WARNING(Render_Vulkan,
"Viewport clip control: geometry_clip={} guardband_z={} guardband={} "
"depth_0_to_1={} pixel_min_z={} pixel_max_z={} depth_mode={}",
GeometryClipName(clip.geometry_clip.Value()),
static_cast<u32>(clip.geometry_guardband_z.Value()),
static_cast<u32>(clip.geometry_guardband.Value()),
clip.depth_0_to_1.Value(), clip.pixel_min_z.Value(),
clip.pixel_max_z.Value(),
regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? "MinusOneToOne"
: "ZeroToOne");
}
}
driver_id = features.driver_id;
driver_version = features.driver_version;
@ -405,18 +360,32 @@ void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs,
depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
}
bool IsDepthClipEnabled(const Maxwell& regs) {
const auto clip = regs.viewport_clip_control.geometry_clip.Value();
return clip == Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
clip == Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
clip == Maxwell::ViewportClipControl::GeometryClip::FrustumZ;
}
bool IsDepthClampEnabled(const Maxwell& regs, bool has_depth_clip_enable) {
if (!has_depth_clip_enable) {
return !IsDepthClipEnabled(regs);
}
return regs.viewport_clip_control.pixel_min_z.Value() != 0 ||
regs.viewport_clip_control.pixel_max_z.Value() != 0;
}
void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs,
const DynamicFeatures& features) {
if (!features.has_dynamic_state3_logic_op_enable) {
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
}
if (features.has_depth_clip_enable) {
depth_clip_disabled.Assign(IsDepthClipEnabled(regs) ? 0 : 1);
}
if (!features.has_dynamic_state3_depth_clamp_enable) {
depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
depth_clamp_disabled.Assign(
IsDepthClampEnabled(regs, features.has_depth_clip_enable) ? 0 : 1);
}
if (!features.has_dynamic_state3_line_stipple_enable) {
line_stipple_enable.Assign(regs.line_stipple_enable);

5
src/video_core/renderer_vulkan/fixed_pipeline_state.h

@ -30,6 +30,7 @@ struct DynamicFeatures {
bool has_extended_dynamic_state_3_blend;
bool has_extended_dynamic_state_3_enables;
bool has_dynamic_state3_depth_clamp_enable;
bool has_depth_clip_enable;
bool has_dynamic_state3_logic_op_enable;
bool has_dynamic_state3_line_stipple_enable;
bool has_dynamic_vertex_input;
@ -165,6 +166,7 @@ struct FixedPipelineState {
BitField<10, 1, u32> logic_op_enable;
BitField<11, 1, u32> depth_clamp_disabled;
BitField<12, 1, u32> line_stipple_enable;
BitField<13, 1, u32> depth_clip_disabled;
};
union {
u32 raw2;
@ -298,6 +300,9 @@ static_assert(std::has_unique_object_representations_v<FixedPipelineState>);
static_assert(std::is_trivially_copyable_v<FixedPipelineState>);
static_assert(std::is_trivially_constructible_v<FixedPipelineState>);
bool IsDepthClipEnabled(const Maxwell& regs);
bool IsDepthClampEnabled(const Maxwell& regs, bool has_depth_clip_enable);
} // namespace Vulkan
namespace std {

10
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@ -808,6 +808,16 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
if (device.IsExtProvokingVertexSupported()) {
provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex);
}
VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip_state{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = 0,
.depthClipEnable = static_cast<VkBool32>(dynamic.depth_clip_disabled == 0 ? VK_TRUE
: VK_FALSE),
};
if (device.IsExtDepthClipEnableSupported()) {
depth_clip_state.pNext = std::exchange(rasterization_ci.pNext, &depth_clip_state);
}
const bool supports_alpha_output = fragment_has_color0_output;
const bool alpha_to_one_supported = device.SupportsAlphaToOne();

5
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@ -515,6 +515,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
dynamic_features.has_dynamic_state3_depth_clamp_enable =
dynamic_features.has_extended_dynamic_state_3_enables &&
device.SupportsDynamicState3DepthClampEnable();
dynamic_features.has_depth_clip_enable =
device.IsExtDepthClipEnableSupported();
dynamic_features.has_dynamic_state3_logic_op_enable =
dynamic_features.has_extended_dynamic_state_3_enables &&
device.SupportsDynamicState3LogicOpEnable();
@ -527,7 +529,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.IsExtVertexInputDynamicStateSupported() &&
Settings::values.vertex_input_dynamic_state.GetValue();
dynamic_features.has_provoking_vertex = device.IsExtProvokingVertexSupported();
dynamic_features.has_provoking_vertex =
device.IsExtProvokingVertexSupported();
dynamic_features.has_provoking_vertex_first_mode =
device.SupportsProvokingVertexFirstMode();
dynamic_features.has_provoking_vertex_last_mode =

29
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@ -103,26 +103,8 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
.maxDepth = src.translate_z + src.scale_z,
};
if (!device.IsExtDepthRangeUnrestrictedSupported()) {
const float requested_min = viewport.minDepth;
const float requested_max = viewport.maxDepth;
viewport.minDepth = std::clamp(requested_min, 0.0f, 1.0f);
viewport.maxDepth = std::clamp(requested_max, 0.0f, 1.0f);
if (viewport.minDepth != requested_min || viewport.maxDepth != requested_max) {
static float last_min = std::numeric_limits<float>::quiet_NaN();
static float last_max = std::numeric_limits<float>::quiet_NaN();
if (requested_min != last_min || requested_max != last_max) {
last_min = requested_min;
last_max = requested_max;
LOG_WARNING(Render_Vulkan,
"Viewport {} depth range squashed: requested [{}, {}] applied [{}, {}] "
"translate_z={} scale_z={} depth_mode={} clamp_zero_one={}",
index, requested_min, requested_max, viewport.minDepth,
viewport.maxDepth, src.translate_z, src.scale_z,
regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? "MinusOneToOne"
: "ZeroToOne",
device.IsExtDepthClampZeroOneSupported());
}
}
viewport.minDepth = std::clamp(viewport.minDepth, 0.0f, 1.0f);
viewport.maxDepth = std::clamp(viewport.maxDepth, 0.0f, 1.0f);
}
return viewport;
}
@ -1684,12 +1666,7 @@ void RasterizerVulkan::UpdateDepthClampEnable(Tegra::Engines::Maxwell3D::Regs& r
if (!device.SupportsDynamicState3DepthClampEnable()) {
return;
}
bool is_enabled = !(regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
const bool is_enabled = IsDepthClampEnabled(regs, device.IsExtDepthClipEnableSupported());
scheduler.Record(
[is_enabled](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthClampEnableEXT(is_enabled); });
}

4
src/video_core/vulkan_common/vulkan_device.cpp

@ -1241,6 +1241,10 @@ void Device::RemoveUnsuitableExtensions() {
extensions.depth_clip_control = features.depth_clip_control.depthClipControl;
RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control,
VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
// VK_EXT_depth_clip_enable
extensions.depth_clip_enable = features.depth_clip_enable.depthClipEnable;
RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_enable, features.depth_clip_enable,
VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
// VK_EXT_extended_dynamic_state
extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState;

6
src/video_core/vulkan_common/vulkan_device.h

@ -57,6 +57,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE(EXT, DepthBiasControl, DEPTH_BIAS_CONTROL, depth_bias_control) \
FEATURE(EXT, DepthClampZeroOne, DEPTH_CLAMP_ZERO_ONE, depth_clamp_zero_one) \
FEATURE(EXT, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \
FEATURE(EXT, DepthClipEnable, DEPTH_CLIP_ENABLE, depth_clip_enable) \
FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \
FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \
FEATURE(EXT, ExtendedDynamicState3, EXTENDED_DYNAMIC_STATE_3, extended_dynamic_state3) \
@ -618,6 +619,11 @@ FN_MAX_LIMIT_LIST
return extensions.depth_clamp_zero_one;
}
/// Returns true if the device supports VK_EXT_depth_clip_enable.
bool IsExtDepthClipEnableSupported() const {
return extensions.depth_clip_enable;
}
/// Returns true if the device supports VK_EXT_depth_bias_control.
bool IsExtDepthBiasControlSupported() const {
return extensions.depth_bias_control;

Loading…
Cancel
Save