mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-22 15:48:56 +00:00
[TEST] depth clip enable implementation
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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); });
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user