-- v13: tests: Mark ReadFromSubresource() and WriteToSubresource() as todo on MoltenVK. tests: Mark a test related to instanced draws as buggy on MoltenVK.
From: Giovanni Mascellani gmascellani@codeweavers.com
d3d12 lumps many tests together, so it's useful to have the summary line in the CI log. --- gitlab/build-linux | 2 ++ gitlab/build-mac | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/gitlab/build-linux b/gitlab/build-linux index d7e7573f1..4871d3d70 100755 --- a/gitlab/build-linux +++ b/gitlab/build-linux @@ -20,6 +20,8 @@ else touch ../build_failed fi
+cat tests/d3d12.log | egrep 'd3d12: [0-9]+ tests executed' || true + mkdir -p ../artifacts/$COMMIT rsync -Rr config.log doc/* test-suite.log tests/*.log tests/*/*.log ../artifacts/$COMMIT || true
diff --git a/gitlab/build-mac b/gitlab/build-mac index 17a8c7a0d..0813ddea8 100755 --- a/gitlab/build-mac +++ b/gitlab/build-mac @@ -19,6 +19,8 @@ else touch ../build_failed fi
+cat tests/d3d12.log | egrep 'd3d12: [0-9]+ tests executed' || true + mkdir -p ../artifacts/$COMMIT rsync -Rr config.log test-suite.log tests/*.log tests/*/*.log ../artifacts/$COMMIT || true
From: Giovanni Mascellani gmascellani@codeweavers.com
This fixes a crash on MoltenVK. --- libs/vkd3d/resource.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 609c67102..356c2f099 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -3444,6 +3444,7 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, vkd3d_desc.miplevel_count = 1; vkd3d_desc.layer_idx = 0; vkd3d_desc.layer_count = 1; + vkd3d_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT; vkd3d_desc.components.r = VK_COMPONENT_SWIZZLE_R; vkd3d_desc.components.g = VK_COMPONENT_SWIZZLE_G; vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_B;
From: Giovanni Mascellani gmascellani@codeweavers.com
This fixes a failure in MoltenVK. --- tests/d3d12.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 1126d9749..3324eef80 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -35376,7 +35376,7 @@ static void test_bufinfo_instruction(void)
memset(&desc, 0, sizeof(desc)); desc.rt_width = desc.rt_height = 64; - desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.rt_format = DXGI_FORMAT_R32G32B32A32_UINT; desc.no_root_signature = true; desc.no_pipeline = true; if (!init_test_context(&context, &desc))
From: Giovanni Mascellani gmascellani@codeweavers.com
Bit field instructions in SPIR-V do not specify what happens when offset + count exceeds the type bit width. After this commit we refine the emitted code's behavior to match TPF.
This fixes a few failures on MoltenVK. --- libs/vkd3d-shader/spirv.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 45f46a91c..0e961293c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1764,6 +1764,15 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder GLSLstd450NMax, operands, ARRAY_SIZE(operands)); }
+static uint32_t vkd3d_spirv_build_op_glsl_std450_umin(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t x, uint32_t y) +{ + uint32_t glsl_std450_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); + uint32_t operands[] = {x, y}; + return vkd3d_spirv_build_op_ext_inst(builder, result_type, glsl_std450_id, + GLSLstd450UMin, operands, ARRAY_SIZE(operands)); +} + static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t min, uint32_t max) { @@ -7321,7 +7330,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - uint32_t src_ids[4], constituents[VKD3D_VEC4_SIZE], type_id, mask_id; + uint32_t src_ids[4], constituents[VKD3D_VEC4_SIZE], type_id, mask_id, size_id, max_count_id; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; @@ -7336,6 +7345,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); + size_id = spirv_compiler_get_constant_uint(compiler, 0x20);
switch (instruction->handler_idx) { @@ -7364,6 +7374,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp { src_ids[j] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[j], mask_id); } + max_count_id = vkd3d_spirv_build_op_isub(builder, type_id, size_id, src_ids[src_count - 2]); + src_ids[src_count - 1] = vkd3d_spirv_build_op_glsl_std450_umin(builder, type_id, + src_ids[src_count - 1], max_count_id);
constituents[k++] = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, src_ids, src_count);
From: Giovanni Mascellani gmascellani@codeweavers.com
Apparently Metal doesn't support specifying a bias directly in the sampler, and, with "nearest" mip filtering, it doesn't switch precisely at LOD 0.5 (though still between 0.5 and 0.6). --- tests/d3d12.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 3324eef80..fb0d4f7a5 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -13685,7 +13685,7 @@ static void test_sample_instructions(void) unsigned int x_step, y_step; ID3D12CommandQueue *queue; ID3D12Resource *texture; - unsigned int i, x, y; + unsigned int i, x = 0, y; ID3D12Device *device; HRESULT hr;
@@ -13908,6 +13908,7 @@ static void test_sample_instructions(void) float max_lod; float ps_constants[4]; const unsigned int *expected_data; + bool bug_on_mvk; } tests[] = { @@ -13919,7 +13920,7 @@ static void test_sample_instructions(void) {&ps_sample_b, &r8g8b8a8_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.0f}, r8g8b8a8_data}, {&ps_sample_b, &a8_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.0f}, a8_expected_data}, {&ps_sample_b, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.0f}, rgba_level_0}, - {&ps_sample_b, &rgba_texture, POINT, 8.0f, 0.0f, MIP_MAX, {0.0f}, level_1_colors}, + {&ps_sample_b, &rgba_texture, POINT, 8.0f, 0.0f, MIP_MAX, {0.0f}, level_1_colors, true}, {&ps_sample_b, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {8.0f}, level_1_colors}, {&ps_sample_b, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {8.4f}, level_1_colors}, {&ps_sample_b, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {8.5f}, level_2_colors}, @@ -13937,19 +13938,21 @@ static void test_sample_instructions(void) {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {-1.0f}, rgba_level_0}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.0f}, rgba_level_0}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.4f}, rgba_level_0}, - {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.5f}, level_1_colors}, + {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.5f}, level_1_colors, true}, + {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {0.6f}, level_1_colors}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {1.0f}, level_1_colors}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {1.4f}, level_1_colors}, - {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {1.5f}, level_2_colors}, + {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {1.5f}, level_2_colors, true}, + {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {1.6f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {2.0f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {3.0f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT, 0.0f, 0.0f, MIP_MAX, {4.0f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT_LINEAR, 0.0f, 0.0f, MIP_MAX, {1.5f}, lerp_1_2_colors}, {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {-2.0f}, rgba_level_0}, - {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {-1.0f}, level_1_colors}, - {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {0.0f}, level_2_colors}, - {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.0f}, level_2_colors}, - {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.5f}, level_2_colors}, + {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {-1.0f}, level_1_colors, true}, + {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {0.0f}, level_2_colors, true}, + {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.0f}, level_2_colors, true}, + {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.5f}, level_2_colors, true}, {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f, {-9.0f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f, {-1.0f}, level_2_colors}, {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f, {0.0f}, level_2_colors}, @@ -14015,6 +14018,9 @@ static void test_sample_instructions(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i) { + unsigned int color = 0; + bool fail = false; + vkd3d_test_push_context("Test %u", i);
memset(&sampler_desc, 0, sizeof(sampler_desc)); @@ -14070,12 +14076,20 @@ static void test_sample_instructions(void) { for (x = 0; x < tests[i].texture->width; ++x) { - unsigned int color = get_readback_uint(&rb.rb, x * x_step + x_step / 2, y * y_step + y_step / 2, 0); - ok(compare_color(color, tests[i].expected_data[tests[i].texture->width * y + x], 1), - "Got color 0x%08x, expected 0x%08x at (%u, %u).\n", - color, tests[i].expected_data[tests[i].texture->width * y + x], x, y); + color = get_readback_uint(&rb.rb, x * x_step + x_step / 2, y * y_step + y_step / 2, 0); + if (!compare_color(color, tests[i].expected_data[tests[i].texture->width * y + x], 1)) + { + fail = true; + break; + } } + + if (fail) + break; } + bug_if(tests[i].bug_on_mvk && is_mvk_device(device)) + ok(!fail, "Got color 0x%08x, expected 0x%08x at (%u, %u).\n", + color, tests[i].expected_data[tests[i].texture->width * y + x], x, y); release_resource_readback(&rb);
ID3D12Resource_Release(texture);
From: Giovanni Mascellani gmascellani@codeweavers.com
It requires Vulkan transform feedback extension. --- tests/d3d12.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index fb0d4f7a5..5967523d6 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -30297,7 +30297,9 @@ static void test_domain_shader_inputs(void) struct test_context context; ID3D12Resource *so_buffer; ID3D12CommandQueue *queue; + const float *elems = NULL; unsigned int x, y; + bool fail = false; HRESULT hr;
#if 0 @@ -30457,6 +30459,7 @@ static void test_domain_shader_inputs(void) pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM; hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + bug_if(is_mvk_device(context.device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
so_buffer = create_default_buffer(context.device, 1024, @@ -30478,13 +30481,21 @@ static void test_domain_shader_inputs(void) get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); for (y = 0; y < ARRAY_SIZE(reference); ++y) { - const float *elems = get_readback_data(&rb.rb, y, 0, 0, stride); + elems = get_readback_data(&rb.rb, y, 0, 0, stride); for (x = 0; x < ARRAY_SIZE(*reference); ++x) { - ok(compare_float(reference[y][x], elems[x], 0), - "Got unexpected value %.8e for [%u][%u], expected %.8e.\n", elems[x], y, x, reference[y][x]); + if (!compare_float(reference[y][x], elems[x], 0)) + { + fail = true; + break; + } } + + if (fail) + break; } + bug_if(is_mvk_device(context.device)) + ok(!fail, "Got unexpected value %.8e for [%u][%u], expected %.8e.\n", elems[x], y, x, reference[y][x]); release_resource_readback(&rb);
ID3D12Resource_Release(so_buffer); @@ -30502,7 +30513,9 @@ static void test_domain_shader_one_patch_constant_input(void) struct test_context context; ID3D12Resource *so_buffer; ID3D12CommandQueue *queue; + const float *elems = NULL; unsigned int x, y; + bool fail = false; HRESULT hr;
#if 0 @@ -30631,6 +30644,7 @@ static void test_domain_shader_one_patch_constant_input(void) pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM; hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + bug_if(is_mvk_device(context.device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
so_buffer = create_default_buffer(context.device, 1024, @@ -30652,13 +30666,21 @@ static void test_domain_shader_one_patch_constant_input(void) get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); for (y = 0; y < ARRAY_SIZE(reference); ++y) { - const float *elems = get_readback_data(&rb.rb, y, 0, 0, stride); + elems = get_readback_data(&rb.rb, y, 0, 0, stride); for (x = 0; x < ARRAY_SIZE(*reference); ++x) { - ok(compare_float(reference[y][x], elems[x], 0), - "Got unexpected value %.8e for [%u][%u], expected %.8e.\n", elems[x], y, x, reference[y][x]); + if (!compare_float(reference[y][x], elems[x], 0)) + { + fail = true; + break; + } } + + if (fail) + break; } + bug_if(is_mvk_device(context.device)) + ok(!fail, "Got unexpected value %.8e for [%u][%u], expected %.8e.\n", elems[x], y, x, reference[y][x]); release_resource_readback(&rb);
ID3D12Resource_Release(so_buffer); @@ -36156,6 +36178,7 @@ static void test_hull_shader_relative_addressing(void) pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM; hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + bug_if(is_mvk_device(context.device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
vb = create_upload_buffer(context.device, sizeof(vertices), vertices); @@ -36182,7 +36205,8 @@ static void test_hull_shader_relative_addressing(void) transition_resource_state(command_list, so_buffer, D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE); get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); - bug_if(is_radv_device(context.device)) check_triangles(&rb.rb, &expected_triangle, 1); + bug_if(is_radv_device(context.device) || is_mvk_device(context.device)) + check_triangles(&rb.rb, &expected_triangle, 1); release_resource_readback(&rb);
ID3D12Resource_Release(so_buffer); @@ -36389,6 +36413,7 @@ static void test_hull_shader_patch_constant_inputs(void) pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM; hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + bug_if(is_mvk_device(context.device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
vb = create_upload_buffer(context.device, sizeof(vertices), vertices); @@ -36414,6 +36439,7 @@ static void test_hull_shader_patch_constant_inputs(void) transition_resource_state(command_list, so_buffer, D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE); get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + bug_if(is_mvk_device(context.device)) check_triangles(&rb.rb, &expected_triangle, 1); release_resource_readback(&rb);
From: Giovanni Mascellani gmascellani@codeweavers.com
It requires Vulkan conditional rendering extension. --- tests/d3d12.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 5967523d6..42bf82086 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -34811,6 +34811,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
reset_command_list(command_list, context.allocator); @@ -34829,6 +34830,7 @@ static void test_conditional_rendering(void)
ID3D12GraphicsCommandList_SetPredication(command_list, conditions, sizeof(uint64_t), D3D12_PREDICATION_OP_EQUAL_ZERO); + bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
reset_command_list(command_list, context.allocator); @@ -34951,6 +34953,7 @@ static void test_conditional_rendering(void) 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO); transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
reset_command_list(command_list, context.allocator); @@ -34972,6 +34975,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
reset_command_list(command_list, context.allocator); @@ -35146,7 +35150,8 @@ static void test_conditional_rendering(void)
get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list); value = get_readback_uint(&rb.rb, 0, 0, 0); - ok(value == (!i ? init_value : input.value), "Got %#x, expected %#x.\n", value, input.value); + bug_if(is_mvk_device(context.device)) + ok(value == (!i ? init_value : input.value), "Got %#x, expected %#x.\n", value, !i ? init_value : input.value); release_resource_readback(&rb); reset_command_list(command_list, context.allocator);
From: Giovanni Mascellani gmascellani@codeweavers.com
They require Vulkan descriptor indexing extension, which is exposed by MoltenVK but known to be buggy, so we assume it is disabled. --- tests/d3d12.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 42bf82086..53db68f50 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -36612,6 +36612,7 @@ static void test_resource_arrays(void) get_cpu_descriptor_handle(&context, heap, ARRAY_SIZE(input_buffers) + i)); }
+ bug_if(is_mvk_device(device)) context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, shader_bytecode(cs_code, sizeof(cs_code))); if (!context.pipeline_state)
From: Giovanni Mascellani gmascellani@codeweavers.com
Specifically, MoltenVK seems to be able to load from stencil, but the specific replicating swizzle (repeating the stencil value on all the channels) is not honored. The stencil value is read only on the red channel. --- tests/d3d12.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 53db68f50..51e19e630 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -21324,11 +21324,13 @@ static void test_stencil_load(void)
transition_sub_resource_state(command_list, context.render_target, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + bug_if(is_mvk_device(context.device)) check_sub_resource_uvec4(context.render_target, 0, queue, command_list, &uvec4);
reset_command_list(command_list, context.allocator); transition_sub_resource_state(command_list, texture, 0, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); + bug_if(is_mvk_device(context.device)) check_sub_resource_uvec4(texture, 0, queue, command_list, &uvec4);
reset_command_list(command_list, context.allocator);
From: Giovanni Mascellani gmascellani@codeweavers.com
They require Vulkan descriptor indexing extension, which is exposed by MoltenVK but known to be buggy, so we assume it is disabled. --- tests/d3d12.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 51e19e630..dd5713273 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -2899,6 +2899,7 @@ static void test_create_root_signature(void) descriptor_ranges[1].RegisterSpace = 0; descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 16; hr = create_root_signature(device, &root_signature_desc, &root_signature); + bug_if(is_mvk_device(device)) ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
/* A bounded range overlapping an unbounded one, mapped to the same @@ -2918,6 +2919,7 @@ static void test_create_root_signature(void) descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; descriptor_ranges[1].NumDescriptors = UINT_MAX; hr = create_root_signature(device, &root_signature_desc, &root_signature); + bug_if(is_mvk_device(device)) ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
/* And unbounded range overlapping a bounded one, mapped to the same @@ -2926,6 +2928,7 @@ static void test_create_root_signature(void) descriptor_ranges[1].BaseShaderRegister = 0; descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 15; hr = create_root_signature(device, &root_signature_desc, &root_signature); + bug_if(is_mvk_device(device)) ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
refcount = ID3D12Device_Release(device); @@ -36750,6 +36753,7 @@ static void test_unbounded_resource_arrays(void) root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters); root_signature_desc.pParameters = root_parameters; hr = create_root_signature(device, &root_signature_desc, &context.root_signature); + bug_if(is_mvk_device(device)) ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr); if (FAILED(hr)) goto done; @@ -36913,6 +36917,7 @@ static void test_unbounded_samplers(void) root_signature_desc.pParameters = root_parameters;
hr = create_root_signature(device, &root_signature_desc, &context.root_signature); + bug_if(is_mvk_device(device)) ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); if (FAILED(hr)) goto done;
From: Giovanni Mascellani gmascellani@codeweavers.com
The generated MSL code is not accepted by the Metal runtime, and it looks wrong anyway. --- tests/d3d12.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index dd5713273..9b55a12f5 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -31861,6 +31861,13 @@ static void test_combined_clip_and_cull_distances(void) command_list = context.list; queue = context.queue;
+ if (is_mvk_device(device)) + { + skip("Cull distance not supported on MoltenVK.\n"); + destroy_test_context(&context); + return; + } + input_layout.pInputElementDescs = layout_desc; input_layout.NumElements = ARRAY_SIZE(layout_desc);
From: Giovanni Mascellani gmascellani@codeweavers.com
At least for tessellation and geometry shaders. --- tests/d3d12.c | 159 ++++++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 76 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 9b55a12f5..74c46f124 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -31514,92 +31514,99 @@ static void test_clip_distance(void)
ID3D12PipelineState_Release(pso);
- /* tessellation shaders */ - pso_desc.HS = hs; - pso_desc.DS = ds; - pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; - hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, - &IID_ID3D12PipelineState, (void **)&pso); - ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr); + if (is_mvk_device(device)) + { + skip("Clipping not supported in tessellation and geometry shaders on MoltenVK.\n"); + } + else + { + /* tessellation shaders */ + pso_desc.HS = hs; + pso_desc.DS = ds; + pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; + hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, + &IID_ID3D12PipelineState, (void **)&pso); + ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr);
- check_clip_distance(&context, pso, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, - vbv, vb[1], vs_cb, tess_cb, gs_cb); + check_clip_distance(&context, pso, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + vbv, vb[1], vs_cb, tess_cb, gs_cb);
- cb_data.use_constant = false; - cb_data.tessellation_factor = 2.0f; - update_buffer_data(tess_cb, 0, sizeof(cb_data), &cb_data); + cb_data.use_constant = false; + cb_data.tessellation_factor = 2.0f; + update_buffer_data(tess_cb, 0, sizeof(cb_data), &cb_data);
- for (i = 0; i < ARRAY_SIZE(vertices); ++i) - vertices[i].clip_distance0 = 1.0f; - update_buffer_data(vb[1], 0, sizeof(vertices), &vertices); + for (i = 0; i < ARRAY_SIZE(vertices); ++i) + vertices[i].clip_distance0 = 1.0f; + update_buffer_data(vb[1], 0, sizeof(vertices), &vertices);
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0, - ID3D12Resource_GetGPUVirtualAddress(vs_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1, - ID3D12Resource_GetGPUVirtualAddress(tess_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2, - ID3D12Resource_GetGPUVirtualAddress(tess_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 3, - ID3D12Resource_GetGPUVirtualAddress(gs_cb)); - ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); - ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); - ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); - ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); - transition_resource_state(command_list, context.render_target, - D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0, + ID3D12Resource_GetGPUVirtualAddress(vs_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1, + ID3D12Resource_GetGPUVirtualAddress(tess_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2, + ID3D12Resource_GetGPUVirtualAddress(tess_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 3, + ID3D12Resource_GetGPUVirtualAddress(gs_cb)); + ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
- ID3D12PipelineState_Release(pso); - reset_command_list(command_list, context.allocator); - transition_resource_state(command_list, context.render_target, - D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + ID3D12PipelineState_Release(pso); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
- cb_data.use_constant = true; - cb_data.clip_distance0 = -1.0f; - update_buffer_data(tess_cb, 0, sizeof(cb_data), &cb_data); + cb_data.use_constant = true; + cb_data.clip_distance0 = -1.0f; + update_buffer_data(tess_cb, 0, sizeof(cb_data), &cb_data);
- /* geometry shader */ - pso_desc.GS = gs; - hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, - &IID_ID3D12PipelineState, (void **)&pso); - ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr); + /* geometry shader */ + pso_desc.GS = gs; + hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, + &IID_ID3D12PipelineState, (void **)&pso); + ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr);
- check_clip_distance(&context, pso, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, - vbv, vb[1], vs_cb, tess_cb, gs_cb); + check_clip_distance(&context, pso, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + vbv, vb[1], vs_cb, tess_cb, gs_cb);
- cb_data.use_constant = true; - cb_data.clip_distance0 = 1.0f; - update_buffer_data(gs_cb, 0, sizeof(cb_data), &cb_data); - ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0, - ID3D12Resource_GetGPUVirtualAddress(vs_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1, - ID3D12Resource_GetGPUVirtualAddress(tess_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2, - ID3D12Resource_GetGPUVirtualAddress(tess_cb)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 3, - ID3D12Resource_GetGPUVirtualAddress(gs_cb)); - ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); - ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); - ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); - ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); - transition_resource_state(command_list, context.render_target, - D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0); + cb_data.use_constant = true; + cb_data.clip_distance0 = 1.0f; + update_buffer_data(gs_cb, 0, sizeof(cb_data), &cb_data); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0, + ID3D12Resource_GetGPUVirtualAddress(vs_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1, + ID3D12Resource_GetGPUVirtualAddress(tess_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2, + ID3D12Resource_GetGPUVirtualAddress(tess_cb)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 3, + ID3D12Resource_GetGPUVirtualAddress(gs_cb)); + ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
- ID3D12PipelineState_Release(pso); - reset_command_list(command_list, context.allocator); - transition_resource_state(command_list, context.render_target, - D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + ID3D12PipelineState_Release(pso); + reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + }
/* multiple clip distances */ pso_desc.VS = vs_multiple;
From: Giovanni Mascellani gmascellani@codeweavers.com
The generated Vulkan calls look right and do not trigger any validation error, but the returned timestamp is 0. A valid timestamp is returned if the CopyResource() call is commented, or the second EndQuery() call is moved before CopyResource(), or the first EndQuery() call is commented. I am not seeing any sensible pattern here, so I guess there is just a bug in MoltenVK. --- tests/d3d12.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 74c46f124..2cde9b1b5 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -24781,6 +24781,7 @@ static void test_resolve_non_issued_query_data(void) "Got unexpected timestamp %#"PRIx64".\n", timestamps[0]); ok(!timestamps[1], "Got unexpected timestamp %#"PRIx64".\n", timestamps[1]); ok(!timestamps[2], "Got unexpected timestamp %#"PRIx64".\n", timestamps[2]); + bug_if(is_mvk_device(device)) ok(timestamps[3] != initial_data[3] && timestamps[3] > 0, "Got unexpected timestamp %#"PRIx64".\n", timestamps[3]); release_resource_readback(&rb);
From: Giovanni Mascellani gmascellani@codeweavers.com
They require Vulkan indirect draw count extension. --- tests/d3d12.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 2cde9b1b5..3e9dbec8c 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -25153,6 +25153,7 @@ static void test_execute_indirect(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
reset_command_list(command_list, context.allocator); @@ -25250,6 +25251,7 @@ static void test_execute_indirect(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + bug_if(is_mvk_device(context.device)) check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffff00, 0);
ID3D12PipelineState_Release(pipeline_state);
From: Giovanni Mascellani gmascellani@codeweavers.com
I haven't been able to understand what's happening here exactly, but it doesn't look like we're generating bad Vulkan calls. --- tests/d3d12.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 3e9dbec8c..6ecf5d672 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -25810,7 +25810,13 @@ static void test_instance_id(void) D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (j = 0; j < ARRAY_SIZE(expected_results); ++j) + { + /* MoltenVK seems to have a bug with instanced draws when + * the instance data step rate is zero: in some cases + * StartVertexLocation seems to be ignored. */ + bug_if(is_mvk_device(context.device) && i == 0 && 8 <= j && j < 12) check_readback_data_uint(&rb.rb, &expected_results[j].box, tests[i].expected_colors[j], 1); + } release_resource_readback(&rb); reset_command_list(command_list, context.allocator); transition_resource_state(command_list, render_target,
From: Giovanni Mascellani gmascellani@codeweavers.com
--- tests/d3d12.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 6ecf5d672..8d671284f 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -33923,11 +33923,11 @@ static void test_read_write_subresource(void)
/* NULL box */ hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, dst_buffer, row_pitch, slice_pitch); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, NULL); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Empty box */ @@ -33966,20 +33966,20 @@ static void test_read_write_subresource(void) if (i) { hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, zero_buffer, row_pitch, slice_pitch); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Write region 1 */ set_box(&box, 0, 0, 0, 2, 2, 2); hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Write region 2 */ set_box(&box, 2, 2, 2, 11, 13, 17); hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2], row_pitch, slice_pitch); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); } else @@ -34001,14 +34001,14 @@ static void test_read_write_subresource(void) /* Read region 1 */ set_box(&box, 0, 0, 0, 2, 2, 2); hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Read region 2 */ set_box(&box, 2, 2, 2, 11, 13, 17); hr = ID3D12Resource_ReadFromSubresource(src_texture, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2], row_pitch, slice_pitch, 0, &box); - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
for (z = 0; z < 64; ++z) @@ -34034,7 +34034,7 @@ static void test_read_write_subresource(void) if (got != expected) break; } - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected); vkd3d_test_pop_context(); } @@ -34084,7 +34084,7 @@ static void test_read_write_subresource(void) if (got != expected) break; } - todo_if(is_nvidia_device(device)) + todo_if(is_nvidia_device(device) || is_mvk_device(device)) ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected); release_resource_readback(&rb);