diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index ddee1b2d896..13435d962e3 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -256,6 +256,7 @@ get_device_extensions(const struct anv_physical_device *device, .EXT_conditional_rendering = device->info.verx10 >= 75, .EXT_conservative_rasterization = device->info.ver >= 9, .EXT_custom_border_color = device->info.ver >= 8, + .EXT_depth_clip_control = true, .EXT_depth_clip_enable = true, .EXT_descriptor_indexing = device->has_a64_buffer_access && device->has_bindless_images, @@ -1783,6 +1784,13 @@ void anv_GetPhysicalDeviceFeatures2( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT: { + VkPhysicalDeviceDepthClipControlFeaturesEXT *features = + (VkPhysicalDeviceDepthClipControlFeaturesEXT *)ext; + features->depthClipControl = true; + break; + } + default: anv_debug_ignored_stype(ext->sType); break; diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index a3f537e532a..58faf35c398 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -2142,6 +2142,13 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline, if (!raster_discard) { assert(pCreateInfo->pViewportState); + const VkPipelineViewportDepthClipControlCreateInfoEXT *ccontrol = + vk_find_struct_const(pCreateInfo->pViewportState, + PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT); + + if (ccontrol) + pipeline->negative_one_to_one = ccontrol->negativeOneToOne; + dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount; if (states & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) { typed_memcpy(dynamic->viewport.viewports, @@ -2571,7 +2578,8 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, const VkPipelineRasterizationDepthClipStateCreateInfoEXT *clip_info = vk_find_struct_const(pCreateInfo->pRasterizationState->pNext, PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); - pipeline->depth_clip_enable = clip_info ? clip_info->depthClipEnable : !pipeline->depth_clamp_enable; + pipeline->depth_clip_enable = clip_info ? clip_info->depthClipEnable : + !(pipeline->depth_clamp_enable || pipeline->negative_one_to_one); result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo); if (result != VK_SUCCESS) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index cc6ac89094a..672aab99ff1 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3528,6 +3528,7 @@ struct anv_graphics_pipeline { bool kill_pixel; bool depth_bounds_test_enable; bool force_fragment_thread_dispatch; + bool negative_one_to_one; /* When primitive replication is used, subpass->view_mask will describe what * views to replicate. diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 21eac79bf35..f05001a48c3 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3949,11 +3949,9 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) cmd_buffer_emit_streamout(cmd_buffer); } - if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) - gfx8_cmd_buffer_emit_viewport(cmd_buffer); - if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_VIEWPORT | ANV_CMD_DIRTY_PIPELINE)) { + gfx8_cmd_buffer_emit_viewport(cmd_buffer); gfx8_cmd_buffer_emit_depth_viewport(cmd_buffer, pipeline->depth_clamp_enable); } diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c index fa4444971b7..2c4d048f9e9 100644 --- a/src/intel/vulkan/gfx8_cmd_buffer.c +++ b/src/intel/vulkan/gfx8_cmd_buffer.c @@ -44,6 +44,11 @@ gfx8_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer) struct anv_state sf_clip_state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 64, 64); + bool negative_one_to_one = + cmd_buffer->state.gfx.pipeline->negative_one_to_one; + + float scale = negative_one_to_one ? 0.5f : 1.0f; + for (uint32_t i = 0; i < count; i++) { const VkViewport *vp = &viewports[i]; @@ -52,10 +57,11 @@ gfx8_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer) struct GENX(SF_CLIP_VIEWPORT) sfv = { .ViewportMatrixElementm00 = vp->width / 2, .ViewportMatrixElementm11 = vp->height / 2, - .ViewportMatrixElementm22 = vp->maxDepth - vp->minDepth, + .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) * scale, .ViewportMatrixElementm30 = vp->x + vp->width / 2, .ViewportMatrixElementm31 = vp->y + vp->height / 2, - .ViewportMatrixElementm32 = vp->minDepth, + .ViewportMatrixElementm32 = negative_one_to_one ? + (vp->minDepth + vp->maxDepth) * scale : vp->minDepth, .XMinClipGuardband = -1.0f, .XMaxClipGuardband = 1.0f, .YMinClipGuardband = -1.0f,