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 <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:04:29 +02:00 committed by Marge Bot
parent 81fb1cfdad
commit 741b5ded49
3 changed files with 38 additions and 13 deletions

View File

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

View File

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

View File

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