Descriptor indexing is not used and SM5.1 is mostly not supported. Allows new SM5.1 tests to be skipped.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index a63fc92b..877512e3 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1423,6 +1423,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->EXT_shader_demote_to_helper_invocation = false; if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment) vulkan_info->EXT_texel_buffer_alignment = false; + vulkan_info->EXT_descriptor_indexing = false;
vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties;
@@ -2728,7 +2729,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
TRACE("Request shader model %#x.\n", data->HighestShaderModel);
- data->HighestShaderModel = D3D_SHADER_MODEL_5_1; + data->HighestShaderModel = device->vk_info.EXT_descriptor_indexing + ? D3D_SHADER_MODEL_5_1 : D3D_SHADER_MODEL_5_0;
TRACE("Shader model %#x.\n", data->HighestShaderModel); return S_OK;
From: Hans-Kristian Arntzen post@arntzen-software.no
Modified to keep within current vkd3d descriptor set pool limits.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- tests/d3d12.c | 1424 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1424 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index f289a10d..7252e65e 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -651,6 +651,27 @@ static bool is_memory_pool_L1_supported(ID3D12Device *device) return !architecture.UMA; }
+#define context_supports_sm51(context) context_supports_sm51_(__LINE__, context) +static bool context_supports_sm51_(unsigned int line, struct test_context *context) +{ + D3D12_FEATURE_DATA_SHADER_MODEL model; + HRESULT hr; + model.HighestShaderModel = D3D_SHADER_MODEL_5_1; + hr = ID3D12Device_CheckFeatureSupport(context->device, D3D12_FEATURE_SHADER_MODEL, &model, sizeof(model)); + ok_(line)(hr == S_OK, "Failed to query shader model support, hr %#x.\n", hr); + + if (hr != S_OK) + return false; + + if (model.HighestShaderModel < D3D_SHADER_MODEL_5_1) + { + skip_(line)("Device does not support shader model 5.1, skipping resource array tests.\n"); + return false; + } + else + return true; +} + #define create_cb_root_signature(a, b, c, e) create_cb_root_signature_(__LINE__, a, b, c, e) static ID3D12RootSignature *create_cb_root_signature_(unsigned int line, ID3D12Device *device, unsigned int reg_idx, D3D12_SHADER_VISIBILITY shader_visibility, @@ -33817,6 +33838,1402 @@ static void test_hull_shader_patch_constant_inputs(void) destroy_test_context(&context); }
+static void test_unbounded_srv(void) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[3]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[4]; + ID3D12DescriptorHeap* heap; + + ID3D12Resource *input_buffers[128]; + ID3D12Resource *input_textures[128]; + ID3D12Resource *output_buffer; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + // Space 1 and 2 have an offset of 0 descriptors, so pattern of descriptors is + // [ buf, tex, buf, tex ] + StructuredBuffer<uint> Buffers[] : register(t4, space1); + Texture2D<uint> Textures[] : register(t4, space2); + + // Space 3 and 4 have an effective offset of 2 descriptor, + // so pattern of descriptors is still + // [ buf, tex, buf, tex ] + StructuredBuffer<uint> AliasBuffers[64] : register(t4, space3); + Texture2D<uint> AliasTextures[64] : register(t4, space4); + + StructuredBuffer<uint> StandaloneBuffer : register(t100, space3); + Texture2D<uint> StandaloneTexture : register(t199, space3); + + RWByteAddressBuffer OBuffer : register(u0); + + [numthreads(64, 1, 1)] + void main(uint idx : SV_DispatchThreadID) + { + uint result = 0; + + if (idx & 1) + result += Textures[NonUniformResourceIndex(idx)].Load(int3(0, 0, 0)); + else + result += Buffers[NonUniformResourceIndex(idx)].Load(0); + + if (idx & 1) + result += AliasTextures[NonUniformResourceIndex(idx)].Load(int3(0, 0, 0)) << 8; + else + result += AliasBuffers[NonUniformResourceIndex(idx)].Load(0) << 8; + + result *= StandaloneBuffer.Load(0); + result *= StandaloneTexture.Load(int3(0, 0, 0)); + OBuffer.Store(4 * idx, result); + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x2b452826, 0x244a6b65, 0xdf8a8f8b, 0xf8326669, 0x00000001, 0x000003c4, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000370, 0x00050051, 0x000000dc, 0x0100086a, + 0x070000a2, 0x00307e46, 0x00000000, 0x00000004, 0xffffffff, 0x00000004, 0x00000001, 0x07001858, + 0x00307e46, 0x00000001, 0x00000004, 0xffffffff, 0x00004444, 0x00000002, 0x070000a2, 0x00307e46, + 0x00000002, 0x00000004, 0x00000043, 0x00000004, 0x00000003, 0x070000a2, 0x00307e46, 0x00000003, + 0x00000064, 0x00000064, 0x00000004, 0x00000003, 0x07001858, 0x00307e46, 0x00000004, 0x000000c7, + 0x000000c7, 0x00004444, 0x00000003, 0x07001858, 0x00307e46, 0x00000005, 0x00000004, 0x00000043, + 0x00004444, 0x00000004, 0x0600009d, 0x0031ee46, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, + 0x06000001, 0x00100012, 0x00000000, 0x0002000a, 0x00004001, 0x00000001, 0x0304001f, 0x0010000a, + 0x00000000, 0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x0e00002d, 0x00100012, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x86207e46, 0x00020001, 0x00000001, + 0x00000004, 0x0010000a, 0x00000000, 0x04000036, 0x00100042, 0x00000000, 0x0002000a, 0x0e00002d, + 0x00100042, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x86207c96, + 0x00020001, 0x00000005, 0x00000004, 0x0010002a, 0x00000000, 0x07000029, 0x00100042, 0x00000000, + 0x0010002a, 0x00000000, 0x00004001, 0x00000008, 0x0700001e, 0x00100012, 0x00000000, 0x0010002a, + 0x00000000, 0x0010000a, 0x00000000, 0x01000012, 0x04000036, 0x00100022, 0x00000000, 0x0002000a, + 0x0d0000a7, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x86207006, + 0x00020001, 0x00000000, 0x00000004, 0x0010001a, 0x00000000, 0x04000036, 0x00100042, 0x00000000, + 0x0002000a, 0x0d0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x86207006, 0x00020001, 0x00000002, 0x00000004, 0x0010002a, 0x00000000, 0x07000029, 0x00100042, + 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000008, 0x0700001e, 0x00100012, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x01000015, 0x0a0000a7, 0x00100022, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000003, 0x00000064, 0x08000026, + 0x0000d000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0b00002d, + 0x00100022, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00207e16, + 0x00000004, 0x000000c7, 0x08000026, 0x0000d000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, + 0x0010000a, 0x00000000, 0x06000029, 0x00100022, 0x00000000, 0x0002000a, 0x00004001, 0x00000002, + 0x080000a6, 0x0021e012, 0x00000000, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, + 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 3; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 2; + root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0]; + + root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[1].DescriptorTable.NumDescriptorRanges = 2; + root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[2]; + + root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[2].Descriptor.RegisterSpace = 0; + root_parameters[2].Descriptor.ShaderRegister = 0; + + /* Need two idential ranges so we can alias two different resource dimensions over same table. */ + for (i = 0; i < 4; ++i) + { + descriptor_ranges[i].RegisterSpace = i + 1; + descriptor_ranges[i].BaseShaderRegister = 4; + descriptor_ranges[i].OffsetInDescriptorsFromTableStart = i >= 2 ? 1 : 0; + descriptor_ranges[i].NumDescriptors = UINT_MAX; + descriptor_ranges[i].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + } + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(input_buffers); ++i) + { + const UINT buffer_data[] = { i * 2, i * 2, i * 2, i * 2 }; + input_buffers[i] = create_default_buffer(context.device, sizeof(buffer_data), D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data), buffer_data, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } + + for (i = 0; i < ARRAY_SIZE(input_textures); ++i) + { + const UINT tex_data = i * 2 + 1; + D3D12_SUBRESOURCE_DATA sub; + sub.pData = &tex_data; + sub.RowPitch = 1; + sub.SlicePitch = 1; + input_textures[i] = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_texture_data(input_textures[i], &sub, 1, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_textures[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } + output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode((const void*)cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 512 + 256); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + for (i = 0; i < ARRAY_SIZE(input_buffers) * 2; ++i) + { + D3D12_SHADER_RESOURCE_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + h.ptr += (512 + i) * descriptor_size; + + /* Every other resource is a buffer and texture SRV which are aliased over the same descriptor table range. */ + if (i & 1) + { + view.Format = DXGI_FORMAT_R32_UINT; + view.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + view.Texture2D.MipLevels = 1; + view.Texture2D.MostDetailedMip = 0; + view.Texture2D.PlaneSlice = 0; + view.Texture2D.ResourceMinLODClamp = 0; + ID3D12Device_CreateShaderResourceView(context.device, input_textures[i >> 1], &view, h); + } + else + { + view.Format = DXGI_FORMAT_UNKNOWN; + view.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + view.Buffer.FirstElement = 0; + view.Buffer.NumElements = 4; + view.Buffer.StructureByteStride = 4; + view.Buffer.Flags = 0; + ID3D12Device_CreateShaderResourceView(context.device, input_buffers[i >> 1], &view, h); + } + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + { + D3D12_GPU_DESCRIPTOR_HANDLE gpu = gpu_handle; + gpu.ptr += 512 * descriptor_size; + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu); + gpu.ptr += descriptor_size; + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1, gpu); + } + ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 2, ID3D12Resource_GetGPUVirtualAddress(output_buffer)); + ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1); + + transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + for (i = 0; i < 64; ++i) + { + UINT value = get_readback_uint(&rb, i, 0, 0); + UINT reference = (i + (i + 2) * 256) * 98 * 197; + ok(value == reference, "Readback value is: %u\n", value); + } + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + for (i = 0; i < ARRAY_SIZE(input_buffers); ++i) + { + ID3D12Resource_Release(input_buffers[i]); + ID3D12Resource_Release(input_textures[i]); + } + ID3D12Resource_Release(output_buffer); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + +static void test_unbounded_samplers(void) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[3]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[2]; + ID3D12DescriptorHeap *heaps[2]; + + ID3D12Resource* input_texture; + ID3D12Resource* output_buffer; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + Texture2D<float> Tex : register(t0); + SamplerState Samp[] : register(s0); + RWByteAddressBuffer OBuffer : register(u0); + + [numthreads(64, 1, 1)] + void main(uint idx : SV_DispatchThreadID) + { + // Should alternate between wrap (sample 0), or clamp (sample 100). + uint value = Tex.SampleLevel(Samp[NonUniformResourceIndex(idx)], 1.1.xx, 0.0); + OBuffer.Store(4 * idx, value); + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x44f291da, 0x1146ced9, 0x71030deb, 0x28d62ae2, 0x00000001, 0x00000174, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000120, 0x00050051, 0x00000048, 0x0100086a, + 0x0600005a, 0x00306e46, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x07001858, 0x00307e46, + 0x00000000, 0x00000000, 0x00000000, 0x00005555, 0x00000000, 0x0600009d, 0x0031ee46, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, + 0x00000040, 0x00000001, 0x00000001, 0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x12000048, + 0x00100012, 0x00000000, 0x00004002, 0x3f8ccccd, 0x3f8ccccd, 0x00000000, 0x00000000, 0x00207e46, + 0x00000000, 0x00000000, 0x84206000, 0x00020001, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, + 0x00000000, 0x0500001c, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x06000029, 0x00100022, + 0x00000000, 0x0002000a, 0x00004001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000000, 0x00000000, + 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 3; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0]; + + root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[1].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[1]; + + root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[2].Descriptor.RegisterSpace = 0; + root_parameters[2].Descriptor.ShaderRegister = 0; + + descriptor_ranges[0].RegisterSpace = 0; + descriptor_ranges[0].BaseShaderRegister = 0; + descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0; + descriptor_ranges[0].NumDescriptors = 1; + descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + + descriptor_ranges[1].RegisterSpace = 0; + descriptor_ranges[1].BaseShaderRegister = 0; + descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 0; + descriptor_ranges[1].NumDescriptors = UINT_MAX; + descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + { + const float tex_data[] = { 10, 100, 100, 100 }; + D3D12_SUBRESOURCE_DATA sub; + sub.pData = tex_data; + sub.RowPitch = 8; + sub.SlicePitch = 8; + input_texture = create_default_texture2d(context.device, 2, 2, 1, 1, DXGI_FORMAT_R32_FLOAT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_texture_data(input_texture, &sub, 1, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } + + output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode((const void*)cs_code, sizeof(cs_code))); + + heaps[0] = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1); + heaps[1] = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1024); + + { + D3D12_SHADER_RESOURCE_VIEW_DESC view; + view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + view.Format = DXGI_FORMAT_R32_FLOAT; + view.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + view.Texture2D.MipLevels = 1; + view.Texture2D.MostDetailedMip = 0; + view.Texture2D.PlaneSlice = 0; + view.Texture2D.ResourceMinLODClamp = 0; + ID3D12Device_CreateShaderResourceView(context.device, input_texture, &view, + ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heaps[0])); + } + + for (i = 0; i < 1024; ++i) + { + D3D12_SAMPLER_DESC samp; + memset(&samp, 0, sizeof(samp)); + samp.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + samp.AddressU = samp.AddressV = samp.AddressW = (i & 1) ? D3D12_TEXTURE_ADDRESS_MODE_CLAMP : D3D12_TEXTURE_ADDRESS_MODE_WRAP; + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heaps[1]); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + cpu_handle.ptr += descriptor_size * i; + ID3D12Device_CreateSampler(context.device, &samp, cpu_handle); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 2, heaps); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heaps[0])); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1, ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heaps[1])); + ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 2, ID3D12Resource_GetGPUVirtualAddress(output_buffer)); + ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1); + + transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + for (i = 0; i < 64; ++i) + { + UINT value = get_readback_uint(&rb, i, 0, 0); + UINT reference = (i & 1) ? 100 : 10; + ok(value == reference, "Readback value for index %u is: %u\n", i, value); + } + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + ID3D12Resource_Release(input_texture); + ID3D12Resource_Release(output_buffer); + ID3D12DescriptorHeap_Release(heaps[0]); + ID3D12DescriptorHeap_Release(heaps[1]); + destroy_test_context(&context); +} + +#define BUFFER_COUNT (61 + 8) + +static void test_bindless_full_root_parameters(void) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[63]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[63]; + ID3D12DescriptorHeap* heap; + + ID3D12Resource* input_buffers[BUFFER_COUNT]; + ID3D12Resource* output_buffer; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + #define R(x) StructuredBuffer<uint> Buffers##x[] : register(t0, space##x) + R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); + R(10); R(11); R(12); R(13); R(14); R(15); R(16); R(17); R(18); R(19); + R(20); R(21); R(22); R(23); R(24); R(25); R(26); R(27); R(28); R(29); + R(30); R(31); R(32); R(33); R(34); R(35); R(36); R(37); R(38); R(39); + R(40); R(41); R(42); R(43); R(44); R(45); R(46); R(47); R(48); R(49); + R(50); R(51); R(52); R(53); R(54); R(55); R(56); R(57); R(58); R(59); + R(60); R(61); + #undef R + + RWByteAddressBuffer OBuffer : register(u0, space62); + + [numthreads(8, 1, 1)] + void main(uint idx : SV_DispatchThreadID) + { + uint result = 0; + #define R(x) result += Buffers##x[NonUniformResourceIndex(idx)].Load(0) + R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); + R(10); R(11); R(12); R(13); R(14); R(15); R(16); R(17); R(18); R(19); + R(20); R(21); R(22); R(23); R(24); R(25); R(26); R(27); R(28); R(29); + R(30); R(31); R(32); R(33); R(34); R(35); R(36); R(37); R(38); R(39); + R(40); R(41); R(42); R(43); R(44); R(45); R(46); R(47); R(48); R(49); + R(50); R(51); R(52); R(53); R(54); R(55); R(56); R(57); R(58); R(59); + R(60); R(61); + #undef R + OBuffer.Store(4 * idx, result); + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x14c36cde, 0x43afd9ea, 0x4f0f1a58, 0x160d65a7, 0x00000001, 0x000019f8, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000019a4, 0x00050051, 0x00000669, 0x0100086a, + 0x070000a2, 0x00307e46, 0x00000000, 0x00000000, 0xffffffff, 0x00000004, 0x00000000, 0x070000a2, + 0x00307e46, 0x00000001, 0x00000000, 0xffffffff, 0x00000004, 0x00000001, 0x070000a2, 0x00307e46, + 0x00000002, 0x00000000, 0xffffffff, 0x00000004, 0x00000002, 0x070000a2, 0x00307e46, 0x00000003, + 0x00000000, 0xffffffff, 0x00000004, 0x00000003, 0x070000a2, 0x00307e46, 0x00000004, 0x00000000, + 0xffffffff, 0x00000004, 0x00000004, 0x070000a2, 0x00307e46, 0x00000005, 0x00000000, 0xffffffff, + 0x00000004, 0x00000005, 0x070000a2, 0x00307e46, 0x00000006, 0x00000000, 0xffffffff, 0x00000004, + 0x00000006, 0x070000a2, 0x00307e46, 0x00000007, 0x00000000, 0xffffffff, 0x00000004, 0x00000007, + 0x070000a2, 0x00307e46, 0x00000008, 0x00000000, 0xffffffff, 0x00000004, 0x00000008, 0x070000a2, + 0x00307e46, 0x00000009, 0x00000000, 0xffffffff, 0x00000004, 0x00000009, 0x070000a2, 0x00307e46, + 0x0000000a, 0x00000000, 0xffffffff, 0x00000004, 0x0000000a, 0x070000a2, 0x00307e46, 0x0000000b, + 0x00000000, 0xffffffff, 0x00000004, 0x0000000b, 0x070000a2, 0x00307e46, 0x0000000c, 0x00000000, + 0xffffffff, 0x00000004, 0x0000000c, 0x070000a2, 0x00307e46, 0x0000000d, 0x00000000, 0xffffffff, + 0x00000004, 0x0000000d, 0x070000a2, 0x00307e46, 0x0000000e, 0x00000000, 0xffffffff, 0x00000004, + 0x0000000e, 0x070000a2, 0x00307e46, 0x0000000f, 0x00000000, 0xffffffff, 0x00000004, 0x0000000f, + 0x070000a2, 0x00307e46, 0x00000010, 0x00000000, 0xffffffff, 0x00000004, 0x00000010, 0x070000a2, + 0x00307e46, 0x00000011, 0x00000000, 0xffffffff, 0x00000004, 0x00000011, 0x070000a2, 0x00307e46, + 0x00000012, 0x00000000, 0xffffffff, 0x00000004, 0x00000012, 0x070000a2, 0x00307e46, 0x00000013, + 0x00000000, 0xffffffff, 0x00000004, 0x00000013, 0x070000a2, 0x00307e46, 0x00000014, 0x00000000, + 0xffffffff, 0x00000004, 0x00000014, 0x070000a2, 0x00307e46, 0x00000015, 0x00000000, 0xffffffff, + 0x00000004, 0x00000015, 0x070000a2, 0x00307e46, 0x00000016, 0x00000000, 0xffffffff, 0x00000004, + 0x00000016, 0x070000a2, 0x00307e46, 0x00000017, 0x00000000, 0xffffffff, 0x00000004, 0x00000017, + 0x070000a2, 0x00307e46, 0x00000018, 0x00000000, 0xffffffff, 0x00000004, 0x00000018, 0x070000a2, + 0x00307e46, 0x00000019, 0x00000000, 0xffffffff, 0x00000004, 0x00000019, 0x070000a2, 0x00307e46, + 0x0000001a, 0x00000000, 0xffffffff, 0x00000004, 0x0000001a, 0x070000a2, 0x00307e46, 0x0000001b, + 0x00000000, 0xffffffff, 0x00000004, 0x0000001b, 0x070000a2, 0x00307e46, 0x0000001c, 0x00000000, + 0xffffffff, 0x00000004, 0x0000001c, 0x070000a2, 0x00307e46, 0x0000001d, 0x00000000, 0xffffffff, + 0x00000004, 0x0000001d, 0x070000a2, 0x00307e46, 0x0000001e, 0x00000000, 0xffffffff, 0x00000004, + 0x0000001e, 0x070000a2, 0x00307e46, 0x0000001f, 0x00000000, 0xffffffff, 0x00000004, 0x0000001f, + 0x070000a2, 0x00307e46, 0x00000020, 0x00000000, 0xffffffff, 0x00000004, 0x00000020, 0x070000a2, + 0x00307e46, 0x00000021, 0x00000000, 0xffffffff, 0x00000004, 0x00000021, 0x070000a2, 0x00307e46, + 0x00000022, 0x00000000, 0xffffffff, 0x00000004, 0x00000022, 0x070000a2, 0x00307e46, 0x00000023, + 0x00000000, 0xffffffff, 0x00000004, 0x00000023, 0x070000a2, 0x00307e46, 0x00000024, 0x00000000, + 0xffffffff, 0x00000004, 0x00000024, 0x070000a2, 0x00307e46, 0x00000025, 0x00000000, 0xffffffff, + 0x00000004, 0x00000025, 0x070000a2, 0x00307e46, 0x00000026, 0x00000000, 0xffffffff, 0x00000004, + 0x00000026, 0x070000a2, 0x00307e46, 0x00000027, 0x00000000, 0xffffffff, 0x00000004, 0x00000027, + 0x070000a2, 0x00307e46, 0x00000028, 0x00000000, 0xffffffff, 0x00000004, 0x00000028, 0x070000a2, + 0x00307e46, 0x00000029, 0x00000000, 0xffffffff, 0x00000004, 0x00000029, 0x070000a2, 0x00307e46, + 0x0000002a, 0x00000000, 0xffffffff, 0x00000004, 0x0000002a, 0x070000a2, 0x00307e46, 0x0000002b, + 0x00000000, 0xffffffff, 0x00000004, 0x0000002b, 0x070000a2, 0x00307e46, 0x0000002c, 0x00000000, + 0xffffffff, 0x00000004, 0x0000002c, 0x070000a2, 0x00307e46, 0x0000002d, 0x00000000, 0xffffffff, + 0x00000004, 0x0000002d, 0x070000a2, 0x00307e46, 0x0000002e, 0x00000000, 0xffffffff, 0x00000004, + 0x0000002e, 0x070000a2, 0x00307e46, 0x0000002f, 0x00000000, 0xffffffff, 0x00000004, 0x0000002f, + 0x070000a2, 0x00307e46, 0x00000030, 0x00000000, 0xffffffff, 0x00000004, 0x00000030, 0x070000a2, + 0x00307e46, 0x00000031, 0x00000000, 0xffffffff, 0x00000004, 0x00000031, 0x070000a2, 0x00307e46, + 0x00000032, 0x00000000, 0xffffffff, 0x00000004, 0x00000032, 0x070000a2, 0x00307e46, 0x00000033, + 0x00000000, 0xffffffff, 0x00000004, 0x00000033, 0x070000a2, 0x00307e46, 0x00000034, 0x00000000, + 0xffffffff, 0x00000004, 0x00000034, 0x070000a2, 0x00307e46, 0x00000035, 0x00000000, 0xffffffff, + 0x00000004, 0x00000035, 0x070000a2, 0x00307e46, 0x00000036, 0x00000000, 0xffffffff, 0x00000004, + 0x00000036, 0x070000a2, 0x00307e46, 0x00000037, 0x00000000, 0xffffffff, 0x00000004, 0x00000037, + 0x070000a2, 0x00307e46, 0x00000038, 0x00000000, 0xffffffff, 0x00000004, 0x00000038, 0x070000a2, + 0x00307e46, 0x00000039, 0x00000000, 0xffffffff, 0x00000004, 0x00000039, 0x070000a2, 0x00307e46, + 0x0000003a, 0x00000000, 0xffffffff, 0x00000004, 0x0000003a, 0x070000a2, 0x00307e46, 0x0000003b, + 0x00000000, 0xffffffff, 0x00000004, 0x0000003b, 0x070000a2, 0x00307e46, 0x0000003c, 0x00000000, + 0xffffffff, 0x00000004, 0x0000003c, 0x070000a2, 0x00307e46, 0x0000003d, 0x00000000, 0xffffffff, + 0x00000004, 0x0000003d, 0x0600009d, 0x0031ee46, 0x00000000, 0x00000000, 0x00000000, 0x0000003e, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000001, 0x00000001, + 0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x0c0000a7, 0x00100022, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000000, 0x0010000a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000001, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000002, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000003, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x00000004, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000005, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x00000006, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x00000007, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000008, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000009, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000a, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000b, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x0000000c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000d, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x0000000e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x0000000f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000010, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000011, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000012, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000013, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x00000014, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000015, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x00000016, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x00000017, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000018, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000019, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001a, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001b, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x0000001c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001d, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x0000001e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x0000001f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000020, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000021, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000022, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000023, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x00000024, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000025, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x00000026, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x00000027, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000028, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000029, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002a, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002b, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x0000002c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002d, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x0000002e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x0000002f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000030, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000031, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000032, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000033, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x00000034, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000035, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, + 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, + 0x00000036, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, + 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, + 0x00000000, 0x84207006, 0x00020001, 0x00000037, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, + 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, + 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000038, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, + 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, + 0x00020001, 0x00000039, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, + 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, + 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003a, 0x0010000a, 0x00000000, 0x0700001e, + 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003b, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x84207006, 0x00020001, 0x0000003c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, + 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100012, 0x00000000, 0x00004001, + 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003d, 0x0010000a, 0x00000000, + 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, 0x00000000, 0x06000029, + 0x00100022, 0x00000000, 0x0002000a, 0x00004001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000000, + 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 63; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + for (i = 0; i < 62; ++i) + { + root_parameters[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[i].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[i].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[i].DescriptorTable.pDescriptorRanges = &descriptor_ranges[i]; + + descriptor_ranges[i].RegisterSpace = i; + descriptor_ranges[i].BaseShaderRegister = 0; + descriptor_ranges[i].OffsetInDescriptorsFromTableStart = 0; + descriptor_ranges[i].NumDescriptors = 8; + descriptor_ranges[i].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + } + + root_parameters[62].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + root_parameters[62].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[62].Descriptor.RegisterSpace = 62; + root_parameters[62].Descriptor.ShaderRegister = 0; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < BUFFER_COUNT; ++i) + { + const UINT buffer_data[] = { i, i, i, i }; + input_buffers[i] = create_default_buffer(context.device, sizeof(buffer_data), D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data), buffer_data, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } + output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode(cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, BUFFER_COUNT); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + for (i = 0; i < BUFFER_COUNT; ++i) + { + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + D3D12_SHADER_RESOURCE_VIEW_DESC view; + + h.ptr += i * descriptor_size; + + view.Format = DXGI_FORMAT_UNKNOWN; + view.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + view.Buffer.FirstElement = 0; + view.Buffer.NumElements = 4; + view.Buffer.StructureByteStride = 4; + view.Buffer.Flags = 0; + ID3D12Device_CreateShaderResourceView(context.device, input_buffers[i], &view, h); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + + for (i = 0; i < 62; ++i) + { + D3D12_GPU_DESCRIPTOR_HANDLE gpu = gpu_handle; + gpu.ptr += i * descriptor_size; + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, i, gpu); + } + ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 62, ID3D12Resource_GetGPUVirtualAddress(output_buffer)); + ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1); + + transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + for (i = 0; i < 8; ++i) + { + UINT value = get_readback_uint(&rb, i, 0, 0); + UINT reference = 62 * (i + (i + 61)) / 2; + ok(value == reference, "Readback value is: %u\n", value); + } + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + for (i = 0; i < BUFFER_COUNT; ++i) + ID3D12Resource_Release(input_buffers[i]); + ID3D12Resource_Release(output_buffer); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + +#undef BUFFER_COUNT + +static void test_unbounded_cbv() +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[2]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges; + ID3D12DescriptorHeap* heap; + + ID3D12Resource* input_buffers[512]; + ID3D12Resource* output_buffer; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + struct Foo + { + uint value; + }; + ConstantBuffer<Foo> CBVs[] : register(b2, space1); + + RWByteAddressBuffer RWBuf : register(u0); + + [numthreads(64, 1, 1)] + void main(uint index : SV_DispatchThreadID) + { + uint value = CBVs[NonUniformResourceIndex(index)].value; + RWBuf.Store(4 * index, value); + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x15b62447, 0xbdab3867, 0x4685eb54, 0xf1bf1b23, 0x00000001, 0x00000114, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c0, 0x00050051, 0x00000030, 0x0100086a, + 0x07000859, 0x00308e46, 0x00000000, 0x00000002, 0xffffffff, 0x00000001, 0x00000001, 0x0600009d, + 0x0031ee46, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200005f, 0x00020012, 0x02000068, + 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, 0x06000029, 0x00100012, 0x00000000, + 0x0002000a, 0x00004001, 0x00000002, 0x04000036, 0x00100022, 0x00000000, 0x0002000a, 0x0d0000a6, + 0x0021e012, 0x00000000, 0x00000000, 0x0010000a, 0x00000000, 0x8630800a, 0x00020001, 0x00000000, + 0x00000002, 0x0010001a, 0x00000000, 0x00000000, 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 2; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges; + + root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[1].Descriptor.RegisterSpace = 0; + root_parameters[1].Descriptor.ShaderRegister = 0; + + descriptor_ranges.RegisterSpace = 1; + descriptor_ranges.BaseShaderRegister = 2; + descriptor_ranges.OffsetInDescriptorsFromTableStart = 1; + descriptor_ranges.NumDescriptors = UINT_MAX; + descriptor_ranges.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < 512; ++i) + { + const UINT buffer_data[] = { i, i, i, i }; + input_buffers[i] = create_default_buffer(context.device, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data), buffer_data, queue, command_list); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } + + output_buffer = create_default_buffer(context.device, 4 * 256, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode((const void*)cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + for (i = 0; i < 512; ++i) + { + D3D12_CONSTANT_BUFFER_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(input_buffers[i]); + view.SizeInBytes = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT; + h.ptr += i * descriptor_size; + ID3D12Device_CreateConstantBufferView(context.device, &view, h); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_handle); + ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 1, ID3D12Resource_GetGPUVirtualAddress(output_buffer)); + ID3D12GraphicsCommandList_Dispatch(command_list, 4, 1, 1); + + transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + for (i = 0; i < 256; ++i) + { + UINT value = get_readback_uint(&rb, i, 0, 0); + UINT reference = i + 1; + + ok(value == reference, "Readback value for iteration %u is: %u\n", i, value); + } + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + for (i = 0; i < 512; ++i) + ID3D12Resource_Release(input_buffers[i]); + ID3D12Resource_Release(output_buffer); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + +static void test_unbounded_uav() +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[1]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[2]; + ID3D12DescriptorHeap *heap; + + ID3D12Resource *output_buffers[256]; + ID3D12Resource *output_textures[256]; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + RWStructuredBuffer<uint> Buffers[] : register(u2, space1); + RWTexture2D<uint> Textures[] : register(u2, space2); + + [numthreads(64, 1, 1)] + void main(uint global_index : SV_DispatchThreadID, uint index : SV_GroupID) + { + // Need this branch or FXC refuses to compile. It doesn't understand we're writing to different resources. + if (global_index < 512) + { + Buffers[NonUniformResourceIndex(global_index)][0] = global_index + 1; + Textures[NonUniformResourceIndex(global_index)][int2(0, 0)] = 256 + global_index + 1; + } + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x7f1b7f4d, 0xd41e1bd6, 0x1fdc0577, 0xc59de64e, 0x00000001, 0x00000184, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000130, 0x00050051, 0x0000004c, 0x0100086a, + 0x0700009e, 0x0031ee46, 0x00000000, 0x00000002, 0xffffffff, 0x00000004, 0x00000001, 0x0700189c, + 0x0031ee46, 0x00000001, 0x00000002, 0xffffffff, 0x00004444, 0x00000002, 0x0200005f, 0x00020012, + 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, 0x0600004f, 0x00100012, + 0x00000000, 0x0002000a, 0x00004001, 0x00000200, 0x0304001f, 0x0010000a, 0x00000000, 0x0900001e, + 0x00100032, 0x00000000, 0x00020006, 0x00004002, 0x00000001, 0x00000101, 0x00000000, 0x00000000, + 0x04000036, 0x00100042, 0x00000000, 0x0002000a, 0x0d0000a8, 0x8621e012, 0x00020001, 0x00000000, + 0x00000002, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0010000a, + 0x00000000, 0x0e0000a4, 0x8621e0f2, 0x00020001, 0x00000001, 0x00000002, 0x0010002a, 0x00000000, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100556, 0x00000000, 0x01000015, + 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 1; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 2; + root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges; + + descriptor_ranges[0].RegisterSpace = 1; + descriptor_ranges[0].BaseShaderRegister = 2; + descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 1; + descriptor_ranges[0].NumDescriptors = UINT_MAX; + descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + + descriptor_ranges[1].RegisterSpace = 2; + descriptor_ranges[1].BaseShaderRegister = 2; + descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 256 + 1; + descriptor_ranges[1].NumDescriptors = UINT_MAX; + descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < 256; ++i) + output_buffers[i] = create_default_buffer(context.device, 256, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + for (i = 0; i < 256; ++i) + output_textures[i] = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode((const void*)cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.Format = DXGI_FORMAT_UNKNOWN; + view.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + view.Buffer.FirstElement = 0; + view.Buffer.NumElements = 64; + view.Buffer.StructureByteStride = 4; + view.Buffer.CounterOffsetInBytes = 0; + view.Buffer.Flags = 0; + h.ptr += (i + 1) * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_buffers[i], NULL, &view, h); + } + + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.Format = DXGI_FORMAT_R32_UINT; + view.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + view.Texture2D.MipSlice = 0; + view.Texture2D.PlaneSlice = 0; + h.ptr += (256 + i + 1) * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_textures[i], NULL, &view, h); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_handle); + ID3D12GraphicsCommandList_Dispatch(command_list, 4, 1, 1); + + for (i = 0; i < 256; ++i) + transition_resource_state(command_list, output_buffers[i], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + for (i = 0; i < 256; ++i) + transition_resource_state(command_list, output_textures[i], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + + for (i = 0; i < 256; ++i) + { + UINT value; + UINT reference = i + 1; + + get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + value = get_readback_uint(&rb, 0, 0, 0); + + ok(value == reference, "Readback value for buffer iteration %u is: %u\n", i, value); + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 256; ++i) + { + UINT value; + UINT reference = i + 1 + 256; + get_texture_readback_with_command_list(output_textures[i], 0, &rb, queue, command_list); + + value = get_readback_uint(&rb, 0, 0, 0); + ok(value == reference, "Readback value for texture iteration %u is: %u\n", i, value); + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 256; ++i) + ID3D12Resource_Release(output_buffers[i]); + for (i = 0; i < 256; ++i) + ID3D12Resource_Release(output_textures[i]); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + +static void test_unbounded_uav_counter(void) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[1]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[1]; + ID3D12DescriptorHeap *heap, *cpu_heap; + + ID3D12Resource *output_buffers[256]; + struct resource_readback rb; + + ID3D12GraphicsCommandList* command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue* queue; + HRESULT hr; + +#if 0 + RWStructuredBuffer<uint> Buffers[] : register(u2, space1); + + [numthreads(64, 1, 1)] + void main(uint global_index : SV_DispatchThreadID, uint index : SV_GroupID) + { + // Need branch here or FXC complains about race condition. + if (global_index < 512) + { + Buffers[NonUniformResourceIndex(global_index)][0] = global_index + 1; + Buffers[NonUniformResourceIndex(global_index & ~3)].IncrementCounter(); + } + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0x3282d7ba, 0xcefa5b07, 0xd66c504b, 0xe11b90a0, 0x00000001, 0x00000160, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000010c, 0x00050051, 0x00000043, 0x0100086a, + 0x0700009e, 0x0031ee46, 0x00000000, 0x00000002, 0xffffffff, 0x00000004, 0x00000001, 0x0200005f, + 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, 0x0600004f, + 0x00100012, 0x00000000, 0x0002000a, 0x00004001, 0x00000200, 0x0304001f, 0x0010000a, 0x00000000, + 0x0600001e, 0x00100012, 0x00000000, 0x0002000a, 0x00004001, 0x00000001, 0x04000036, 0x00100022, + 0x00000000, 0x0002000a, 0x0d0000a8, 0x8621e012, 0x00020001, 0x00000000, 0x00000002, 0x0010001a, + 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x06000001, + 0x00100012, 0x00000000, 0x0002000a, 0x00004001, 0x007ffffc, 0x090000b2, 0x00100012, 0x00000000, + 0x8621e000, 0x00020001, 0x00000000, 0x00000002, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 1; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 1; + root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges; + + descriptor_ranges[0].RegisterSpace = 1; + descriptor_ranges[0].BaseShaderRegister = 2; + descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 1; + descriptor_ranges[0].NumDescriptors = UINT_MAX; + descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < 256; ++i) + output_buffers[i] = create_default_buffer(context.device, 256, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode((const void*)cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + + view.Format = DXGI_FORMAT_UNKNOWN; + view.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + view.Buffer.FirstElement = 1; + view.Buffer.NumElements = 63; + view.Buffer.StructureByteStride = 4; + view.Buffer.CounterOffsetInBytes = 0; + view.Buffer.Flags = 0; + h.ptr += (i + 1) * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_buffers[i], output_buffers[i ^ 1], &view, h); + } + + /* Cannot UAV clear structured buffers, so use a separate raw byte address buffer for that. */ + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_h = cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_h = gpu_handle; + static const UINT init_data[4] = { 10, 10, 10, 10 }; + + cpu_h.ptr += (512 + i) * descriptor_size; + gpu_h.ptr += (512 + i) * descriptor_size; + + view.Format = DXGI_FORMAT_R32_TYPELESS; + view.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + view.Buffer.FirstElement = 0; + view.Buffer.NumElements = 64; + view.Buffer.StructureByteStride = 0; + view.Buffer.CounterOffsetInBytes = 0; + view.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; + + ID3D12Device_CreateUnorderedAccessView(context.device, output_buffers[i], NULL, &view, cpu_h); + cpu_h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_heap); + cpu_h.ptr += (512 + i) * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_buffers[i], NULL, &view, cpu_h); + ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list, gpu_h, cpu_h, output_buffers[i], init_data, 0, NULL); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_handle); + ID3D12GraphicsCommandList_Dispatch(command_list, 4, 1, 1); + + for (i = 0; i < 256; ++i) + transition_resource_state(command_list, output_buffers[i], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + + for (i = 0; i < 256; ++i) + { + UINT value; + UINT reference = i + 1; + get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + value = get_readback_uint(&rb, 1, 0, 0); + ok(value == reference, "Readback value for buffer iteration %u is: %u\n", i, value); + + value = get_readback_uint(&rb, 0, 0, 0); + reference = ((i ^ 1) & 3) == 0 ? 14 : 10; + todo_if(reference == 14) ok(value == reference, "Readback value for buffer counter iteration %u is: %u\n", i, value); + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 256; ++i) + ID3D12Resource_Release(output_buffers[i]); + ID3D12DescriptorHeap_Release(heap); + ID3D12DescriptorHeap_Release(cpu_heap); + destroy_test_context(&context); +} + +static void test_unbounded_bufinfo(void) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + D3D12_ROOT_PARAMETER root_parameters[1]; + D3D12_DESCRIPTOR_RANGE descriptor_ranges[2]; + ID3D12DescriptorHeap *heap; + + ID3D12Resource *output_buffers[256]; + ID3D12Resource *output_textures[256]; + struct resource_readback rb; + + ID3D12GraphicsCommandList *command_list; + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; + unsigned int i, descriptor_size; + struct test_context context; + ID3D12CommandQueue *queue; + HRESULT hr; + +#if 0 + RWStructuredBuffer<uint> RWBuf[] : register(u0, space0); + RWTexture2D<uint> RWTex[] : register(u0, space1); + + [numthreads(64, 1, 1)] + void main(uint2 thr : SV_DispatchThreadID) + { + uint width, height, count, stride; + RWTex[NonUniformResourceIndex(thr.x)].GetDimensions(width, height); + + if (thr.y == 0) + RWTex[NonUniformResourceIndex(thr.x)][int2(0, 0)] = width; + + RWBuf[NonUniformResourceIndex(thr.x)].GetDimensions(count, stride); + if (thr.y == 0) + RWBuf[NonUniformResourceIndex(thr.x)][0] = count; + } +#endif + static const DWORD cs_code[] = + { + 0x43425844, 0xd997b29f, 0xbe9e2ef9, 0xe48c0c37, 0x0829289c, 0x00000001, 0x00000190, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000013c, 0x00050051, 0x0000004f, 0x0100086a, + 0x0700009e, 0x0031ee46, 0x00000000, 0x00000000, 0xffffffff, 0x00000004, 0x00000000, 0x0700189c, + 0x0031ee46, 0x00000001, 0x00000000, 0xffffffff, 0x00004444, 0x00000001, 0x0200005f, 0x00020032, + 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, 0x04000036, 0x00100012, + 0x00000000, 0x0002000a, 0x0a00103d, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x8421ee16, + 0x00020001, 0x00000001, 0x0010000a, 0x00000000, 0x0200001f, 0x0002001a, 0x0d0000a4, 0x8421e0f2, + 0x00020001, 0x00000001, 0x0010000a, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100556, 0x00000000, 0x01000015, 0x08000079, 0x00100022, 0x00000000, 0x8421ee16, + 0x00020001, 0x00000000, 0x0010000a, 0x00000000, 0x0200001f, 0x0002001a, 0x0c0000a8, 0x8421e012, + 0x00020001, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, + 0x0010001a, 0x00000000, 0x01000015, 0x0100003e, + }; + + if (!init_compute_test_context(&context) || !context_supports_sm51(&context)) + return; + + command_list = context.list; + queue = context.queue; + + root_signature_desc.NumParameters = 1; + root_signature_desc.Flags = 0; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.pParameters = root_parameters; + + root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + root_parameters[0].DescriptorTable.NumDescriptorRanges = 2; + root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges; + + descriptor_ranges[0].RegisterSpace = 0; + descriptor_ranges[0].BaseShaderRegister = 0; + descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0; + descriptor_ranges[0].NumDescriptors = UINT_MAX; + descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + + descriptor_ranges[1].RegisterSpace = 1; + descriptor_ranges[1].BaseShaderRegister = 0; + descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 256; + descriptor_ranges[1].NumDescriptors = UINT_MAX; + descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + + hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature); + ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + for (i = 0; i < 256; ++i) + output_buffers[i] = create_default_buffer(context.device, 4096, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + for (i = 0; i < 256; ++i) + output_textures[i] = create_default_texture2d(context.device, i + 1, 1, 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + context.pipeline_state = create_compute_pipeline_state(context.device, + context.root_signature, + shader_bytecode(cs_code, sizeof(cs_code))); + + heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.Format = DXGI_FORMAT_UNKNOWN; + view.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + view.Buffer.FirstElement = i & 3; /* Unaligned FirstElement might affect bufinfo computation if we have to emulate alignment. */ + view.Buffer.NumElements = 1 + i; + view.Buffer.StructureByteStride = 4; + view.Buffer.CounterOffsetInBytes = 0; + view.Buffer.Flags = 0; + h.ptr += i * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_buffers[i], NULL, &view, h); + } + + for (i = 0; i < 256; ++i) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC view; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle; + view.Format = DXGI_FORMAT_R32_UINT; + view.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + view.Texture2D.MipSlice = 0; + view.Texture2D.PlaneSlice = 0; + h.ptr += (256 + i) * descriptor_size; + ID3D12Device_CreateUnorderedAccessView(context.device, output_textures[i], NULL, &view, h); + } + + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_handle); + ID3D12GraphicsCommandList_Dispatch(command_list, 4, 1, 1); + + for (i = 0; i < 256; ++i) + transition_resource_state(command_list, output_buffers[i], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + for (i = 0; i < 256; ++i) + transition_resource_state(command_list, output_textures[i], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + + for (i = 0; i < 256; ++i) + { + UINT value; + UINT reference = i + 1; + get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + + value = get_readback_uint(&rb, i & 3, 0, 0); + ok(value == reference, "Readback value for buffer iteration %u is: %u\n", i, value); + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 256; ++i) + { + UINT value; + UINT reference = i + 1; + get_texture_readback_with_command_list(output_textures[i], 0, &rb, queue, command_list); + + value = get_readback_uint(&rb, 0, 0, 0); + ok(value == reference, "Readback value for texture iteration %u is: %u\n", i, value); + + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 256; ++i) + ID3D12Resource_Release(output_buffers[i]); + for (i = 0; i < 256; ++i) + ID3D12Resource_Release(output_textures[i]); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + START_TEST(d3d12) { parse_args(argc, argv); @@ -33985,4 +35402,11 @@ START_TEST(d3d12) run_test(test_sampler_register_space); run_test(test_hull_shader_relative_addressing); run_test(test_hull_shader_patch_constant_inputs); + run_test(test_unbounded_srv); + run_test(test_unbounded_samplers); + run_test(test_bindless_full_root_parameters); + run_test(test_unbounded_cbv); + run_test(test_unbounded_uav); + run_test(test_unbounded_uav_counter); + run_test(test_unbounded_bufinfo); }
On 5/26/21 3:04 AM, Conor McCarthy wrote:
From: Hans-Kristian Arntzen post@arntzen-software.no
Modified to keep within current vkd3d descriptor set pool limits.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
tests/d3d12.c | 1424 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1424 insertions(+)
So, it goes without saying, but this is a lot of code to send at once, and a lot for one patch, and it would be relatively easy to break this up by test function.
Nevertheless, I'll try to give a complete review...
diff --git a/tests/d3d12.c b/tests/d3d12.c index f289a10d..7252e65e 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -651,6 +651,27 @@ static bool is_memory_pool_L1_supported(ID3D12Device *device) return !architecture.UMA; }
+#define context_supports_sm51(context) context_supports_sm51_(__LINE__, context) +static bool context_supports_sm51_(unsigned int line, struct test_context *context) +{
- D3D12_FEATURE_DATA_SHADER_MODEL model;
- HRESULT hr;
- model.HighestShaderModel = D3D_SHADER_MODEL_5_1;
- hr = ID3D12Device_CheckFeatureSupport(context->device, D3D12_FEATURE_SHADER_MODEL, &model, sizeof(model));
- ok_(line)(hr == S_OK, "Failed to query shader model support, hr %#x.\n", hr);
- if (hr != S_OK)
return false;
- if (model.HighestShaderModel < D3D_SHADER_MODEL_5_1)
- {
skip_(line)("Device does not support shader model 5.1, skipping resource array tests.\n");
return false;
- }
- else
return true;
+}
This should probably resemble the other is_*_supported() helpers.
#define create_cb_root_signature(a, b, c, e) create_cb_root_signature_(__LINE__, a, b, c, e) static ID3D12RootSignature *create_cb_root_signature_(unsigned int line, ID3D12Device *device, unsigned int reg_idx, D3D12_SHADER_VISIBILITY shader_visibility, @@ -33817,6 +33838,1402 @@ static void test_hull_shader_patch_constant_inputs(void) destroy_test_context(&context); }
+static void test_unbounded_srv(void) +{
- D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
- D3D12_ROOT_PARAMETER root_parameters[3];
- D3D12_DESCRIPTOR_RANGE descriptor_ranges[4];
- ID3D12DescriptorHeap* heap;
- ID3D12Resource *input_buffers[128];
- ID3D12Resource *input_textures[128];
- ID3D12Resource *output_buffer;
- struct resource_readback rb;
- ID3D12GraphicsCommandList* command_list;
- D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
- D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
- unsigned int i, descriptor_size;
- struct test_context context;
- ID3D12CommandQueue* queue;
- HRESULT hr;
+#if 0
- // Space 1 and 2 have an offset of 0 descriptors, so pattern of descriptors is
- // [ buf, tex, buf, tex ]
- StructuredBuffer<uint> Buffers[] : register(t4, space1);
- Texture2D<uint> Textures[] : register(t4, space2);
- // Space 3 and 4 have an effective offset of 2 descriptor,
- // so pattern of descriptors is still
- // [ buf, tex, buf, tex ]
- StructuredBuffer<uint> AliasBuffers[64] : register(t4, space3);
- Texture2D<uint> AliasTextures[64] : register(t4, space4);
- StructuredBuffer<uint> StandaloneBuffer : register(t100, space3);
- Texture2D<uint> StandaloneTexture : register(t199, space3);
- RWByteAddressBuffer OBuffer : register(u0);
- [numthreads(64, 1, 1)]
- void main(uint idx : SV_DispatchThreadID)
- {
uint result = 0;
if (idx & 1)
result += Textures[NonUniformResourceIndex(idx)].Load(int3(0, 0, 0));
else
result += Buffers[NonUniformResourceIndex(idx)].Load(0);
if (idx & 1)
result += AliasTextures[NonUniformResourceIndex(idx)].Load(int3(0, 0, 0)) << 8;
else
result += AliasBuffers[NonUniformResourceIndex(idx)].Load(0) << 8;
I'm kind of curious what the point of the alternation is here; not that there's anything wrong with it, but it seems a bit orthogonal to the test.
At least I presume the two conditionals can be merged into one?
result *= StandaloneBuffer.Load(0);
result *= StandaloneTexture.Load(int3(0, 0, 0));
OBuffer.Store(4 * idx, result);
- }
+#endif
- static const DWORD cs_code[] =
- {
0x43425844, 0x2b452826, 0x244a6b65, 0xdf8a8f8b, 0xf8326669, 0x00000001, 0x000003c4, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000370, 0x00050051, 0x000000dc, 0x0100086a,
0x070000a2, 0x00307e46, 0x00000000, 0x00000004, 0xffffffff, 0x00000004, 0x00000001, 0x07001858,
0x00307e46, 0x00000001, 0x00000004, 0xffffffff, 0x00004444, 0x00000002, 0x070000a2, 0x00307e46,
0x00000002, 0x00000004, 0x00000043, 0x00000004, 0x00000003, 0x070000a2, 0x00307e46, 0x00000003,
0x00000064, 0x00000064, 0x00000004, 0x00000003, 0x07001858, 0x00307e46, 0x00000004, 0x000000c7,
0x000000c7, 0x00004444, 0x00000003, 0x07001858, 0x00307e46, 0x00000005, 0x00000004, 0x00000043,
0x00004444, 0x00000004, 0x0600009d, 0x0031ee46, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001,
0x06000001, 0x00100012, 0x00000000, 0x0002000a, 0x00004001, 0x00000001, 0x0304001f, 0x0010000a,
0x00000000, 0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x0e00002d, 0x00100012, 0x00000000,
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x86207e46, 0x00020001, 0x00000001,
0x00000004, 0x0010000a, 0x00000000, 0x04000036, 0x00100042, 0x00000000, 0x0002000a, 0x0e00002d,
0x00100042, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x86207c96,
0x00020001, 0x00000005, 0x00000004, 0x0010002a, 0x00000000, 0x07000029, 0x00100042, 0x00000000,
0x0010002a, 0x00000000, 0x00004001, 0x00000008, 0x0700001e, 0x00100012, 0x00000000, 0x0010002a,
0x00000000, 0x0010000a, 0x00000000, 0x01000012, 0x04000036, 0x00100022, 0x00000000, 0x0002000a,
0x0d0000a7, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x86207006,
0x00020001, 0x00000000, 0x00000004, 0x0010001a, 0x00000000, 0x04000036, 0x00100042, 0x00000000,
0x0002000a, 0x0d0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x86207006, 0x00020001, 0x00000002, 0x00000004, 0x0010002a, 0x00000000, 0x07000029, 0x00100042,
0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000008, 0x0700001e, 0x00100012, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x01000015, 0x0a0000a7, 0x00100022, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000003, 0x00000064, 0x08000026,
0x0000d000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0b00002d,
0x00100022, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00207e16,
0x00000004, 0x000000c7, 0x08000026, 0x0000d000, 0x00100012, 0x00000000, 0x0010001a, 0x00000000,
0x0010000a, 0x00000000, 0x06000029, 0x00100022, 0x00000000, 0x0002000a, 0x00004001, 0x00000002,
0x080000a6, 0x0021e012, 0x00000000, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000,
0x0100003e,
- };
- if (!init_compute_test_context(&context) || !context_supports_sm51(&context))
return;
- command_list = context.list;
- queue = context.queue;
- root_signature_desc.NumParameters = 3;
- root_signature_desc.Flags = 0;
- root_signature_desc.NumStaticSamplers = 0;
- root_signature_desc.pStaticSamplers = NULL;
- root_signature_desc.pParameters = root_parameters;
- root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
- root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0];
- root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[1].DescriptorTable.NumDescriptorRanges = 2;
- root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[2];
- root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
- root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[2].Descriptor.RegisterSpace = 0;
- root_parameters[2].Descriptor.ShaderRegister = 0;
- /* Need two idential ranges so we can alias two different resource dimensions over same table. */
- for (i = 0; i < 4; ++i)
- {
descriptor_ranges[i].RegisterSpace = i + 1;
descriptor_ranges[i].BaseShaderRegister = 4;
descriptor_ranges[i].OffsetInDescriptorsFromTableStart = i >= 2 ? 1 : 0;
descriptor_ranges[i].NumDescriptors = UINT_MAX;
descriptor_ranges[i].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- }
- hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
- ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
- for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
- {
const UINT buffer_data[] = { i * 2, i * 2, i * 2, i * 2 };
input_buffers[i] = create_default_buffer(context.device, sizeof(buffer_data), D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data), buffer_data, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- }
- for (i = 0; i < ARRAY_SIZE(input_textures); ++i)
- {
const UINT tex_data = i * 2 + 1;
D3D12_SUBRESOURCE_DATA sub;
sub.pData = &tex_data;
sub.RowPitch = 1;
sub.SlicePitch = 1;
input_textures[i] = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
upload_texture_data(input_textures[i], &sub, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_textures[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- }
- output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- context.pipeline_state = create_compute_pipeline_state(context.device,
context.root_signature,
shader_bytecode((const void*)cs_code, sizeof(cs_code)));
- heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 512 + 256);
- cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
- gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
- descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- for (i = 0; i < ARRAY_SIZE(input_buffers) * 2; ++i)
- {
D3D12_SHADER_RESOURCE_VIEW_DESC view;
D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle;
view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
h.ptr += (512 + i) * descriptor_size;
/* Every other resource is a buffer and texture SRV which are aliased over the same descriptor table range. */
if (i & 1)
{
view.Format = DXGI_FORMAT_R32_UINT;
view.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
view.Texture2D.MipLevels = 1;
view.Texture2D.MostDetailedMip = 0;
view.Texture2D.PlaneSlice = 0;
view.Texture2D.ResourceMinLODClamp = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_textures[i >> 1], &view, h);
}
else
{
view.Format = DXGI_FORMAT_UNKNOWN;
view.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
view.Buffer.FirstElement = 0;
view.Buffer.NumElements = 4;
view.Buffer.StructureByteStride = 4;
view.Buffer.Flags = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_buffers[i >> 1], &view, h);
}
- }
It seems to me this would be simpler as two consecutive loops.
- ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
- ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
- ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
- {
D3D12_GPU_DESCRIPTOR_HANDLE gpu = gpu_handle;
gpu.ptr += 512 * descriptor_size;
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu);
gpu.ptr += descriptor_size;
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1, gpu);
- }
We have a get_gpu_descriptor_handle() helper for this.
- ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 2, ID3D12Resource_GetGPUVirtualAddress(output_buffer));
- ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
- transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
- for (i = 0; i < 64; ++i)
- {
UINT value = get_readback_uint(&rb, i, 0, 0);
UINT reference = (i + (i + 2) * 256) * 98 * 197;
ok(value == reference, "Readback value is: %u\n", value);
Could you please print the index of the failing test here?
- }
- release_resource_readback(&rb);
- reset_command_list(command_list, context.allocator);
- for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
- {
ID3D12Resource_Release(input_buffers[i]);
ID3D12Resource_Release(input_textures[i]);
- }
- ID3D12Resource_Release(output_buffer);
- ID3D12DescriptorHeap_Release(heap);
- destroy_test_context(&context);
+}
+static void test_unbounded_samplers(void) +{
- D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
- D3D12_ROOT_PARAMETER root_parameters[3];
- D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
- ID3D12DescriptorHeap *heaps[2];
- ID3D12Resource* input_texture;
- ID3D12Resource* output_buffer;
- struct resource_readback rb;
- ID3D12GraphicsCommandList* command_list;
- D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
- unsigned int i, descriptor_size;
- struct test_context context;
- ID3D12CommandQueue* queue;
- HRESULT hr;
+#if 0
- Texture2D<float> Tex : register(t0);
- SamplerState Samp[] : register(s0);
- RWByteAddressBuffer OBuffer : register(u0);
- [numthreads(64, 1, 1)]
- void main(uint idx : SV_DispatchThreadID)
- {
// Should alternate between wrap (sample 0), or clamp (sample 100).
uint value = Tex.SampleLevel(Samp[NonUniformResourceIndex(idx)], 1.1.xx, 0.0);
"1.1.xx" made me scratch my head for a minute. Granted, that may be because I haven't done much GPU programming.
OBuffer.Store(4 * idx, value);
- }
+#endif
- static const DWORD cs_code[] =
- {
0x43425844, 0x44f291da, 0x1146ced9, 0x71030deb, 0x28d62ae2, 0x00000001, 0x00000174, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000120, 0x00050051, 0x00000048, 0x0100086a,
0x0600005a, 0x00306e46, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x07001858, 0x00307e46,
0x00000000, 0x00000000, 0x00000000, 0x00005555, 0x00000000, 0x0600009d, 0x0031ee46, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b,
0x00000040, 0x00000001, 0x00000001, 0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x12000048,
0x00100012, 0x00000000, 0x00004002, 0x3f8ccccd, 0x3f8ccccd, 0x00000000, 0x00000000, 0x00207e46,
0x00000000, 0x00000000, 0x84206000, 0x00020001, 0x00000000, 0x0010000a, 0x00000000, 0x00004001,
0x00000000, 0x0500001c, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x06000029, 0x00100022,
0x00000000, 0x0002000a, 0x00004001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000000, 0x00000000,
0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
- };
- if (!init_compute_test_context(&context) || !context_supports_sm51(&context))
return;
- command_list = context.list;
- queue = context.queue;
- root_signature_desc.NumParameters = 3;
- root_signature_desc.Flags = 0;
- root_signature_desc.NumStaticSamplers = 0;
- root_signature_desc.pStaticSamplers = NULL;
- root_signature_desc.pParameters = root_parameters;
- root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
- root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0];
- root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
- root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[1];
- root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
- root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[2].Descriptor.RegisterSpace = 0;
- root_parameters[2].Descriptor.ShaderRegister = 0;
- descriptor_ranges[0].RegisterSpace = 0;
- descriptor_ranges[0].BaseShaderRegister = 0;
- descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
- descriptor_ranges[0].NumDescriptors = 1;
- descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- descriptor_ranges[1].RegisterSpace = 0;
- descriptor_ranges[1].BaseShaderRegister = 0;
- descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 0;
- descriptor_ranges[1].NumDescriptors = UINT_MAX;
- descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
- hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
- ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
- {
const float tex_data[] = { 10, 100, 100, 100 };
D3D12_SUBRESOURCE_DATA sub;
sub.pData = tex_data;
sub.RowPitch = 8;
sub.SlicePitch = 8;
input_texture = create_default_texture2d(context.device, 2, 2, 1, 1, DXGI_FORMAT_R32_FLOAT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
create_default_texture() is a slightly shorter version of this.
upload_texture_data(input_texture, &sub, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- }
- output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- context.pipeline_state = create_compute_pipeline_state(context.device,
context.root_signature,
shader_bytecode((const void*)cs_code, sizeof(cs_code)));
- heaps[0] = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
- heaps[1] = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1024);
- {
D3D12_SHADER_RESOURCE_VIEW_DESC view;
view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
view.Format = DXGI_FORMAT_R32_FLOAT;
view.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
view.Texture2D.MipLevels = 1;
view.Texture2D.MostDetailedMip = 0;
view.Texture2D.PlaneSlice = 0;
view.Texture2D.ResourceMinLODClamp = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_texture, &view,
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heaps[0]));
- }
- for (i = 0; i < 1024; ++i)
- {
D3D12_SAMPLER_DESC samp;
memset(&samp, 0, sizeof(samp));
samp.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
samp.AddressU = samp.AddressV = samp.AddressW = (i & 1) ? D3D12_TEXTURE_ADDRESS_MODE_CLAMP : D3D12_TEXTURE_ADDRESS_MODE_WRAP;
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heaps[1]);
descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
cpu_handle.ptr += descriptor_size * i;
ID3D12Device_CreateSampler(context.device, &samp, cpu_handle);
- }
- ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
- ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
- ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 2, heaps);
- ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heaps[0]));
- ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1, ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heaps[1]));
- ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 2, ID3D12Resource_GetGPUVirtualAddress(output_buffer));
- ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
- transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
- for (i = 0; i < 64; ++i)
- {
UINT value = get_readback_uint(&rb, i, 0, 0);
UINT reference = (i & 1) ? 100 : 10;
ok(value == reference, "Readback value for index %u is: %u\n", i, value);
- }
- release_resource_readback(&rb);
- reset_command_list(command_list, context.allocator);
- ID3D12Resource_Release(input_texture);
- ID3D12Resource_Release(output_buffer);
- ID3D12DescriptorHeap_Release(heaps[0]);
- ID3D12DescriptorHeap_Release(heaps[1]);
- destroy_test_context(&context);
+}
+#define BUFFER_COUNT (61 + 8)
This could just be replaced with ARRAY_SIZE(input_buffers) everywhere it's used. On the other hand, the "63" everywhere is not great either; it'd be nice to replace that with ARRAY_SIZE where possible. It also took me a bit of a minute to realize that this test was overlapping every buffer range, not necessarily a bad idea, but could use a comment I guess.
Also, what is the point of this "bindless" test?
+static void test_bindless_full_root_parameters(void) +{
- D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
- D3D12_ROOT_PARAMETER root_parameters[63];
- D3D12_DESCRIPTOR_RANGE descriptor_ranges[63];
- ID3D12DescriptorHeap* heap;
- ID3D12Resource* input_buffers[BUFFER_COUNT];
- ID3D12Resource* output_buffer;
- struct resource_readback rb;
- ID3D12GraphicsCommandList* command_list;
- D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
- D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
- unsigned int i, descriptor_size;
- struct test_context context;
- ID3D12CommandQueue* queue;
- HRESULT hr;
+#if 0
#define R(x) StructuredBuffer<uint> Buffers##x[] : register(t0, space##x)
R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9);
R(10); R(11); R(12); R(13); R(14); R(15); R(16); R(17); R(18); R(19);
R(20); R(21); R(22); R(23); R(24); R(25); R(26); R(27); R(28); R(29);
R(30); R(31); R(32); R(33); R(34); R(35); R(36); R(37); R(38); R(39);
R(40); R(41); R(42); R(43); R(44); R(45); R(46); R(47); R(48); R(49);
R(50); R(51); R(52); R(53); R(54); R(55); R(56); R(57); R(58); R(59);
R(60); R(61);
#undef R
RWByteAddressBuffer OBuffer : register(u0, space62);
[numthreads(8, 1, 1)]
void main(uint idx : SV_DispatchThreadID)
{
uint result = 0;
#define R(x) result += Buffers##x[NonUniformResourceIndex(idx)].Load(0)
R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9);
R(10); R(11); R(12); R(13); R(14); R(15); R(16); R(17); R(18); R(19);
R(20); R(21); R(22); R(23); R(24); R(25); R(26); R(27); R(28); R(29);
R(30); R(31); R(32); R(33); R(34); R(35); R(36); R(37); R(38); R(39);
R(40); R(41); R(42); R(43); R(44); R(45); R(46); R(47); R(48); R(49);
R(50); R(51); R(52); R(53); R(54); R(55); R(56); R(57); R(58); R(59);
R(60); R(61);
#undef R
OBuffer.Store(4 * idx, result);
}
+#endif
- static const DWORD cs_code[] =
- {
0x43425844, 0x14c36cde, 0x43afd9ea, 0x4f0f1a58, 0x160d65a7, 0x00000001, 0x000019f8, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000019a4, 0x00050051, 0x00000669, 0x0100086a,
0x070000a2, 0x00307e46, 0x00000000, 0x00000000, 0xffffffff, 0x00000004, 0x00000000, 0x070000a2,
0x00307e46, 0x00000001, 0x00000000, 0xffffffff, 0x00000004, 0x00000001, 0x070000a2, 0x00307e46,
0x00000002, 0x00000000, 0xffffffff, 0x00000004, 0x00000002, 0x070000a2, 0x00307e46, 0x00000003,
0x00000000, 0xffffffff, 0x00000004, 0x00000003, 0x070000a2, 0x00307e46, 0x00000004, 0x00000000,
0xffffffff, 0x00000004, 0x00000004, 0x070000a2, 0x00307e46, 0x00000005, 0x00000000, 0xffffffff,
0x00000004, 0x00000005, 0x070000a2, 0x00307e46, 0x00000006, 0x00000000, 0xffffffff, 0x00000004,
0x00000006, 0x070000a2, 0x00307e46, 0x00000007, 0x00000000, 0xffffffff, 0x00000004, 0x00000007,
0x070000a2, 0x00307e46, 0x00000008, 0x00000000, 0xffffffff, 0x00000004, 0x00000008, 0x070000a2,
0x00307e46, 0x00000009, 0x00000000, 0xffffffff, 0x00000004, 0x00000009, 0x070000a2, 0x00307e46,
0x0000000a, 0x00000000, 0xffffffff, 0x00000004, 0x0000000a, 0x070000a2, 0x00307e46, 0x0000000b,
0x00000000, 0xffffffff, 0x00000004, 0x0000000b, 0x070000a2, 0x00307e46, 0x0000000c, 0x00000000,
0xffffffff, 0x00000004, 0x0000000c, 0x070000a2, 0x00307e46, 0x0000000d, 0x00000000, 0xffffffff,
0x00000004, 0x0000000d, 0x070000a2, 0x00307e46, 0x0000000e, 0x00000000, 0xffffffff, 0x00000004,
0x0000000e, 0x070000a2, 0x00307e46, 0x0000000f, 0x00000000, 0xffffffff, 0x00000004, 0x0000000f,
0x070000a2, 0x00307e46, 0x00000010, 0x00000000, 0xffffffff, 0x00000004, 0x00000010, 0x070000a2,
0x00307e46, 0x00000011, 0x00000000, 0xffffffff, 0x00000004, 0x00000011, 0x070000a2, 0x00307e46,
0x00000012, 0x00000000, 0xffffffff, 0x00000004, 0x00000012, 0x070000a2, 0x00307e46, 0x00000013,
0x00000000, 0xffffffff, 0x00000004, 0x00000013, 0x070000a2, 0x00307e46, 0x00000014, 0x00000000,
0xffffffff, 0x00000004, 0x00000014, 0x070000a2, 0x00307e46, 0x00000015, 0x00000000, 0xffffffff,
0x00000004, 0x00000015, 0x070000a2, 0x00307e46, 0x00000016, 0x00000000, 0xffffffff, 0x00000004,
0x00000016, 0x070000a2, 0x00307e46, 0x00000017, 0x00000000, 0xffffffff, 0x00000004, 0x00000017,
0x070000a2, 0x00307e46, 0x00000018, 0x00000000, 0xffffffff, 0x00000004, 0x00000018, 0x070000a2,
0x00307e46, 0x00000019, 0x00000000, 0xffffffff, 0x00000004, 0x00000019, 0x070000a2, 0x00307e46,
0x0000001a, 0x00000000, 0xffffffff, 0x00000004, 0x0000001a, 0x070000a2, 0x00307e46, 0x0000001b,
0x00000000, 0xffffffff, 0x00000004, 0x0000001b, 0x070000a2, 0x00307e46, 0x0000001c, 0x00000000,
0xffffffff, 0x00000004, 0x0000001c, 0x070000a2, 0x00307e46, 0x0000001d, 0x00000000, 0xffffffff,
0x00000004, 0x0000001d, 0x070000a2, 0x00307e46, 0x0000001e, 0x00000000, 0xffffffff, 0x00000004,
0x0000001e, 0x070000a2, 0x00307e46, 0x0000001f, 0x00000000, 0xffffffff, 0x00000004, 0x0000001f,
0x070000a2, 0x00307e46, 0x00000020, 0x00000000, 0xffffffff, 0x00000004, 0x00000020, 0x070000a2,
0x00307e46, 0x00000021, 0x00000000, 0xffffffff, 0x00000004, 0x00000021, 0x070000a2, 0x00307e46,
0x00000022, 0x00000000, 0xffffffff, 0x00000004, 0x00000022, 0x070000a2, 0x00307e46, 0x00000023,
0x00000000, 0xffffffff, 0x00000004, 0x00000023, 0x070000a2, 0x00307e46, 0x00000024, 0x00000000,
0xffffffff, 0x00000004, 0x00000024, 0x070000a2, 0x00307e46, 0x00000025, 0x00000000, 0xffffffff,
0x00000004, 0x00000025, 0x070000a2, 0x00307e46, 0x00000026, 0x00000000, 0xffffffff, 0x00000004,
0x00000026, 0x070000a2, 0x00307e46, 0x00000027, 0x00000000, 0xffffffff, 0x00000004, 0x00000027,
0x070000a2, 0x00307e46, 0x00000028, 0x00000000, 0xffffffff, 0x00000004, 0x00000028, 0x070000a2,
0x00307e46, 0x00000029, 0x00000000, 0xffffffff, 0x00000004, 0x00000029, 0x070000a2, 0x00307e46,
0x0000002a, 0x00000000, 0xffffffff, 0x00000004, 0x0000002a, 0x070000a2, 0x00307e46, 0x0000002b,
0x00000000, 0xffffffff, 0x00000004, 0x0000002b, 0x070000a2, 0x00307e46, 0x0000002c, 0x00000000,
0xffffffff, 0x00000004, 0x0000002c, 0x070000a2, 0x00307e46, 0x0000002d, 0x00000000, 0xffffffff,
0x00000004, 0x0000002d, 0x070000a2, 0x00307e46, 0x0000002e, 0x00000000, 0xffffffff, 0x00000004,
0x0000002e, 0x070000a2, 0x00307e46, 0x0000002f, 0x00000000, 0xffffffff, 0x00000004, 0x0000002f,
0x070000a2, 0x00307e46, 0x00000030, 0x00000000, 0xffffffff, 0x00000004, 0x00000030, 0x070000a2,
0x00307e46, 0x00000031, 0x00000000, 0xffffffff, 0x00000004, 0x00000031, 0x070000a2, 0x00307e46,
0x00000032, 0x00000000, 0xffffffff, 0x00000004, 0x00000032, 0x070000a2, 0x00307e46, 0x00000033,
0x00000000, 0xffffffff, 0x00000004, 0x00000033, 0x070000a2, 0x00307e46, 0x00000034, 0x00000000,
0xffffffff, 0x00000004, 0x00000034, 0x070000a2, 0x00307e46, 0x00000035, 0x00000000, 0xffffffff,
0x00000004, 0x00000035, 0x070000a2, 0x00307e46, 0x00000036, 0x00000000, 0xffffffff, 0x00000004,
0x00000036, 0x070000a2, 0x00307e46, 0x00000037, 0x00000000, 0xffffffff, 0x00000004, 0x00000037,
0x070000a2, 0x00307e46, 0x00000038, 0x00000000, 0xffffffff, 0x00000004, 0x00000038, 0x070000a2,
0x00307e46, 0x00000039, 0x00000000, 0xffffffff, 0x00000004, 0x00000039, 0x070000a2, 0x00307e46,
0x0000003a, 0x00000000, 0xffffffff, 0x00000004, 0x0000003a, 0x070000a2, 0x00307e46, 0x0000003b,
0x00000000, 0xffffffff, 0x00000004, 0x0000003b, 0x070000a2, 0x00307e46, 0x0000003c, 0x00000000,
0xffffffff, 0x00000004, 0x0000003c, 0x070000a2, 0x00307e46, 0x0000003d, 0x00000000, 0xffffffff,
0x00000004, 0x0000003d, 0x0600009d, 0x0031ee46, 0x00000000, 0x00000000, 0x00000000, 0x0000003e,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000001, 0x00000001,
0x04000036, 0x00100012, 0x00000000, 0x0002000a, 0x0c0000a7, 0x00100022, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000000, 0x0010000a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000001, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000002, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000003,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x00000004, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000005, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x00000006, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x00000007, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000008, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000009, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000a, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000b,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x0000000c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000000d, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x0000000e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x0000000f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000010, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000011, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000012, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000013,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x00000014, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000015, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x00000016, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x00000017, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000018, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000019, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001a, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001b,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x0000001c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000001d, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x0000001e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x0000001f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000020, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000021, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000022, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000023,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x00000024, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000025, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x00000026, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x00000027, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000028, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000029, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002a, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002b,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x0000002c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000002d, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x0000002e, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x0000002f, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000030, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000031, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000032, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000033,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x00000034, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000035, 0x0010000a, 0x00000000,
0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7,
0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001,
0x00000036, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000,
0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001,
0x00000000, 0x84207006, 0x00020001, 0x00000037, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000,
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x00000038, 0x0010000a,
0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000,
0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006,
0x00020001, 0x00000039, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a,
0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003a, 0x0010000a, 0x00000000, 0x0700001e,
0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100042,
0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003b,
0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
0x00000000, 0x0c0000a7, 0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
0x84207006, 0x00020001, 0x0000003c, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0c0000a7, 0x00100012, 0x00000000, 0x00004001,
0x00000000, 0x00004001, 0x00000000, 0x84207006, 0x00020001, 0x0000003d, 0x0010000a, 0x00000000,
0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, 0x00000000, 0x06000029,
0x00100022, 0x00000000, 0x0002000a, 0x00004001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000000,
0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e
- };
- if (!init_compute_test_context(&context) || !context_supports_sm51(&context))
return;
- command_list = context.list;
- queue = context.queue;
- root_signature_desc.NumParameters = 63;
- root_signature_desc.Flags = 0;
- root_signature_desc.NumStaticSamplers = 0;
- root_signature_desc.pStaticSamplers = NULL;
- root_signature_desc.pParameters = root_parameters;
- for (i = 0; i < 62; ++i)
- {
root_parameters[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[i].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[i].DescriptorTable.NumDescriptorRanges = 1;
root_parameters[i].DescriptorTable.pDescriptorRanges = &descriptor_ranges[i];
descriptor_ranges[i].RegisterSpace = i;
descriptor_ranges[i].BaseShaderRegister = 0;
descriptor_ranges[i].OffsetInDescriptorsFromTableStart = 0;
descriptor_ranges[i].NumDescriptors = 8;
descriptor_ranges[i].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- }
- root_parameters[62].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
- root_parameters[62].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- root_parameters[62].Descriptor.RegisterSpace = 62;
- root_parameters[62].Descriptor.ShaderRegister = 0;
- hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
- ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
- for (i = 0; i < BUFFER_COUNT; ++i)
- {
const UINT buffer_data[] = { i, i, i, i };
input_buffers[i] = create_default_buffer(context.device, sizeof(buffer_data), D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
upload_buffer_data(input_buffers[i], 0, sizeof(buffer_data), buffer_data, queue, command_list);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, input_buffers[i], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- }
- output_buffer = create_default_buffer(context.device, 4 * 64, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- context.pipeline_state = create_compute_pipeline_state(context.device,
context.root_signature,
shader_bytecode(cs_code, sizeof(cs_code)));
- heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, BUFFER_COUNT);
- cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
- gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
- descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- for (i = 0; i < BUFFER_COUNT; ++i)
- {
D3D12_CPU_DESCRIPTOR_HANDLE h = cpu_handle;
D3D12_SHADER_RESOURCE_VIEW_DESC view;
h.ptr += i * descriptor_size;
We have get_cpu_descriptor_handle() for this.
view.Format = DXGI_FORMAT_UNKNOWN;
view.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
view.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
view.Buffer.FirstElement = 0;
view.Buffer.NumElements = 4;
view.Buffer.StructureByteStride = 4;
view.Buffer.Flags = 0;
ID3D12Device_CreateShaderResourceView(context.device, input_buffers[i], &view, h);
- }
- ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
- ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
- ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
- for (i = 0; i < 62; ++i)
- {
D3D12_GPU_DESCRIPTOR_HANDLE gpu = gpu_handle;
gpu.ptr += i * descriptor_size;
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, i, gpu);
- }
- ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 62, ID3D12Resource_GetGPUVirtualAddress(output_buffer));
- ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
- transition_resource_state(command_list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
- for (i = 0; i < 8; ++i)
- {
UINT value = get_readback_uint(&rb, i, 0, 0);
UINT reference = 62 * (i + (i + 61)) / 2;
ok(value == reference, "Readback value is: %u\n", value);
- }
- release_resource_readback(&rb);
- reset_command_list(command_list, context.allocator);
- for (i = 0; i < BUFFER_COUNT; ++i)
ID3D12Resource_Release(input_buffers[i]);
- ID3D12Resource_Release(output_buffer);
- ID3D12DescriptorHeap_Release(heap);
- destroy_test_context(&context);
+}
+#undef BUFFER_COUNT
+static void test_unbounded_cbv() +{
It may be easier to just test all (most?) types of unbounded resources (well, except samplers maybe) in one test—it may make it easier to just match array lengths, and it'd be less code to review.
Enables calculation of upper bounds for variable Vulkan bindings. The alternative is to use an arbitrary count value. The counting is complex, and can be simplified slightly if/when update-after-bind is used, as total counts will no longer be required.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/state.c | 188 +++++++++++++++++++++++++++++++++++-- libs/vkd3d/vkd3d_private.h | 2 +- 2 files changed, 181 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index e459c998..749d3763 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -314,6 +314,19 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB
struct d3d12_root_signature_info { + uint32_t cbv_stage_count[5]; + uint32_t uav_stage_count[5]; + uint32_t srv_stage_count[5]; + uint32_t sampler_stage_count[5]; + uint32_t total_stage_count[5]; + + uint32_t cbv_unbounded_set_count; + uint32_t uav_unbounded_set_count; + uint32_t srv_unbounded_set_count; + uint32_t sampler_unbounded_set_count; + uint32_t total_unbounded_set_count; + + size_t mapping_count; size_t binding_count;
size_t root_constant_count; @@ -362,11 +375,149 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig info->binding_count += range->NumDescriptors; }
+ /* Without descriptor indexing these are always equal. */ + info->mapping_count = info->binding_count; + + return S_OK; +} + +static void d3d12_count_shader_stages(D3D12_SHADER_VISIBILITY visibility, + uint32_t stage_count[5], unsigned int count) +{ + unsigned int i; + + switch (visibility) + { + case D3D12_SHADER_VISIBILITY_ALL: + for (i = 0; i < 5; ++i) + stage_count[i] += count; + break; + case D3D12_SHADER_VISIBILITY_VERTEX: + stage_count[0] += count; + break; + case D3D12_SHADER_VISIBILITY_HULL: + stage_count[1] += count; + break; + case D3D12_SHADER_VISIBILITY_DOMAIN: + stage_count[2] += count; + break; + case D3D12_SHADER_VISIBILITY_GEOMETRY: + stage_count[3] += count; + break; + case D3D12_SHADER_VISIBILITY_PIXEL: + stage_count[4] += count; + break; + default: + break; + } +} + +static HRESULT d3d12_root_signature_info_count_bindless_descriptors(struct d3d12_root_signature_info *info, + const D3D12_ROOT_DESCRIPTOR_TABLE *table, D3D12_SHADER_VISIBILITY visibility, + const struct d3d12_device *device) +{ + /* XXX: Vulkan buffer and image descriptors have different types. In order + * to preserve compatibility between Vulkan resource bindings for the same + * root signature, we create descriptor set layouts with two bindings for + * each SRV and UAV. Space must be allowed for UAV counters too. */ + static const uint32_t multiplier[] = { 2, 3, 1, 1}; + uint32_t *const stage_count[] = { + info->srv_stage_count, + info->uav_stage_count, + info->cbv_stage_count, + info->sampler_stage_count + }; + uint32_t *const unbounded_set_count[] = { + &info->srv_unbounded_set_count, + &info->uav_unbounded_set_count, + &info->cbv_unbounded_set_count, + &info->sampler_unbounded_set_count + }; + unsigned int min_offset[4], max_offset[4]; + unsigned int i, offset = 0; + + memset(min_offset, 0xFF, sizeof(min_offset)); + memset(max_offset, 0, sizeof(max_offset)); + + for (i = 0; i < table->NumDescriptorRanges; ++i) + { + const D3D12_DESCRIPTOR_RANGE *range = &table->pDescriptorRanges[i]; + unsigned int j; + + if (range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + offset = range->OffsetInDescriptorsFromTableStart; + + switch (range->RangeType) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + info->mapping_count += 2; + j = 0; + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + info->mapping_count += 2; + j = 1; + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + ++info->mapping_count; + j = 2; + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: + ++info->mapping_count; + j = 3; + break; + default: + FIXME("Unhandled descriptor type %#x.\n", range->RangeType); + return E_NOTIMPL; + } + + min_offset[j] = min(min_offset[j], offset); + if (range->NumDescriptors == ~0u) + { + if (offset == ~0u && range->OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + ERR("Unbounded range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after " + "another unbounded range.\n"); + return E_INVALIDARG; + } + max_offset[j] = ~0u; + offset = ~0u; + } + else + { + if (offset == ~0u) + { + ERR("Static range occurs after unbounded range.\n"); + return E_INVALIDARG; + } + offset += range->NumDescriptors; + max_offset[j] = max(max_offset[j], offset); + } + } + + for (i = 0; i < 4; ++i) + { + if (min_offset[i] != ~0u) + { + /* Count descriptors bound to each stage to enable calculation of upper bounds for + * variable Vulkan bindings. */ + if (max_offset[i] != ~0u) + d3d12_count_shader_stages(visibility, stage_count[i], (max_offset[i] - min_offset[i]) * multiplier[i]); + /* One Vulkan variable binding for each descriptor type, plus possible UAV counters. */ + if (max_offset[i] == ~0u) + { + *unbounded_set_count[i] += multiplier[i]; + info->total_unbounded_set_count += multiplier[i]; + } + /* UAV counter bindings are not counted here as they are created later in separate set layouts. */ + info->binding_count += (multiplier[i] > 1) ? 2 : 1; + } + } + return S_OK; }
static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_info *info, - const D3D12_ROOT_SIGNATURE_DESC *desc) + const D3D12_ROOT_SIGNATURE_DESC *desc, const struct d3d12_device *device) { unsigned int i; HRESULT hr; @@ -380,8 +531,12 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i switch (p->ParameterType) { case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - if (FAILED(hr = d3d12_root_signature_info_count_descriptors(info, - &p->u.DescriptorTable))) + if (device->vk_info.EXT_descriptor_indexing) + hr = d3d12_root_signature_info_count_bindless_descriptors(info, + &p->u.DescriptorTable, p->ShaderVisibility, device); + else + hr = d3d12_root_signature_info_count_descriptors(info, &p->u.DescriptorTable); + if (FAILED(hr)) return hr; ++info->cost; break; @@ -389,16 +544,22 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i case D3D12_ROOT_PARAMETER_TYPE_CBV: ++info->root_descriptor_count; ++info->binding_count; + ++info->mapping_count; + d3d12_count_shader_stages(p->ShaderVisibility, info->cbv_stage_count, 1); info->cost += 2; break; case D3D12_ROOT_PARAMETER_TYPE_SRV: ++info->root_descriptor_count; ++info->binding_count; + ++info->mapping_count; + d3d12_count_shader_stages(p->ShaderVisibility, info->srv_stage_count, 1); info->cost += 2; break; case D3D12_ROOT_PARAMETER_TYPE_UAV: ++info->root_descriptor_count; ++info->binding_count; + ++info->mapping_count; + d3d12_count_shader_stages(p->ShaderVisibility, info->uav_stage_count, 1); info->cost += 2; break;
@@ -414,6 +575,17 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i }
info->binding_count += desc->NumStaticSamplers; + info->mapping_count += desc->NumStaticSamplers; + for (i = 0; i < desc->NumStaticSamplers; ++i) + d3d12_count_shader_stages(desc->pStaticSamplers[i].ShaderVisibility, info->sampler_stage_count, 1); + + for (i = 0; i < ARRAY_SIZE(info->total_stage_count); ++i) + { + info->total_stage_count[i] += info->cbv_stage_count[i]; + info->total_stage_count[i] += info->uav_stage_count[i]; + info->total_stage_count[i] += info->srv_stage_count[i]; + info->total_stage_count[i] += info->sampler_stage_count[i]; + }
return S_OK; } @@ -794,7 +966,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT)) FIXME("Ignoring root signature flags %#x.\n", desc->Flags);
- if (FAILED(hr = d3d12_root_signature_info_from_desc(&info, desc))) + if (FAILED(hr = d3d12_root_signature_info_from_desc(&info, desc, device))) return hr; if (info.cost > D3D12_MAX_ROOT_COST) { @@ -802,7 +974,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa return E_INVALIDARG; }
- root_signature->binding_count = info.binding_count; + root_signature->mapping_count = info.mapping_count; root_signature->static_sampler_count = desc->NumStaticSamplers; root_signature->root_descriptor_count = info.root_descriptor_count;
@@ -811,7 +983,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa if (!(root_signature->parameters = vkd3d_calloc(root_signature->parameter_count, sizeof(*root_signature->parameters)))) goto fail; - if (!(root_signature->descriptor_mapping = vkd3d_calloc(root_signature->binding_count, + if (!(root_signature->descriptor_mapping = vkd3d_calloc(root_signature->mapping_count, sizeof(*root_signature->descriptor_mapping)))) goto fail; root_signature->root_constant_count = info.root_constant_count; @@ -1549,7 +1721,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; shader_interface.next = NULL; shader_interface.bindings = root_signature->descriptor_mapping; - shader_interface.binding_count = root_signature->binding_count; + shader_interface.binding_count = root_signature->mapping_count; shader_interface.push_constant_buffers = root_signature->root_constants; shader_interface.push_constant_buffer_count = root_signature->root_constant_count; shader_interface.combined_samplers = NULL; @@ -2258,7 +2430,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; shader_interface.next = NULL; shader_interface.bindings = root_signature->descriptor_mapping; - shader_interface.binding_count = root_signature->binding_count; + shader_interface.binding_count = root_signature->mapping_count; shader_interface.push_constant_buffers = root_signature->root_constants; shader_interface.push_constant_buffer_count = root_signature->root_constant_count; shader_interface.combined_samplers = NULL; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index b30e38e9..79cd3f4f 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -712,7 +712,7 @@ struct d3d12_root_signature
D3D12_ROOT_SIGNATURE_FLAGS flags;
- unsigned int binding_count; + unsigned int mapping_count; struct vkd3d_shader_resource_binding *descriptor_mapping;
unsigned int root_constant_count;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/state.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 749d3763..03684264 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -749,6 +749,62 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty } }
+static uint32_t vk_max_unbounded_range_descriptor_count(D3D12_SHADER_VISIBILITY visibility, + const uint32_t stage_count[5], uint32_t max_descriptors, uint32_t binding_count) +{ + static const unsigned int stages[5] = { + D3D12_SHADER_VISIBILITY_VERTEX, + D3D12_SHADER_VISIBILITY_HULL, + D3D12_SHADER_VISIBILITY_DOMAIN, + D3D12_SHADER_VISIBILITY_GEOMETRY, + D3D12_SHADER_VISIBILITY_PIXEL}; + uint32_t count = max_descriptors / binding_count; + unsigned int i; + + for (i = 0; i < 5; ++i) + if (visibility == D3D12_SHADER_VISIBILITY_ALL || visibility == stages[i]) + count = (max_descriptors > stage_count[i]) + ? min(count, (max_descriptors - stage_count[i]) / binding_count) + : 0; + if (!count) + ERR("Exceeded maximum bindless descriptor count for shader visibility %u.\n", visibility); + + return count; +} + +static unsigned int vk_descriptor_count_from_d3d12_desc_range_type(D3D12_DESCRIPTOR_RANGE_TYPE type, + D3D12_SHADER_VISIBILITY visibility, const struct d3d12_root_signature_info *info, + const struct d3d12_device *device) +{ + unsigned int all_max = vk_max_unbounded_range_descriptor_count(visibility, info->total_stage_count, + device->vk_info.device_limits.maxPerStageResources, info->total_unbounded_set_count); + unsigned int type_max; + + switch (type) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->srv_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorSampledImages, info->srv_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->uav_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorStorageImages, info->uav_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->cbv_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorUniformBuffers, info->cbv_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->sampler_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorSamplers, info->sampler_unbounded_set_count); + break; + default: + ERR("Invalid range type %#x.\n", type); + return 0; + } + return min(type_max, all_max); +} + 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) {
On 5/26/21 3:04 AM, Conor McCarthy wrote:
Descriptor indexing is not used and SM5.1 is mostly not supported. Allows new SM5.1 tests to be skipped.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
libs/vkd3d/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index a63fc92b..877512e3 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1423,6 +1423,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->EXT_shader_demote_to_helper_invocation = false; if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment) vulkan_info->EXT_texel_buffer_alignment = false;
vulkan_info->EXT_descriptor_indexing = false;
vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties;
I get the impression we usually don't disable reported capabilities just because we don't actually support them, indeed, we tend to err in the opposite direction, and lie that we can support more than we actually can—because applications trust us too much ;-)
Hence this strikes me as a good idea at least only if it doesn't break more applications than it fixes.
Regarding the tests—IIRC vkd3d-shader currently fails to compile the shader if it uses descriptor arrays; can't we just call create_compute_pipeline_state() in a todo block, and skip the rest of the tests if it fails?
@@ -2728,7 +2729,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
TRACE("Request shader model %#x.\n", data->HighestShaderModel);
data->HighestShaderModel = D3D_SHADER_MODEL_5_1;
data->HighestShaderModel = device->vk_info.EXT_descriptor_indexing
? D3D_SHADER_MODEL_5_1 : D3D_SHADER_MODEL_5_0; TRACE("Shader model %#x.\n", data->HighestShaderModel); return S_OK;
This, on the other hand, strikes me as a separate change, and something we want regardless.