diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 037bdcd5bd2..30df302a85d 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -4462,7 +4462,12 @@ dzn_CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasClamp, float depthBiasSlopeFactor) { - dzn_stub(); + VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); + + cmdbuf->state.pipeline_variant.depth_bias.constant_factor = depthBiasConstantFactor; + cmdbuf->state.pipeline_variant.depth_bias.clamp = depthBiasClamp; + cmdbuf->state.pipeline_variant.depth_bias.slope_factor = depthBiasSlopeFactor; + cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_GRAPHICS].dirty |= DZN_CMD_BINDPOINT_DIRTY_PIPELINE; } VKAPI_ATTR void VKAPI_CALL @@ -4482,10 +4487,15 @@ dzn_CmdSetDepthBounds(VkCommandBuffer commandBuffer, float maxDepthBounds) { VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); + struct dzn_device *device = container_of(cmdbuf->vk.base.device, struct dzn_device, vk); + struct dzn_physical_device *pdev = + container_of(device->vk.physical, struct dzn_physical_device, vk); - cmdbuf->state.zsa.depth_bounds.min = minDepthBounds; - cmdbuf->state.zsa.depth_bounds.max = maxDepthBounds; - cmdbuf->state.dirty |= DZN_CMD_DIRTY_DEPTH_BOUNDS; + if (pdev->options2.DepthBoundsTestSupported) { + cmdbuf->state.zsa.depth_bounds.min = minDepthBounds; + cmdbuf->state.zsa.depth_bounds.max = maxDepthBounds; + cmdbuf->state.dirty |= DZN_CMD_DIRTY_DEPTH_BOUNDS; + } } VKAPI_ATTR void VKAPI_CALL @@ -4495,13 +4505,18 @@ dzn_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, { VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); - if (faceMask & VK_STENCIL_FACE_FRONT_BIT) + if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { cmdbuf->state.zsa.stencil_test.front.compare_mask = compareMask; + cmdbuf->state.pipeline_variant.stencil_test.front.compare_mask = compareMask; + } - if (faceMask & VK_STENCIL_FACE_BACK_BIT) + if (faceMask & VK_STENCIL_FACE_BACK_BIT) { cmdbuf->state.zsa.stencil_test.back.compare_mask = compareMask; + cmdbuf->state.pipeline_variant.stencil_test.back.compare_mask = compareMask; + } cmdbuf->state.dirty |= DZN_CMD_DIRTY_STENCIL_COMPARE_MASK; + cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_GRAPHICS].dirty |= DZN_CMD_BINDPOINT_DIRTY_PIPELINE; } VKAPI_ATTR void VKAPI_CALL @@ -4511,13 +4526,18 @@ dzn_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, { VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); - if (faceMask & VK_STENCIL_FACE_FRONT_BIT) + if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { cmdbuf->state.zsa.stencil_test.front.write_mask = writeMask; + cmdbuf->state.pipeline_variant.stencil_test.front.write_mask = writeMask; + } - if (faceMask & VK_STENCIL_FACE_BACK_BIT) + if (faceMask & VK_STENCIL_FACE_BACK_BIT) { cmdbuf->state.zsa.stencil_test.back.write_mask = writeMask; + cmdbuf->state.pipeline_variant.stencil_test.back.write_mask = writeMask; + } cmdbuf->state.dirty |= DZN_CMD_DIRTY_STENCIL_WRITE_MASK; + cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_GRAPHICS].dirty |= DZN_CMD_BINDPOINT_DIRTY_PIPELINE; } VKAPI_ATTR void VKAPI_CALL diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index bc5715c4ceb..d9206ed3835 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -1069,7 +1069,7 @@ dzn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, .multiDrawIndirect = true, .drawIndirectFirstInstance = true, .depthClamp = false, - .depthBiasClamp = false, + .depthBiasClamp = true, .fillModeNonSolid = false, .depthBounds = dzn_physical_device_supports_depth_bounds(pdev), .wideLines = false, diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index b5869c34ffc..7618b380765 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -661,6 +661,8 @@ dzn_graphics_pipeline_translate_rast(struct dzn_graphics_pipeline *pipeline, } d3d12_gfx_pipeline_state_stream_new_desc(out, RASTERIZER, D3D12_RASTERIZER_DESC, desc); + pipeline->templates.desc_offsets.rast = + (uintptr_t)desc - (uintptr_t)out->pPipelineStateSubobjectStream; desc->DepthClipEnable = !in_rast->depthClampEnable; desc->FillMode = translate_polygon_mode(in_rast->polygonMode); desc->CullMode = translate_cull_mode(in_rast->cullMode); @@ -841,13 +843,18 @@ dzn_graphics_pipeline_translate_zsa(struct dzn_graphics_pipeline *pipeline, return; d3d12_gfx_pipeline_state_stream_new_desc(out, DEPTH_STENCIL1, D3D12_DEPTH_STENCIL_DESC1, desc); + pipeline->templates.desc_offsets.ds = + (uintptr_t)desc - (uintptr_t)out->pPipelineStateSubobjectStream; - desc->DepthEnable = in_zsa->depthTestEnable; + desc->DepthEnable = + in_zsa->depthTestEnable || in_zsa->depthBoundsTestEnable; desc->DepthWriteMask = in_zsa->depthWriteEnable ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; desc->DepthFunc = - dzn_translate_compare_op(in_zsa->depthCompareOp); + in_zsa->depthTestEnable ? + dzn_translate_compare_op(in_zsa->depthCompareOp) : + D3D12_COMPARISON_FUNC_ALWAYS; pipeline->zsa.depth_bounds.enable = in_zsa->depthBoundsTestEnable; pipeline->zsa.depth_bounds.min = in_zsa->minDepthBounds; pipeline->zsa.depth_bounds.max = in_zsa->maxDepthBounds; @@ -1155,6 +1162,12 @@ dzn_graphics_pipeline_create(struct dzn_device *device, case VK_DYNAMIC_STATE_DEPTH_BOUNDS: pipeline->zsa.depth_bounds.dynamic = true; break; + case VK_DYNAMIC_STATE_DEPTH_BIAS: + pipeline->zsa.dynamic_depth_bias = true; + ret = dzn_graphics_pipeline_prepare_for_variants(device, pipeline); + if (ret) + goto out; + break; default: unreachable("Unsupported dynamic state"); } } @@ -1266,6 +1279,25 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, if (dzn_graphics_pipeline_get_desc_template(pipeline, ib_strip_cut)) masked_key.ib_strip_cut = key->ib_strip_cut; + if (dzn_graphics_pipeline_get_desc_template(pipeline, rast) && + pipeline->zsa.dynamic_depth_bias) + masked_key.depth_bias = key->depth_bias; + + const D3D12_DEPTH_STENCIL_DESC1 *ds_templ = + dzn_graphics_pipeline_get_desc_template(pipeline, ds); + if (ds_templ && ds_templ->StencilEnable) { + if (ds_templ->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds_templ->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS) + masked_key.stencil_test.front.compare_mask = key->stencil_test.front.compare_mask; + if (ds_templ->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds_templ->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS) + masked_key.stencil_test.back.compare_mask = key->stencil_test.back.compare_mask; + if (pipeline->zsa.stencil_test.dynamic_write_mask) { + masked_key.stencil_test.front.write_mask = key->stencil_test.front.write_mask; + masked_key.stencil_test.back.write_mask = key->stencil_test.back.write_mask; + } + } + struct dzn_device *device = container_of(pipeline->base.base.device, struct dzn_device, vk); struct hash_entry *he = @@ -1290,6 +1322,45 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, if (ib_strip_cut) *ib_strip_cut = masked_key.ib_strip_cut; + D3D12_RASTERIZER_DESC *rast = + dzn_graphics_pipeline_get_desc(pipeline, stream_buf, rast); + if (rast && pipeline->zsa.dynamic_depth_bias) { + rast->DepthBias = masked_key.depth_bias.constant_factor; + rast->DepthBiasClamp = masked_key.depth_bias.clamp; + rast->SlopeScaledDepthBias = masked_key.depth_bias.slope_factor; + } + + D3D12_DEPTH_STENCIL_DESC1 *ds = + dzn_graphics_pipeline_get_desc(pipeline, stream_buf, ds); + if (ds && ds->StencilEnable) { + if (pipeline->zsa.stencil_test.dynamic_compare_mask) { + if (ds->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS) { + ds->StencilReadMask = masked_key.stencil_test.front.compare_mask; + } + + if (ds->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS) { + ds->StencilReadMask = masked_key.stencil_test.back.compare_mask; + } + + if (ds->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds->FrontFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS && + ds->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_NEVER && + ds->BackFace.StencilFunc != D3D12_COMPARISON_FUNC_ALWAYS) + assert(masked_key.stencil_test.front.compare_mask == masked_key.stencil_test.back.compare_mask); + } + + if (pipeline->zsa.stencil_test.dynamic_write_mask) { + assert(!masked_key.stencil_test.front.write_mask || + !masked_key.stencil_test.back.write_mask || + masked_key.stencil_test.front.write_mask == masked_key.stencil_test.back.write_mask); + ds->StencilWriteMask = + masked_key.stencil_test.front.write_mask | + masked_key.stencil_test.back.write_mask; + } + } + HRESULT hres = ID3D12Device2_CreatePipelineState(device->dev, &stream_desc, &IID_ID3D12PipelineState, &variant->state); diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 1093048028e..f2cc40d5b2e 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -458,6 +458,16 @@ struct dzn_rendering_attachment { struct dzn_graphics_pipeline_variant_key { D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ib_strip_cut; + struct { + int constant_factor; + float slope_factor; + float clamp; + } depth_bias; + struct { + struct { + uint32_t ref, compare_mask, write_mask; + } front, back; + } stencil_test; }; struct dzn_graphics_pipeline_variant { @@ -791,6 +801,7 @@ struct dzn_graphics_pipeline { bool dynamic; float min, max; } depth_bounds; + bool dynamic_depth_bias; } zsa; struct { @@ -803,6 +814,8 @@ struct dzn_graphics_pipeline { D3D12_PIPELINE_STATE_STREAM_DESC stream_desc; struct { uint32_t ib_strip_cut; + uint32_t rast; + uint32_t ds; } desc_offsets; D3D12_INPUT_ELEMENT_DESC inputs[D3D12_VS_INPUT_REGISTER_COUNT]; struct {