From 741b5ded49d2f002995b92371a7e95fd7db42599 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 10 Jun 2022 15:04:29 +0200 Subject: [PATCH] dzn: Fix primitiveRestart support We can't hardcode the strip cut value to 0xffffffff, otherwise we break support for 16-bit index buffers. Let's use the pipeline variant infrastructure to deal with that case. Reviewed-by: Jesse Natalie Part-of: --- src/microsoft/vulkan/dzn_cmd_buffer.c | 14 +++++++++--- src/microsoft/vulkan/dzn_pipeline.c | 33 ++++++++++++++++++++------- src/microsoft/vulkan/dzn_private.h | 4 ++-- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 3d3d081e1a2..de84cc53960 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -2538,6 +2538,9 @@ dzn_cmd_buffer_triangle_fan_rewrite_index(struct dzn_cmd_buffer *cmdbuf, static void dzn_cmd_buffer_prepare_draw(struct dzn_cmd_buffer *cmdbuf, bool indexed) { + if (indexed) + dzn_cmd_buffer_update_ibview(cmdbuf); + dzn_cmd_buffer_update_pipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS); dzn_cmd_buffer_update_heaps(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS); dzn_cmd_buffer_update_sysvals(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS); @@ -2549,9 +2552,6 @@ dzn_cmd_buffer_prepare_draw(struct dzn_cmd_buffer *cmdbuf, bool indexed) dzn_cmd_buffer_update_blend_constants(cmdbuf); dzn_cmd_buffer_update_depth_bounds(cmdbuf); - if (indexed) - dzn_cmd_buffer_update_ibview(cmdbuf); - /* Reset the dirty states */ cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_GRAPHICS].dirty = 0; cmdbuf->state.dirty = 0; @@ -3963,14 +3963,22 @@ dzn_CmdBindIndexBuffer(VkCommandBuffer commandBuffer, switch (indexType) { case VK_INDEX_TYPE_UINT16: cmdbuf->state.ib.view.Format = DXGI_FORMAT_R16_UINT; + cmdbuf->state.pipeline_variant.ib_strip_cut = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF; break; case VK_INDEX_TYPE_UINT32: cmdbuf->state.ib.view.Format = DXGI_FORMAT_R32_UINT; + cmdbuf->state.pipeline_variant.ib_strip_cut = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; break; default: unreachable("Invalid index type"); } cmdbuf->state.dirty |= DZN_CMD_DIRTY_IB; + + const struct dzn_graphics_pipeline *pipeline = + (const struct dzn_graphics_pipeline *)cmdbuf->state.pipeline; + + if (pipeline && dzn_graphics_pipeline_get_desc_template(pipeline, ib_strip_cut)) + 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_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index 11e5b3766ab..b5869c34ffc 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -576,8 +576,9 @@ to_prim_topology(VkPrimitiveTopology in, unsigned patch_control_points) } } -static void -dzn_graphics_pipeline_translate_ia(struct dzn_graphics_pipeline *pipeline, +static VkResult +dzn_graphics_pipeline_translate_ia(struct dzn_device *device, + struct dzn_graphics_pipeline *pipeline, D3D12_PIPELINE_STATE_STREAM_DESC *out, const VkGraphicsPipelineCreateInfo *in) { @@ -593,6 +594,7 @@ dzn_graphics_pipeline_translate_ia(struct dzn_graphics_pipeline *pipeline, } const VkPipelineTessellationStateCreateInfo *in_tes = has_tes ? in->pTessellationState : NULL; + VkResult ret = VK_SUCCESS; d3d12_gfx_pipeline_state_stream_new_desc(out, PRIMITIVE_TOPOLOGY, D3D12_PRIMITIVE_TOPOLOGY_TYPE, prim_top_type); *prim_top_type = to_prim_topology_type(in_ia->topology); @@ -600,12 +602,15 @@ dzn_graphics_pipeline_translate_ia(struct dzn_graphics_pipeline *pipeline, pipeline->ia.topology = to_prim_topology(in_ia->topology, in_tes ? in_tes->patchControlPoints : 0); - /* FIXME: does that work for u16 index buffers? */ - d3d12_gfx_pipeline_state_stream_new_desc(out, IB_STRIP_CUT_VALUE, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, ib_strip_cut); - if (in_ia->primitiveRestartEnable) - *ib_strip_cut = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; - else + if (in_ia->primitiveRestartEnable) { + d3d12_gfx_pipeline_state_stream_new_desc(out, IB_STRIP_CUT_VALUE, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, ib_strip_cut); + pipeline->templates.desc_offsets.ib_strip_cut = + (uintptr_t)ib_strip_cut - (uintptr_t)out->pPipelineStateSubobjectStream; *ib_strip_cut = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + ret = dzn_graphics_pipeline_prepare_for_variants(device, pipeline); + } + + return ret; } static D3D12_FILL_MODE @@ -1155,7 +1160,10 @@ dzn_graphics_pipeline_create(struct dzn_device *device, } } - dzn_graphics_pipeline_translate_ia(pipeline, stream_desc, pCreateInfo); + ret = dzn_graphics_pipeline_translate_ia(device, pipeline, stream_desc, pCreateInfo); + if (ret) + goto out; + dzn_graphics_pipeline_translate_rast(pipeline, stream_desc, pCreateInfo); dzn_graphics_pipeline_translate_ms(pipeline, stream_desc, pCreateInfo); dzn_graphics_pipeline_translate_zsa(pipeline, stream_desc, pCreateInfo); @@ -1254,6 +1262,10 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, return pipeline->base.state; struct dzn_graphics_pipeline_variant_key masked_key = { 0 }; + + if (dzn_graphics_pipeline_get_desc_template(pipeline, ib_strip_cut)) + masked_key.ib_strip_cut = key->ib_strip_cut; + struct dzn_device *device = container_of(pipeline->base.base.device, struct dzn_device, vk); struct hash_entry *he = @@ -1273,6 +1285,11 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline, memcpy(stream_buf, pipeline->templates.stream_buf, stream_desc.SizeInBytes); + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE *ib_strip_cut = + dzn_graphics_pipeline_get_desc(pipeline, stream_buf, ib_strip_cut); + if (ib_strip_cut) + *ib_strip_cut = masked_key.ib_strip_cut; + 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 461f8922e2c..4a91484169d 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -448,7 +448,7 @@ struct dzn_rendering_attachment { }; struct dzn_graphics_pipeline_variant_key { - uint32_t dummy; + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ib_strip_cut; }; struct dzn_graphics_pipeline_variant { @@ -793,7 +793,7 @@ struct dzn_graphics_pipeline { uintptr_t stream_buf[MAX_GFX_PIPELINE_STATE_STREAM_SIZE / sizeof(uintptr_t)]; D3D12_PIPELINE_STATE_STREAM_DESC stream_desc; struct { - uint32_t dummy; + uint32_t ib_strip_cut; } desc_offsets; D3D12_INPUT_ELEMENT_DESC inputs[D3D12_VS_INPUT_REGISTER_COUNT]; struct {