From 127ae6cf12bb4dfee37dc206a252ac5daaa260e6 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sun, 1 Sep 2024 20:32:20 +0200 Subject: [PATCH] vkd3d: Implement d3d12_command_list_OMSetDepthBounds(). Based on the design document, "The runtime will not clamp or validate the input, but implementations may clamp to the range [0,1] if necessary.", so we test for the EXT_depth_range_unrestricted extension, and only clamp if it's not available (thus, necessary to do so). NaNs are converted to zero as per "NaNs must be treated as 0, but the runtime will convert NaNs to 0 on behalf of the implementation.", and a default bounds are set to 0.0 and 1.0. --- include/private/vkd3d_common.h | 2 ++ libs/vkd3d/command.c | 30 +++++++++++++++++++++++++++-- libs/vkd3d/device.c | 1 + libs/vkd3d/state.c | 1 + libs/vkd3d/vkd3d_private.h | 3 ++- tests/hlsl/depth-bounds.shader_test | 8 ++++---- 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index d9321439..3560c691 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -62,6 +62,8 @@ #define VKD3D_STRINGIFY(x) #x #define VKD3D_EXPAND_AND_STRINGIFY(x) VKD3D_EXPAND(VKD3D_STRINGIFY(x)) +#define vkd3d_clamp(value, lower, upper) max(min(value, upper), lower) + #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 188162f9..eab0436b 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -19,6 +19,7 @@ */ #include "vkd3d_private.h" +#include static void d3d12_fence_incref(struct d3d12_fence *fence); static void d3d12_fence_decref(struct d3d12_fence *fence); @@ -2451,6 +2452,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL } list->is_recording = false; + list->has_depth_bounds = false; if (!list->is_valid) { @@ -2479,7 +2481,7 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, list->fb_layer_count = 0; list->xfb_enabled = false; - + list->has_depth_bounds = false; list->is_predicated = false; list->current_framebuffer = VK_NULL_HANDLE; @@ -3363,6 +3365,12 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list list->xfb_enabled = true; } + if (graphics->ds_desc.depthBoundsTestEnable && !list->has_depth_bounds) + { + list->has_depth_bounds = true; + VK_CALL(vkCmdSetDepthBounds(list->vk_command_buffer, 0.0f, 1.0f)); + } + return true; } @@ -5951,7 +5959,25 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList6 *iface, FLOAT min, FLOAT max) { - FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList6(iface); + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + + TRACE("iface %p, min %.8e, max %.8e.\n", iface, min, max); + + if (isnan(max)) + max = 0.0f; + if (isnan(min)) + min = 0.0f; + + if (!list->device->vk_info.EXT_depth_range_unrestricted && (min < 0.0f || min > 1.0f || max < 0.0f || max > 1.0f)) + { + WARN("VK_EXT_depth_range_unrestricted was not found, clamping depth bounds to 0.0 and 1.0.\n"); + max = vkd3d_clamp(max, 0.0f, 1.0f); + min = vkd3d_clamp(min, 0.0f, 1.0f); + } + + list->has_depth_bounds = true; + VK_CALL(vkCmdSetDepthBounds(list->vk_command_buffer, min, max)); } static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList6 *iface, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 01841c89..65339c7b 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -102,6 +102,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps), VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering), VK_DEBUG_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker), + VK_EXTENSION(EXT_DEPTH_RANGE_UNRESTRICTED, EXT_depth_range_unrestricted), VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable), VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing), VK_EXTENSION(EXT_FRAGMENT_SHADER_INTERLOCK, EXT_fragment_shader_interlock), diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index bc887fa2..ea7d8f04 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -3867,6 +3867,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_DEPTH_BOUNDS, }; static const VkPipelineDynamicStateCreateInfo dynamic_desc = { diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 3ba9a30a..65ace137 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -131,6 +131,7 @@ struct vkd3d_vulkan_info bool EXT_calibrated_timestamps; bool EXT_conditional_rendering; bool EXT_debug_marker; + bool EXT_depth_range_unrestricted; bool EXT_depth_clip_enable; bool EXT_descriptor_indexing; bool EXT_fragment_shader_interlock; @@ -1254,7 +1255,7 @@ struct d3d12_command_list VkFormat dsv_format; bool xfb_enabled; - + bool has_depth_bounds; bool is_predicated; VkFramebuffer current_framebuffer; diff --git a/tests/hlsl/depth-bounds.shader_test b/tests/hlsl/depth-bounds.shader_test index 7702403e..e808b117 100644 --- a/tests/hlsl/depth-bounds.shader_test +++ b/tests/hlsl/depth-bounds.shader_test @@ -37,8 +37,8 @@ depth greater equal clear rtv 0 0.0 0.0 0.0 0.0 clear dsv 0.0 todo(glsl) draw quad -todo(d3d12) probe (0, 0) rgba(0, 0, 0, 0) -todo probe uav 1 (0) r(0.0) +probe (0, 0) rgba(0, 0, 0, 0) +todo(sm<6) probe uav 1 (0) r(0.0) clear rtv 0 0.0 0.0 0.0 0.0 clear dsv 0.3 @@ -61,5 +61,5 @@ probe uav 1 (0) r(1.0) clear rtv 0 0.0 0.0 0.0 0.0 clear dsv 1.0 todo(glsl) draw quad -todo(d3d12) probe (0, 0) rgba(0, 0, 0, 0) -todo probe uav 1 (0) r(0.0) +probe (0, 0) rgba(0, 0, 0, 0) +todo(sm<6) probe uav 1 (0) r(0.0)