The last major feature for compute shader support.
The tests are a bit ad-hoc, and ideally would be extended beyond d3d12. The nonuniform readback is what makes this difficult.
My plan is to refactor the shader runner so that it exposes an interface usable both from a file interpreter frontend and also directly from C code. That would allow, in this case, declaring the shaders and drawing as a shader_test file would, but then making use of C loops to test the readback. It would also make it generally easier to port loop-based tests in e.g. d3d12.c.
From: Zebediah Figura zfigura@codeweavers.com
--- tests/d3d12.c | 39 ---------- tests/d3d12_test_utils.h | 29 +++++++ tests/hlsl_d3d12.c | 161 +++++++++++++++++++++++++++++++++++++++ tests/utils.h | 10 +++ 4 files changed, 200 insertions(+), 39 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 1e995aa8..ea569bc3 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -26,11 +26,6 @@ static PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER pfn_D3D12CreateVersionedRootSignatureDeserializer; static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE pfn_D3D12SerializeVersionedRootSignature;
-struct uvec4 -{ - unsigned int x, y, z, w; -}; - struct ivec4 { int x, y, z, w; @@ -41,11 +36,6 @@ struct dvec2 double x, y; };
-static bool compare_uvec4(const struct uvec4* v1, const struct uvec4 *v2) -{ - return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; -} - static bool compare_uint8(uint8_t a, uint8_t b, unsigned int max_diff) { return abs(a - b) <= max_diff; @@ -725,35 +715,6 @@ static ID3D12CommandSignature *create_command_signature_(unsigned int line, return command_signature; }
-#define init_compute_test_context(context) init_compute_test_context_(__LINE__, context) -static bool init_compute_test_context_(unsigned int line, struct test_context *context) -{ - ID3D12Device *device; - HRESULT hr; - - memset(context, 0, sizeof(*context)); - - if (!(context->device = create_device())) - { - skip_(line)("Failed to create device.\n"); - return false; - } - device = context->device; - - context->queue = create_command_queue_(line, device, - D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL); - - hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, - &IID_ID3D12CommandAllocator, (void **)&context->allocator); - ok_(line)(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr); - - hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE, - context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); - ok_(line)(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); - - return true; -} - struct depth_stencil_resource { ID3D12Resource *texture; diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index eebf3206..b6a99d43 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -1034,6 +1034,35 @@ static inline bool init_test_context_(unsigned int line, struct test_context *co return true; }
+#define init_compute_test_context(context) init_compute_test_context_(__LINE__, context) +static inline bool init_compute_test_context_(unsigned int line, struct test_context *context) +{ + ID3D12Device *device; + HRESULT hr; + + memset(context, 0, sizeof(*context)); + + if (!(context->device = create_device())) + { + skip_(line)("Failed to create device.\n"); + return false; + } + device = context->device; + + context->queue = create_command_queue_(line, device, + D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL); + + hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, + &IID_ID3D12CommandAllocator, (void **)&context->allocator); + ok_(line)(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr); + + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE, + context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); + ok_(line)(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + + return true; +} + static inline void destroy_pipeline_state_objects(struct test_context *context) { size_t i; diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index da8e0eac..8de8d653 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -416,6 +416,166 @@ static void test_preprocess(void) ID3D10Blob_Release(errors); }
+#define compile_shader(a, b) compile_shader_(__LINE__, a, b, 0) +#define compile_shader_flags(a, b, c) compile_shader_(__LINE__, a, b, c) +static ID3D10Blob *compile_shader_(unsigned int line, const char *source, const char *target, UINT flags) +{ + ID3D10Blob *blob = NULL, *errors = NULL; + HRESULT hr; + + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", target, flags, 0, &blob, &errors); + ok_(line)(hr == S_OK, "Failed to compile shader, hr %#x.\n", hr); + if (errors) + { + if (vkd3d_test_state.debug_level) + trace_(line)("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors)); + ID3D10Blob_Release(errors); + } + return blob; +} + +static void test_thread_id(void) +{ + ID3D12GraphicsCommandList *command_list; + struct d3d12_resource_readback rb; + struct test_context context; + ID3D12Resource *textures[3]; + ID3D12DescriptorHeap *heap; + unsigned int i, x, y, z; + ID3D12Device *device; + ID3D10Blob *cs_code; + HRESULT hr; + + static const char cs_source[] = + "RWTexture3D<uint4> group_uav, thread_uav, dispatch_uav;\n" + "[numthreads(5, 3, 2)]\n" + "void main(uint3 group : sv_groupid, uint3 thread : sv_groupthreadid, uint3 dispatch : sv_dispatchthreadid)\n" + "{\n" + " group_uav[dispatch] = uint4(group, 1);\n" + " thread_uav[dispatch] = uint4(thread, 2);\n" + " dispatch_uav[dispatch] = uint4(dispatch, 3);\n" + "}"; + + static const D3D12_DESCRIPTOR_RANGE descriptor_range = {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 3, 0, 0, 0}; + + static const D3D12_ROOT_PARAMETER root_parameter = + { + .ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + .DescriptorTable = {1, &descriptor_range}, + }; + + static const D3D12_ROOT_SIGNATURE_DESC root_signature_desc = + { + .NumParameters = 1, + .pParameters = &root_parameter, + }; + + if (!init_compute_test_context(&context)) + return; + command_list = context.list; + device = context.device; + + hr = create_root_signature(device, &root_signature_desc, &context.root_signature); + ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr); + + heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 3); + + for (i = 0; i < 3; ++i) + { + textures[i] = create_default_texture3d(device, 16, 8, 8, 1, DXGI_FORMAT_R32G32B32A32_UINT, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + ID3D12Device_CreateUnorderedAccessView(device, textures[i], NULL, NULL, + get_cpu_descriptor_handle(&context, heap, i)); + } + + todo cs_code = compile_shader(cs_source, "cs_5_0"); + if (cs_code) + { + context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, + shader_bytecode(ID3D10Blob_GetBufferPointer(cs_code), ID3D10Blob_GetBufferSize(cs_code))); + + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, + 0, get_gpu_descriptor_handle(&context, heap, 0)); + ID3D12GraphicsCommandList_Dispatch(command_list, 2, 2, 2); + + transition_resource_state(command_list, textures[0], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[0], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) + { + for (y = 0; y < 8; ++y) + { + for (z = 0; z < 8; ++z) + { + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x / 5, y / 3, z / 2, 1}; + + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect)); + + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); + } + } + } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + transition_resource_state(command_list, textures[1], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[1], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) + { + for (y = 0; y < 8; ++y) + { + for (z = 0; z < 8; ++z) + { + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x % 5, y % 3, z % 2, 2}; + + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect)); + + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); + } + } + } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + + transition_resource_state(command_list, textures[2], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[2], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) + { + for (y = 0; y < 8; ++y) + { + for (z = 0; z < 8; ++z) + { + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x, y, z, 3}; + + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect)); + + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); + } + } + } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + } + + for (i = 0; i < 3; ++i) + ID3D12Resource_Release(textures[i]); + ID3D12DescriptorHeap_Release(heap); + destroy_test_context(&context); +} + START_TEST(hlsl_d3d12) { parse_args(argc, argv); @@ -423,4 +583,5 @@ START_TEST(hlsl_d3d12) init_adapter_info();
run_test(test_preprocess); + run_test(test_thread_id); } diff --git a/tests/utils.h b/tests/utils.h index 82f0fc35..4097b6d1 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -35,6 +35,11 @@ struct vec4 float x, y, z, w; };
+struct uvec4 +{ + unsigned int x, y, z, w; +}; + struct resource_readback { uint64_t width; @@ -97,6 +102,11 @@ static bool compare_float(float f, float g, unsigned int ulps) return true; }
+static inline bool compare_uvec4(const struct uvec4 *v1, const struct uvec4 *v2) +{ + return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; +} + static inline bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps) { return compare_float(v1->x, v2->x, ulps)
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl_sm4.c | 26 +++++-- tests/hlsl-numthreads.shader_test | 4 +- tests/hlsl_d3d12.c | 115 +++++++++++++++--------------- 3 files changed, 78 insertions(+), 67 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e06f4b15..dab32377 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -49,21 +49,25 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem const char *semantic; bool output; enum vkd3d_shader_type shader_type; - enum vkd3d_sm4_register_type type; enum vkd3d_sm4_swizzle_type swizzle_type; + enum vkd3d_sm4_register_type type; bool has_idx; } register_table[] = { - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_RT_PRIMID, VKD3D_SM4_SWIZZLE_NONE, false}, + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_THREAD_ID, false}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_THREAD_GROUP_ID, false}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_LOCAL_THREAD_ID, false}, + + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_SWIZZLE_NONE, VKD3D_SM4_RT_PRIMID, false},
/* Put sv_target in this table, instead of letting it fall through to * default varying allocation, so that the register index matches the * usage index. */ - {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_OUTPUT, VKD3D_SM4_SWIZZLE_VEC4, true}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4, false}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4, false}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_OUTPUT, VKD3D_SM4_SWIZZLE_VEC4, true}, + {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_OUTPUT, true}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_DEPTHOUT, false}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_DEPTHOUT, false}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_OUTPUT, true}, };
for (i = 0; i < ARRAY_SIZE(register_table); ++i) @@ -97,6 +101,10 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant } semantics[] = { + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"position", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_POSITION}, {"sv_position", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_POSITION}, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_PRIMITIVE_ID}, @@ -164,6 +172,8 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
ret = hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); assert(ret); + if (usage == ~0u) + continue; usage_idx = var->semantic.index;
if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx)) @@ -226,6 +236,8 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, continue;
hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); + if (usage == ~0u) + continue;
if (usage == D3D_NAME_TARGET && !ascii_strcasecmp(semantic, "color")) string_offset = put_string(&buffer, "SV_Target"); @@ -1205,6 +1217,8 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b instr.dsts[0].reg.dim = VKD3D_SM4_DIMENSION_SCALAR;
hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); + if (usage == ~0u) + usage = D3D_NAME_UNDEFINED;
if (var->is_input_semantic) { diff --git a/tests/hlsl-numthreads.shader_test b/tests/hlsl-numthreads.shader_test index 9e561ae4..404d7d76 100644 --- a/tests/hlsl-numthreads.shader_test +++ b/tests/hlsl-numthreads.shader_test @@ -171,7 +171,7 @@ size (2, 2) 1.0 1.0 1.0 1.0
-[compute shader todo] +[compute shader] /* Attributes are taken from the first function, and dropped from the second. */ RWTexture2D<float> u;
@@ -185,7 +185,7 @@ void main(uint2 id : sv_dispatchthreadid) }
[test] -todo dispatch 1 1 1 +dispatch 1 1 1 probe uav 0 (0, 0) r (2.0) probe uav 0 (0, 1) r (1.0) probe uav 0 (1, 0) r (2.0) diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 8de8d653..17788d9b 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -488,87 +488,84 @@ static void test_thread_id(void) get_cpu_descriptor_handle(&context, heap, i)); }
- todo cs_code = compile_shader(cs_source, "cs_5_0"); - if (cs_code) + cs_code = compile_shader(cs_source, "cs_5_0"); + context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, + shader_bytecode(ID3D10Blob_GetBufferPointer(cs_code), ID3D10Blob_GetBufferSize(cs_code))); + + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, + 0, get_gpu_descriptor_handle(&context, heap, 0)); + ID3D12GraphicsCommandList_Dispatch(command_list, 2, 2, 2); + + transition_resource_state(command_list, textures[0], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[0], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) { - context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, - shader_bytecode(ID3D10Blob_GetBufferPointer(cs_code), ID3D10Blob_GetBufferSize(cs_code))); - - ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); - ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); - ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, - 0, get_gpu_descriptor_handle(&context, heap, 0)); - ID3D12GraphicsCommandList_Dispatch(command_list, 2, 2, 2); - - transition_resource_state(command_list, textures[0], - D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[0], 0, &rb, context.queue, command_list); - for (x = 0; x < 16; ++x) + for (y = 0; y < 8; ++y) { - for (y = 0; y < 8; ++y) + for (z = 0; z < 8; ++z) { - for (z = 0; z < 8; ++z) - { - const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); - struct uvec4 expect = {x / 5, y / 3, z / 2, 1}; + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x / 5, y / 3, z / 2, 1};
- if (x >= 10 || y >= 6 || z >= 4) - memset(&expect, 0, sizeof(expect)); + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect));
- ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", - v->x, v->y, v->z, v->w, x, y, z); - } + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); } } - release_resource_readback(&rb); - reset_command_list(command_list, context.allocator); + } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator);
- transition_resource_state(command_list, textures[1], - D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[1], 0, &rb, context.queue, command_list); - for (x = 0; x < 16; ++x) + transition_resource_state(command_list, textures[1], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[1], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) + { + for (y = 0; y < 8; ++y) { - for (y = 0; y < 8; ++y) + for (z = 0; z < 8; ++z) { - for (z = 0; z < 8; ++z) - { - const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); - struct uvec4 expect = {x % 5, y % 3, z % 2, 2}; + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x % 5, y % 3, z % 2, 2};
- if (x >= 10 || y >= 6 || z >= 4) - memset(&expect, 0, sizeof(expect)); + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect));
- ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", - v->x, v->y, v->z, v->w, x, y, z); - } + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); } } - release_resource_readback(&rb); - reset_command_list(command_list, context.allocator); + } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator);
- transition_resource_state(command_list, textures[2], - D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[2], 0, &rb, context.queue, command_list); - for (x = 0; x < 16; ++x) + transition_resource_state(command_list, textures[2], + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + get_texture_readback_with_command_list(textures[2], 0, &rb, context.queue, command_list); + for (x = 0; x < 16; ++x) + { + for (y = 0; y < 8; ++y) { - for (y = 0; y < 8; ++y) + for (z = 0; z < 8; ++z) { - for (z = 0; z < 8; ++z) - { - const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); - struct uvec4 expect = {x, y, z, 3}; + const struct uvec4 *v = get_readback_data(&rb.rb, x, y, z, sizeof(struct uvec4)); + struct uvec4 expect = {x, y, z, 3};
- if (x >= 10 || y >= 6 || z >= 4) - memset(&expect, 0, sizeof(expect)); + if (x >= 10 || y >= 6 || z >= 4) + memset(&expect, 0, sizeof(expect));
- ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", - v->x, v->y, v->z, v->w, x, y, z); - } + ok(compare_uvec4(v, &expect), "Got {%u, %u, %u, %u} at (%u, %u, %u).\n", + v->x, v->y, v->z, v->w, x, y, z); } } - release_resource_readback(&rb); - reset_command_list(command_list, context.allocator); } + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator);
for (i = 0; i < 3; ++i) ID3D12Resource_Release(textures[i]);
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Henri Verbeet.