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)