dzn: Support dynamic depth testing parameters properly

Now that we have support for pipeline variants, we can take the dynamic
depth testing parameters into account and create a new pipeline state
using those dynamic parameters.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16971>
This commit is contained in:
Boris Brezillon 2022-06-10 15:57:56 +02:00 committed by Marge Bot
parent 91f3c7a9fb
commit 7d9afb93cc
4 changed files with 115 additions and 11 deletions

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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 {