diff --git a/tests/shader_runner.c b/tests/shader_runner.c index a820810a..143d0c72 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -412,6 +412,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) else if (match_string(line, "probe", &line)) { unsigned int left, top, right, bottom, ulps; + struct resource_readback *rb; struct vec4 v; int ret, len; RECT rect; @@ -433,6 +434,10 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) set_rect(&rect, left, top, left + 1, top + 1); line += len; } + else + { + fatal_error("Malformed probe arguments '%s'.\n", line); + } if (!match_string(line, "rgba", &line)) fatal_error("Malformed probe arguments '%s'.\n", line); @@ -443,7 +448,9 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (ret < 5) ulps = 0; - runner->ops->probe_vec4(runner, &rect, &v, ulps); + rb = runner->ops->get_rt_readback(runner); + todo_if(runner->is_todo) check_readback_data_vec4(rb, &rect, &v, ulps); + runner->ops->release_readback(runner, rb); } else if (match_string(line, "uniform", &line)) { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 9685eaa3..6ed0109e 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -123,7 +123,8 @@ struct shader_runner_ops struct resource *(*create_resource)(struct shader_runner *runner, const struct resource_params *params); void (*destroy_resource)(struct shader_runner *runner, struct resource *resource); bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count); - void (*probe_vec4)(struct shader_runner *runner, const RECT *rect, const struct vec4 *v, unsigned int ulps); + struct resource_readback *(*get_rt_readback)(struct shader_runner *runner); + void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb); }; void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2); diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index a4e4f52b..6edbdf75 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -546,8 +546,10 @@ struct d3d11_resource_readback ID3D11Resource *resource; }; -static void init_readback(struct d3d11_shader_runner *runner, struct d3d11_resource_readback *rb) +static struct resource_readback *d3d11_runner_get_rt_readback(struct shader_runner *r) { + struct d3d11_shader_runner *runner = d3d11_shader_runner(r); + struct d3d11_resource_readback *rb = malloc(sizeof(*rb)); D3D11_TEXTURE2D_DESC texture_desc; D3D11_MAPPED_SUBRESOURCE map_desc; HRESULT hr; @@ -569,22 +571,17 @@ static void init_readback(struct d3d11_shader_runner *runner, struct d3d11_resou rb->rb.width = texture_desc.Width; rb->rb.height = texture_desc.Height; rb->rb.depth = 1; + return &rb->rb; } -static void release_readback(struct d3d11_shader_runner *runner, struct d3d11_resource_readback *rb) -{ - ID3D11DeviceContext_Unmap(runner->immediate_context, rb->resource, 0); - ID3D11Resource_Release(rb->resource); -} - -static void d3d11_runner_probe_vec4(struct shader_runner *r, const RECT *rect, const struct vec4 *v, unsigned int ulps) +static void d3d11_runner_release_readback(struct shader_runner *r, struct resource_readback *rb) { + struct d3d11_resource_readback *d3d11_rb = CONTAINING_RECORD(rb, struct d3d11_resource_readback, rb); struct d3d11_shader_runner *runner = d3d11_shader_runner(r); - struct d3d11_resource_readback rb; - init_readback(runner, &rb); - check_readback_data_vec4(&rb.rb, rect, v, ulps); - release_readback(runner, &rb); + ID3D11DeviceContext_Unmap(runner->immediate_context, d3d11_rb->resource, 0); + ID3D11Resource_Release(d3d11_rb->resource); + free(d3d11_rb); } static const struct shader_runner_ops d3d11_runner_ops = @@ -592,7 +589,8 @@ static const struct shader_runner_ops d3d11_runner_ops = .create_resource = d3d11_runner_create_resource, .destroy_resource = d3d11_runner_destroy_resource, .draw = d3d11_runner_draw, - .probe_vec4 = d3d11_runner_probe_vec4, + .get_rt_readback = d3d11_runner_get_rt_readback, + .release_readback = d3d11_runner_release_readback, }; void run_shader_tests_d3d11(int argc, char **argv) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 1a546f21..22c9b226 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -309,22 +309,31 @@ static bool d3d12_runner_draw(struct shader_runner *r, return true; } -static void d3d12_runner_probe_vec4(struct shader_runner *r, - const RECT *rect, const struct vec4 *v, unsigned int ulps) +static struct resource_readback *d3d12_runner_get_rt_readback(struct shader_runner *r) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; - struct d3d12_resource_readback rb; + struct d3d12_resource_readback *rb = malloc(sizeof(*rb)); transition_resource_state(test_context->list, test_context->render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(test_context->render_target, 0, &rb, + get_texture_readback_with_command_list(test_context->render_target, 0, rb, test_context->queue, test_context->list); - todo_if (runner->r.is_todo) check_readback_data_vec4(&rb.rb, rect, v, ulps); - release_resource_readback(&rb); + + return &rb->rb; +} + +static void d3d12_runner_release_readback(struct shader_runner *r, struct resource_readback *rb) +{ + struct d3d12_resource_readback *d3d12_rb = CONTAINING_RECORD(rb, struct d3d12_resource_readback, rb); + struct d3d12_shader_runner *runner = d3d12_shader_runner(r); + struct test_context *test_context = &runner->test_context; + + release_resource_readback(d3d12_rb); reset_command_list(test_context->list, test_context->allocator); transition_resource_state(test_context->list, test_context->render_target, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + free(d3d12_rb); } static const struct shader_runner_ops d3d12_runner_ops = @@ -332,7 +341,8 @@ static const struct shader_runner_ops d3d12_runner_ops = .create_resource = d3d12_runner_create_resource, .destroy_resource = d3d12_runner_destroy_resource, .draw = d3d12_runner_draw, - .probe_vec4 = d3d12_runner_probe_vec4, + .get_rt_readback = d3d12_runner_get_rt_readback, + .release_readback = d3d12_runner_release_readback, }; void run_shader_tests_d3d12(int argc, char **argv) diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 8fa189cc..b9ec55b4 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -455,8 +455,10 @@ struct d3d9_resource_readback IDirect3DSurface9 *surface; }; -static void init_readback(struct d3d9_shader_runner *runner, struct d3d9_resource_readback *rb) +static struct resource_readback *d3d9_runner_get_rt_readback(struct shader_runner *r) { + struct d3d9_shader_runner *runner = d3d9_shader_runner(r); + struct d3d9_resource_readback *rb = malloc(sizeof(*rb)); D3DLOCKED_RECT map_desc; D3DSURFACE_DESC desc; HRESULT hr; @@ -478,22 +480,16 @@ static void init_readback(struct d3d9_shader_runner *runner, struct d3d9_resourc rb->rb.width = desc.Width; rb->rb.height = desc.Height; rb->rb.depth = 1; + return &rb->rb; } -static void release_readback(struct d3d9_resource_readback *rb) +static void d3d9_runner_release_readback(struct shader_runner *r, struct resource_readback *rb) { - IDirect3DSurface9_UnlockRect(rb->surface); - IDirect3DSurface9_Release(rb->surface); -} + struct d3d9_resource_readback *d3d9_rb = CONTAINING_RECORD(rb, struct d3d9_resource_readback, rb); -static void d3d9_runner_probe_vec4(struct shader_runner *r, const RECT *rect, const struct vec4 *v, unsigned int ulps) -{ - struct d3d9_shader_runner *runner = d3d9_shader_runner(r); - struct d3d9_resource_readback rb; - - init_readback(runner, &rb); - check_readback_data_vec4(&rb.rb, rect, v, ulps); - release_readback(&rb); + IDirect3DSurface9_UnlockRect(d3d9_rb->surface); + IDirect3DSurface9_Release(d3d9_rb->surface); + free(d3d9_rb); } static const struct shader_runner_ops d3d9_runner_ops = @@ -502,7 +498,8 @@ static const struct shader_runner_ops d3d9_runner_ops = .create_resource = d3d9_runner_create_resource, .destroy_resource = d3d9_runner_destroy_resource, .draw = d3d9_runner_draw, - .probe_vec4 = d3d9_runner_probe_vec4, + .get_rt_readback = d3d9_runner_get_rt_readback, + .release_readback = d3d9_runner_release_readback, }; void run_shader_tests_d3d9(int argc, char **argv) diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index f218399b..601eb5a1 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -832,21 +832,21 @@ struct vulkan_resource_readback VkBuffer buffer; }; -static void vulkan_runner_probe_vec4(struct shader_runner *r, const RECT *rect, const struct vec4 *v, unsigned int ulps) +static struct resource_readback *vulkan_runner_get_rt_readback(struct shader_runner *r) { struct vulkan_shader_runner *runner = vulkan_shader_runner(r); - struct vulkan_resource_readback rb; + struct vulkan_resource_readback *rb = malloc(sizeof(*rb)); VkDevice device = runner->device; VkBufferImageCopy region = {0}; - rb.rb.width = RENDER_TARGET_WIDTH; - rb.rb.height = RENDER_TARGET_HEIGHT; - rb.rb.depth = 1; + rb->rb.width = RENDER_TARGET_WIDTH; + rb->rb.height = RENDER_TARGET_HEIGHT; + rb->rb.depth = 1; - rb.rb.row_pitch = rb.rb.width * sizeof(struct vec4); + rb->rb.row_pitch = rb->rb.width * sizeof(struct vec4); - rb.buffer = create_buffer(runner, rb.rb.row_pitch * RENDER_TARGET_HEIGHT, - VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &rb.memory); + rb->buffer = create_buffer(runner, rb->rb.row_pitch * RENDER_TARGET_HEIGHT, + VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &rb->memory); begin_command_buffer(runner); @@ -860,19 +860,28 @@ static void vulkan_runner_probe_vec4(struct shader_runner *r, const RECT *rect, region.imageExtent.depth = 1; VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, runner->render_target, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb.buffer, 1, ®ion)); + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion)); transition_image_layout(runner, runner->render_target, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); end_command_buffer(runner); - VK_CALL(vkMapMemory(device, rb.memory, 0, VK_WHOLE_SIZE, 0, &rb.rb.data)); - todo_if (runner->r.is_todo) check_readback_data_vec4(&rb.rb, rect, v, ulps); - VK_CALL(vkUnmapMemory(device, rb.memory)); + VK_CALL(vkMapMemory(device, rb->memory, 0, VK_WHOLE_SIZE, 0, &rb->rb.data)); + return &rb->rb; +} - VK_CALL(vkFreeMemory(device, rb.memory, NULL)); - VK_CALL(vkDestroyBuffer(device, rb.buffer, NULL)); +static void vulkan_runner_release_readback(struct shader_runner *r, struct resource_readback *rb) +{ + struct vulkan_resource_readback *vulkan_rb = CONTAINING_RECORD(rb, struct vulkan_resource_readback, rb); + struct vulkan_shader_runner *runner = vulkan_shader_runner(r); + VkDevice device = runner->device; + + VK_CALL(vkUnmapMemory(device, vulkan_rb->memory)); + + VK_CALL(vkFreeMemory(device, vulkan_rb->memory, NULL)); + VK_CALL(vkDestroyBuffer(device, vulkan_rb->buffer, NULL)); + free(vulkan_rb); } static const struct shader_runner_ops vulkan_runner_ops = @@ -880,7 +889,8 @@ static const struct shader_runner_ops vulkan_runner_ops = .create_resource = vulkan_runner_create_resource, .destroy_resource = vulkan_runner_destroy_resource, .draw = vulkan_runner_draw, - .probe_vec4 = vulkan_runner_probe_vec4, + .get_rt_readback = vulkan_runner_get_rt_readback, + .release_readback = vulkan_runner_release_readback, }; static bool get_graphics_queue_index(const struct vulkan_shader_runner *runner, uint32_t *index)