vkd3d: Reject descriptor tables containing register collisions.

Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Conor McCarthy 2021-10-06 18:43:29 +02:00 committed by Alexandre Julliard
parent c5fdd2f404
commit d3090699c5
2 changed files with 38 additions and 3 deletions

View File

@ -662,6 +662,39 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r
return S_OK; return S_OK;
} }
static int compare_register_range(const void *a, const void *b)
{
const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b;
int ret;
if ((ret = range_a->type - range_b->type))
return ret;
if ((ret = range_a->register_space - range_b->register_space))
return ret;
return range_a->base_register_idx - range_b->base_register_idx;
}
static HRESULT validate_descriptor_register_ranges(const struct d3d12_root_descriptor_table_range *ranges,
unsigned int count)
{
const struct d3d12_root_descriptor_table_range *range, *prev;
unsigned int i;
for (i = 1; i < count; ++i)
{
range = &ranges[i];
prev = &ranges[i - 1];
if (range->type == prev->type && range->register_space == prev->register_space
&& range->base_register_idx - prev->base_register_idx < prev->descriptor_count)
return E_INVALIDARG;
}
return S_OK;
}
static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature, static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature,
const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context)
{ {
@ -715,6 +748,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
offset += range->NumDescriptors; offset += range->NumDescriptors;
} }
qsort(table->ranges, range_count, sizeof(*table->ranges), compare_register_range);
if (FAILED(hr = validate_descriptor_register_ranges(table->ranges, range_count)))
return hr;
for (j = 0; j < range_count; ++j) for (j = 0; j < range_count; ++j)
{ {
struct d3d12_root_descriptor_table_range *range; struct d3d12_root_descriptor_table_range *range;

View File

@ -2674,9 +2674,7 @@ static void test_create_root_signature(void)
descriptor_ranges[1].BaseShaderRegister = 7; descriptor_ranges[1].BaseShaderRegister = 7;
descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 8; descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 8;
hr = create_root_signature(device, &root_signature_desc, &root_signature); hr = create_root_signature(device, &root_signature_desc, &root_signature);
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr))
ID3D12RootSignature_Release(root_signature);
/* Identical ranges and register indices but different type. */ /* Identical ranges and register indices but different type. */
descriptor_ranges[1] = descriptor_ranges[0]; descriptor_ranges[1] = descriptor_ranges[0];