From: Conor McCarthy Subject: [PATCH vkd3d 2/4] tests: Add resource array tests for SM5.1. Message-Id: <20210526080437.19137-2-cmccarthy@codeweavers.com> Date: Wed, 26 May 2021 18:04:35 +1000 In-Reply-To: <20210526080437.19137-1-cmccarthy@codeweavers.com> References: <20210526080437.19137-1-cmccarthy@codeweavers.com> From: Hans-Kristian Arntzen Modified to keep within current vkd3d descriptor set pool limits. Signed-off-by: Conor McCarthy --- 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 Buffers[] : register(t4, space1); + Texture2D 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 AliasBuffers[64] : register(t4, space3); + Texture2D AliasTextures[64] : register(t4, space4); + + StructuredBuffer StandaloneBuffer : register(t100, space3); + Texture2D 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 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 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 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 Buffers[] : register(u2, space1); + RWTexture2D 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 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 RWBuf[] : register(u0, space0); + RWTexture2D 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); } -- 2.31.1