From: Francisco Casas fcasas@codeweavers.com
This would allow us to test compilation of SM1 shaders even if we don't have an available backend that can run them. --- tests/shader_runner.c | 73 ++++++++++++++++++++++++++++-------- tests/shader_runner.h | 2 +- tests/shader_runner_d3d11.c | 2 +- tests/shader_runner_d3d12.c | 2 +- tests/shader_runner_d3d9.c | 2 +- tests/shader_runner_vulkan.c | 2 +- 6 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index fa631588d..feabf0113 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -501,6 +501,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (ret < 3) fatal_error("Malformed dispatch arguments '%s'.\n", line);
+ assert(runner->ops->dispatch); runner->last_render_failed = !runner->ops->dispatch(runner, x, y, z); } else if (match_string(line, "draw quad", &line)) @@ -533,6 +534,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) params.height = RENDER_TARGET_HEIGHT; params.level_count = 1;
+ assert(runner->ops->create_resource); set_resource(runner, runner->ops->create_resource(runner, ¶ms)); }
@@ -552,11 +554,13 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) params.data = malloc(sizeof(quad)); memcpy(params.data, quad, sizeof(quad)); params.data_size = sizeof(quad); + assert(runner->ops->create_resource); set_resource(runner, runner->ops->create_resource(runner, ¶ms));
if (!runner->vs_source) runner->vs_source = strdup(vs_source);
+ assert(runner->ops->draw); runner->last_render_failed = !runner->ops->draw(runner, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3); } else if (match_string(line, "draw", &line)) @@ -578,6 +582,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) params.height = RENDER_TARGET_HEIGHT; params.level_count = 1;
+ assert(runner->ops->create_resource); set_resource(runner, runner->ops->create_resource(runner, ¶ms)); }
@@ -592,6 +597,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (line == rest) fatal_error("Malformed vertex count '%s'.\n", line);
+ assert(runner->ops->draw); runner->last_render_failed = !runner->ops->draw(runner, topology, vertex_count); } else if (match_string(line, "probe", &line)) @@ -640,6 +646,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); }
+ assert(runner->ops->get_resource_readback); rb = runner->ops->get_resource_readback(runner, resource);
if (match_string(line, "all", &line)) @@ -688,6 +695,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed probe arguments '%s'.\n", line); }
+ assert(runner->ops->release_readback); runner->ops->release_readback(runner, rb); } else if (match_string(line, "uniform", &line)) @@ -934,8 +942,8 @@ static void compile_shader(struct shader_runner *runner, IDxcCompiler3 *dxc_comp
static const char *const shader_models[] = { - [SHADER_MODEL_2_0] = "4_0", - [SHADER_MODEL_3_0] = "4_0", + [SHADER_MODEL_2_0] = "2_0", + [SHADER_MODEL_3_0] = "3_0", [SHADER_MODEL_4_0] = "4_0", [SHADER_MODEL_4_1] = "4_1", [SHADER_MODEL_5_0] = "5_0", @@ -1021,7 +1029,7 @@ static enum parse_state read_shader_directive(struct shader_runner *runner, enum }
static void run_shader_tests_with_model(struct shader_runner *runner, const struct shader_runner_ops *ops, - void *dxc_compiler, enum shader_model model) + void *dxc_compiler, enum shader_model model, bool compilation_check) { size_t shader_source_size = 0, shader_source_len = 0; struct resource_params current_resource; @@ -1054,9 +1062,12 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru if (runner->current_shader_model == SHADER_MODEL_6_0) skip_tests = false;
- assert(runner->ops->check_requirements); - if (!runner->ops->check_requirements(runner)) - skip_tests = true; + if (runner->ops) + { + assert(runner->ops->check_requirements); + if (!runner->ops->check_requirements(runner)) + skip_tests = true; + }
for (;;) { @@ -1076,7 +1087,7 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru break;
case STATE_REQUIRE: - if (!runner->ops->check_requirements(runner)) + if (runner->ops && !runner->ops->check_requirements(runner)) skip_tests = true;
break; @@ -1087,14 +1098,15 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru * textures with data type other than float). */ if (!skip_tests) { - set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); + if (runner->ops) + set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); } free(current_resource.data); break;
case STATE_SHADER_COMPUTE: case STATE_SHADER_COMPUTE_TODO: - if (!skip_tests) + if (!skip_tests && compilation_check) { todo_if (state == STATE_SHADER_COMPUTE_TODO) compile_shader(runner, dxc_compiler, shader_source, shader_source_len, SHADER_TYPE_CS, @@ -1109,7 +1121,7 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru
case STATE_SHADER_PIXEL: case STATE_SHADER_PIXEL_TODO: - if (!skip_tests) + if (!skip_tests && compilation_check) { todo_if (state == STATE_SHADER_PIXEL_TODO) compile_shader(runner, dxc_compiler, shader_source, shader_source_len, SHADER_TYPE_PS, @@ -1124,7 +1136,7 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru
case STATE_SHADER_VERTEX: case STATE_SHADER_VERTEX_TODO: - if (!skip_tests) + if (!skip_tests && compilation_check) { todo_if (state == STATE_SHADER_VERTEX_TODO) compile_shader(runner, dxc_compiler, shader_source, shader_source_len, SHADER_TYPE_VS, @@ -1378,7 +1390,7 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru case STATE_TEST: /* Compilation which fails with dxcompiler is not 'todo', therefore the tests are * not 'todo' either. They cannot run, so skip them entirely. */ - if (!skip_tests && SUCCEEDED(expect_hr)) + if (!skip_tests && !compilation_check && SUCCEEDED(expect_hr)) parse_test_directive(runner, line); break; } @@ -1392,6 +1404,7 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru free(runner->ps_source); for (i = 0; i < runner->resource_count; ++i) { + assert(runner->ops); if (runner->resources[i]) runner->ops->destroy_resource(runner, runner->resources[i]); } @@ -1399,18 +1412,33 @@ static void run_shader_tests_with_model(struct shader_runner *runner, const stru fclose(f); }
-void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler) +static void run_shader_tests_range(struct shader_runner *runner, const struct shader_runner_ops *ops, + enum shader_model minimum_shader_model, enum shader_model maximum_shader_model, + bool compilation_check, void *dxc_compiler) { unsigned int i;
- for (i = SHADER_MODEL_2_0; i <= SHADER_MODEL_6_0; ++i) + for (i = minimum_shader_model; i <= maximum_shader_model; ++i) { vkd3d_test_push_context("Model %s", model_strings[i]); - run_shader_tests_with_model(runner, ops, dxc_compiler, i); + run_shader_tests_with_model(runner, ops, dxc_compiler, i, compilation_check); vkd3d_test_pop_context(); } }
+void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops) +{ + run_shader_tests_range(runner, ops, SHADER_MODEL_2_0, SHADER_MODEL_6_0, false, NULL); +} + +static void run_compilation_tests(enum shader_model minimum_shader_model, enum shader_model maximum_shader_model, + void *dxc_compiler) +{ + struct shader_runner runner = {0}; + + run_shader_tests_range(&runner, NULL, minimum_shader_model, maximum_shader_model, true, dxc_compiler); +} + #ifdef _WIN32 static void print_dll_version(const char *file_name) { @@ -1509,6 +1537,9 @@ START_TEST(shader_runner) #if defined(VKD3D_CROSSTEST) trace("Running tests from a Windows cross build\n");
+ trace("Compiling shaders with d3dcompiler_47.dll\n"); + run_compilation_tests(SHADER_MODEL_2_0, SHADER_MODEL_5_1, NULL); + trace("Compiling shaders with d3dcompiler_47.dll and executing with d3d9.dll\n"); run_shader_tests_d3d9();
@@ -1526,6 +1557,9 @@ START_TEST(shader_runner) #elif defined(_WIN32) trace("Running tests from a Windows non-cross build\n");
+ trace("Compiling shaders with vkd3d_shader.\n"); + run_compilation_tests(SHADER_MODEL_4_0, SHADER_MODEL_5_1, NULL); + trace("Compiling shaders with vkd3d-shader and executing with d3d9.dll\n"); run_shader_tests_d3d9();
@@ -1537,6 +1571,9 @@ START_TEST(shader_runner)
if ((dxc_compiler = dxcompiler_create())) { + trace("Compiling shaders with dxcompiler\n"); + run_compilation_tests(SHADER_MODEL_6_0, SHADER_MODEL_6_0, dxc_compiler); + trace("Compiling shaders with dxcompiler and executing with vkd3d\n"); run_shader_tests_d3d12(dxc_compiler, SHADER_MODEL_6_0, SHADER_MODEL_6_0); IDxcCompiler3_Release(dxc_compiler); @@ -1548,6 +1585,9 @@ START_TEST(shader_runner) #else trace("Running tests from a Unix build\n");
+ trace("Compiling shaders with vkd3d_shader.\n"); + run_compilation_tests(SHADER_MODEL_4_0, SHADER_MODEL_5_1, NULL); + trace("Compiling shaders with vkd3d-shader and executing with Vulkan\n"); run_shader_tests_vulkan();
@@ -1556,6 +1596,9 @@ START_TEST(shader_runner)
if ((dxc_compiler = dxcompiler_create())) { + trace("Compiling shaders with dxcompiler\n"); + run_compilation_tests(SHADER_MODEL_6_0, SHADER_MODEL_6_0, dxc_compiler); + trace("Compiling shaders with dxcompiler and executing with vkd3d\n"); run_shader_tests_d3d12(dxc_compiler, SHADER_MODEL_6_0, SHADER_MODEL_6_0); IDxcCompiler3_Release(dxc_compiler); diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 90202c6a7..23e8af441 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -163,7 +163,7 @@ void init_resource(struct resource *resource, const struct resource_params *para HRESULT dxc_compiler_compile_shader(void *dxc_compiler, enum shader_type type, unsigned int compile_options, const char *hlsl, ID3D10Blob **blob_out, ID3D10Blob **errors_out);
-void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler); +void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops);
#ifdef _WIN32 void run_shader_tests_d3d9(void); diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index fa05b7491..4e2a92e8f 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -753,7 +753,7 @@ void run_shader_tests_d3d11(void) init_adapter_info(); if (init_test_context(&runner)) { - run_shader_tests(&runner.r, &d3d11_runner_ops, NULL); + run_shader_tests(&runner.r, &d3d11_runner_ops); destroy_test_context(&runner); } } diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 1427aac79..8ce5f6e5e 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -629,7 +629,7 @@ void run_shader_tests_d3d12(void *dxc_compiler, enum shader_model minimum_shader runner.compute_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&runner.compute_list); ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
- run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler); + run_shader_tests(&runner.r, &d3d12_runner_ops);
ID3D12GraphicsCommandList_Release(runner.compute_list); ID3D12CommandAllocator_Release(runner.compute_allocator); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index fe7abc327..4aebd8cf1 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -538,7 +538,7 @@ void run_shader_tests_d3d9(void)
init_adapter_info(); init_test_context(&runner); - run_shader_tests(&runner.r, &d3d9_runner_ops, NULL); + run_shader_tests(&runner.r, &d3d9_runner_ops); destroy_test_context(&runner); } FreeLibrary(d3d9_module); diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index a82178c04..bed82cf51 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -1390,7 +1390,7 @@ void run_shader_tests_vulkan(void) if (!init_vulkan_runner(&runner)) return;
- run_shader_tests(&runner.r, &vulkan_runner_ops, NULL); + run_shader_tests(&runner.r, &vulkan_runner_ops);
cleanup_vulkan_runner(&runner); }