From 930fbcbb26522341757fb78c8b9d5e276d053929 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 19 Feb 2024 16:47:11 +0100 Subject: [PATCH] tests/shader_runner: Pass the runner capabilities to run_shader_tests(). Allowing these to be checked by run_shader_tests() itself, instead of reimplementing those checks in each individual runner. --- tests/shader_runner.c | 29 +++++++++++----- tests/shader_runner.h | 16 ++++++--- tests/shader_runner_d3d11.c | 26 ++++----------- tests/shader_runner_d3d12.c | 64 ++++++++++++++++-------------------- tests/shader_runner_d3d9.c | 34 ++++++++----------- tests/shader_runner_gl.c | 26 +++------------ tests/shader_runner_vulkan.c | 31 +++++------------ 7 files changed, 94 insertions(+), 132 deletions(-) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 3fa00101..4f5a04ef 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -1309,8 +1309,22 @@ static enum parse_state read_shader_directive(struct shader_runner *runner, enum return state; } -void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler, - enum shader_model minimum_shader_model, enum shader_model maximum_shader_model) +static bool check_requirements(const struct shader_runner *runner, const struct shader_runner_caps *caps) +{ + if (runner->maximum_shader_model < runner->minimum_shader_model) + return false; + if (runner->require_float64 && !caps->float64) + return false; + if (runner->require_int64 && !caps->int64) + return false; + if (runner->require_rov && !caps->rov) + return false; + + return true; +} + +void run_shader_tests(struct shader_runner *runner, const struct shader_runner_caps *caps, + const struct shader_runner_ops *ops, void *dxc_compiler) { size_t shader_source_size = 0, shader_source_len = 0; struct resource_params current_resource; @@ -1332,8 +1346,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o memset(runner, 0, sizeof(*runner)); runner->ops = ops; - runner->minimum_shader_model = minimum_shader_model; - runner->maximum_shader_model = maximum_shader_model; + runner->minimum_shader_model = caps->minimum_shader_model; + runner->maximum_shader_model = caps->maximum_shader_model; if ((testname = strrchr(test_options.filename, '/'))) ++testname; @@ -1360,8 +1374,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o break; case STATE_REQUIRE: - if (runner->maximum_shader_model < runner->minimum_shader_model - || !runner->ops->check_requirements(runner)) + if (!check_requirements(runner, caps)) skip_tests = true; break; @@ -1512,8 +1525,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o else if (!strcmp(line, "[require]\n")) { state = STATE_REQUIRE; - runner->minimum_shader_model = minimum_shader_model; - runner->maximum_shader_model = maximum_shader_model; + runner->minimum_shader_model = caps->minimum_shader_model; + runner->maximum_shader_model = caps->maximum_shader_model; runner->require_float64 = false; runner->require_int64 = false; runner->require_rov = false; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index da4b2efc..10637368 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -117,6 +117,15 @@ struct input_element #define MAX_RESOURCES 32 #define MAX_SAMPLERS 32 +struct shader_runner_caps +{ + enum shader_model minimum_shader_model; + enum shader_model maximum_shader_model; + bool float64; + bool int64; + bool rov; +}; + struct shader_runner { const struct shader_runner_ops *ops; @@ -152,9 +161,6 @@ struct shader_runner struct shader_runner_ops { - /* Returns false if unable to run the given tests. If NULL, all tests are - * run. */ - bool (*check_requirements)(struct shader_runner *runner); 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); @@ -177,8 +183,8 @@ HRESULT dxc_compiler_compile_shader(void *dxc_compiler, enum shader_type type, u struct sampler *shader_runner_get_sampler(struct shader_runner *runner, unsigned int slot); struct resource *shader_runner_get_resource(struct shader_runner *runner, enum resource_type type, unsigned int slot); -void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler, - enum shader_model minimum_shader_model, enum shader_model maximum_shader_model); +void run_shader_tests(struct shader_runner *runner, const struct shader_runner_caps *caps, + const struct shader_runner_ops *ops, void *dxc_compiler); #ifdef _WIN32 void run_shader_tests_d3d9(void); diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index e7fb3800..7ca61109 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -65,15 +65,13 @@ static struct d3d11_resource *d3d11_resource(struct resource *r) struct d3d11_shader_runner { struct shader_runner r; + struct shader_runner_caps caps; ID3D11Device *device; HWND window; IDXGISwapChain *swapchain; ID3D11DeviceContext *immediate_context; ID3D11RasterizerState *rasterizer_state; - - bool supports_float64; - bool supports_rov; }; static struct d3d11_shader_runner *d3d11_shader_runner(struct shader_runner *r) @@ -277,17 +275,20 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) return FALSE; } + runner->caps.minimum_shader_model = SHADER_MODEL_4_0; + runner->caps.maximum_shader_model = SHADER_MODEL_5_1; + hr = ID3D11Device_CheckFeatureSupport(runner->device, D3D11_FEATURE_DOUBLES, &doubles, sizeof(doubles)); ok(hr == S_OK, "Failed to check double precision feature support, hr %#lx.\n", hr); trace("DoublePrecisionFloatShaderOps: %u.\n", doubles.DoublePrecisionFloatShaderOps); - runner->supports_float64 = doubles.DoublePrecisionFloatShaderOps; + runner->caps.float64 = doubles.DoublePrecisionFloatShaderOps; hr = ID3D11Device_CheckFeatureSupport(runner->device, D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2)); ok(hr == S_OK, "Got hr %#lx.\n", hr); trace("ROVsSupported: %u.\n", options2.ROVsSupported); - runner->supports_rov = options2.ROVsSupported; + runner->caps.rov = options2.ROVsSupported; rt_width = RENDER_TARGET_WIDTH; rt_height = RENDER_TARGET_HEIGHT; @@ -336,18 +337,6 @@ static void destroy_test_context(struct d3d11_shader_runner *runner) ok(!ref, "Device has %lu references left.\n", ref); } -static bool d3d11_runner_check_requirements(struct shader_runner *r) -{ - struct d3d11_shader_runner *runner = d3d11_shader_runner(r); - - if (runner->r.require_float64 && !runner->supports_float64) - return false; - if (runner->r.require_rov && !runner->supports_rov) - return false; - - return true; -} - static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags, unsigned int size, const void *data) { D3D11_SUBRESOURCE_DATA resource_data; @@ -794,7 +783,6 @@ static void d3d11_runner_release_readback(struct shader_runner *r, struct resour static const struct shader_runner_ops d3d11_runner_ops = { - .check_requirements = d3d11_runner_check_requirements, .create_resource = d3d11_runner_create_resource, .destroy_resource = d3d11_runner_destroy_resource, .dispatch = d3d11_runner_dispatch, @@ -820,7 +808,7 @@ void run_shader_tests_d3d11(void) init_adapter_info(); if (init_test_context(&runner)) { - run_shader_tests(&runner.r, &d3d11_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1); + run_shader_tests(&runner.r, &runner.caps, &d3d11_runner_ops, NULL); destroy_test_context(&runner); } } diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 88a34100..74ca9492 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -50,6 +50,7 @@ static struct d3d12_resource *d3d12_resource(struct resource *r) struct d3d12_shader_runner { struct shader_runner r; + struct shader_runner_caps caps; struct test_context test_context; @@ -60,9 +61,6 @@ struct d3d12_shader_runner ID3D12GraphicsCommandList *compute_list; IDxcCompiler3 *dxc_compiler; - - D3D12_FEATURE_DATA_D3D12_OPTIONS options; - D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; }; static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r) @@ -107,22 +105,6 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons return blob; } -static bool d3d12_runner_check_requirements(struct shader_runner *r) -{ - struct d3d12_shader_runner *runner = d3d12_shader_runner(r); - - if (runner->r.require_float64 && !runner->options.DoublePrecisionFloatShaderOps) - return false; - - if (runner->r.require_int64 && !runner->options1.Int64ShaderOps) - return false; - - if (runner->r.require_rov && !runner->options.ROVsSupported) - return false; - - return true; -} - #define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2) static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params) @@ -628,7 +610,6 @@ static void d3d12_runner_release_readback(struct shader_runner *r, struct resour static const struct shader_runner_ops d3d12_runner_ops = { - .check_requirements = d3d12_runner_check_requirements, .create_resource = d3d12_runner_create_resource, .destroy_resource = d3d12_runner_destroy_resource, .dispatch = d3d12_runner_dispatch, @@ -637,6 +618,28 @@ static const struct shader_runner_ops d3d12_runner_ops = .release_readback = d3d12_runner_release_readback, }; +static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner) +{ + ID3D12Device *device = runner->test_context.device; + D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; + D3D12_FEATURE_DATA_D3D12_OPTIONS options; + HRESULT hr; + + hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); + ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr); + trace("DoublePrecisionFloatShaderOps: %u.\n", options.DoublePrecisionFloatShaderOps); + trace("ROVsSupported: %u.\n", options.ROVsSupported); + hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)); + ok(hr == S_OK, "Failed to check feature options1 support, hr %#x.\n", hr); + trace("Int64ShaderOps: %u.\n", options1.Int64ShaderOps); + + runner->caps.minimum_shader_model = SHADER_MODEL_4_0; + runner->caps.maximum_shader_model = SHADER_MODEL_5_1; + runner->caps.float64 = options.DoublePrecisionFloatShaderOps; + runner->caps.int64 = options1.Int64ShaderOps; + runner->caps.rov = options.ROVsSupported; +} + void run_shader_tests_d3d12(void *dxc_compiler) { static const struct test_context_desc desc = @@ -654,6 +657,8 @@ void run_shader_tests_d3d12(void *dxc_compiler) init_adapter_info(); if (!init_test_context(&runner.test_context, &desc)) return; + d3d12_runner_init_caps(&runner); + device = runner.test_context.device; runner.dxc_compiler = dxc_compiler; @@ -669,25 +674,14 @@ void run_shader_tests_d3d12(void *dxc_compiler) runner.compute_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&runner.compute_list); ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); - hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, - &runner.options, sizeof(runner.options)); - ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr); - trace("DoublePrecisionFloatShaderOps: %u.\n", runner.options.DoublePrecisionFloatShaderOps); - trace("ROVsSupported: %u.\n", runner.options.ROVsSupported); - - hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1, - &runner.options1, sizeof(runner.options1)); - ok(hr == S_OK, "Failed to check feature options1 support, hr %#x.\n", hr); - trace("Compiling SM4-SM5 shaders with %s and executing with %s\n", HLSL_COMPILER, SHADER_RUNNER); - run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, SHADER_MODEL_4_0, SHADER_MODEL_5_1); - + run_shader_tests(&runner.r, &runner.caps, &d3d12_runner_ops, NULL); if (dxc_compiler) { - trace("Int64ShaderOps: %u.\n", runner.options1.Int64ShaderOps); - + runner.caps.minimum_shader_model = SHADER_MODEL_6_0; + runner.caps.maximum_shader_model = SHADER_MODEL_6_0; trace("Compiling SM6 shaders with dxcompiler and executing with %s\n", SHADER_RUNNER); - run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, SHADER_MODEL_6_0, SHADER_MODEL_6_0); + run_shader_tests(&runner.r, &runner.caps, &d3d12_runner_ops, dxc_compiler); } ID3D12GraphicsCommandList_Release(runner.compute_list); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index c8ec532a..7bad3dc2 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -50,6 +50,7 @@ static struct d3d9_resource *d3d9_resource(struct resource *r) struct d3d9_shader_runner { struct shader_runner r; + struct shader_runner_caps caps; IDirect3DDevice9 *device; HWND window; @@ -154,6 +155,9 @@ static bool init_test_context(struct d3d9_shader_runner *runner) return false; } + runner->caps.minimum_shader_model = SHADER_MODEL_2_0; + runner->caps.maximum_shader_model = SHADER_MODEL_3_0; + return true; } @@ -189,19 +193,6 @@ static D3DTEXTUREADDRESS sampler_address_to_d3d9(D3D12_TEXTURE_ADDRESS_MODE addr vkd3d_unreachable(); } -static bool d3d9_runner_check_requirements(struct shader_runner *r) -{ - struct d3d9_shader_runner *runner = d3d9_shader_runner(r); - - if (runner->r.minimum_shader_model >= SHADER_MODEL_4_0) - return false; - - if (runner->r.require_rov) - return false; - - return true; -} - static struct resource *d3d9_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct d3d9_shader_runner *runner = d3d9_shader_runner(r); @@ -535,7 +526,6 @@ static void d3d9_runner_release_readback(struct shader_runner *r, struct resourc static const struct shader_runner_ops d3d9_runner_ops = { - .check_requirements = d3d9_runner_check_requirements, .create_resource = d3d9_runner_create_resource, .destroy_resource = d3d9_runner_destroy_resource, .dispatch = d3d9_runner_dispatch, @@ -551,16 +541,18 @@ void run_shader_tests_d3d9(void) trace("Compiling SM2-SM3 shaders with %s and executing with d3d9.dll\n", HLSL_COMPILER); - d3d9_module = LoadLibraryA("d3d9.dll"); - if (d3d9_module) - { - pDirect3DCreate9 = (void *)GetProcAddress(d3d9_module, "Direct3DCreate9"); + if (!(d3d9_module = LoadLibraryA("d3d9.dll"))) + return; - init_adapter_info(); - init_test_context(&runner); - run_shader_tests(&runner.r, &d3d9_runner_ops, NULL, SHADER_MODEL_2_0, SHADER_MODEL_3_0); + pDirect3DCreate9 = (void *)GetProcAddress(d3d9_module, "Direct3DCreate9"); + + init_adapter_info(); + if (init_test_context(&runner)) + { + run_shader_tests(&runner.r, &runner.caps, &d3d9_runner_ops, NULL); destroy_test_context(&runner); } + FreeLibrary(d3d9_module); } diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index a24beb7b..fedb20e7 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -58,12 +58,7 @@ static struct gl_resource *gl_resource(struct resource *r) struct gl_runner { struct shader_runner r; - - struct - { - bool float64; - bool int64; - } caps; + struct shader_runner_caps caps; EGLDisplay display; EGLContext context; @@ -230,6 +225,8 @@ static bool gl_runner_init(struct gl_runner *runner) eglTerminate(display); continue; } + runner->caps.minimum_shader_model = SHADER_MODEL_4_0; + runner->caps.maximum_shader_model = SHADER_MODEL_5_1; trace("Using device %u.\n", i); runner->display = display; @@ -289,20 +286,6 @@ static void gl_runner_cleanup(struct gl_runner *runner) ok(ret, "Failed to terminate EGL display connection.\n"); } -static bool gl_runner_check_requirements(struct shader_runner *r) -{ - struct gl_runner *runner = gl_runner(r); - - if (r->require_float64 && !runner->caps.float64) - return false; - if (r->require_int64 && !runner->caps.int64) - return false; - if (r->require_rov) - return false; - - return true; -} - static const struct format_info *get_format_info(enum DXGI_FORMAT format) { size_t i; @@ -1033,7 +1016,6 @@ static void gl_runner_release_readback(struct shader_runner *runner, struct reso static const struct shader_runner_ops gl_runner_ops = { - .check_requirements = gl_runner_check_requirements, .create_resource = gl_runner_create_resource, .destroy_resource = gl_runner_destroy_resource, .dispatch = gl_runner_dispatch, @@ -1053,7 +1035,7 @@ void run_shader_tests_gl(void) goto done; trace("Compiling SM4-SM5 shaders with vkd3d-shader and executing with OpenGL\n"); - run_shader_tests(&runner.r, &gl_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1); + run_shader_tests(&runner.r, &runner.caps, &gl_runner_ops, NULL); gl_runner_cleanup(&runner); done: vkd3d_test_name = test_name; diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index f95fabc5..c1b167eb 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -55,6 +55,7 @@ DECLARE_VK_PFN(vkGetInstanceProcAddr) struct vulkan_shader_runner { struct shader_runner r; + struct shader_runner_caps caps; VkInstance instance; VkPhysicalDevice phys_device; @@ -72,9 +73,6 @@ struct vulkan_shader_runner uint32_t binding; } samplers[MAX_SAMPLERS]; - bool supports_float64; - bool supports_int64; - DECLARE_VK_PFN(vkCreateInstance); #define VK_INSTANCE_PFN DECLARE_VK_PFN #define VK_DEVICE_PFN DECLARE_VK_PFN @@ -86,20 +84,6 @@ static struct vulkan_shader_runner *vulkan_shader_runner(struct shader_runner *r return CONTAINING_RECORD(r, struct vulkan_shader_runner, r); } -static bool vulkan_runner_check_requirements(struct shader_runner *r) -{ - struct vulkan_shader_runner *runner = vulkan_shader_runner(r); - - if (runner->r.require_float64 && !runner->supports_float64) - return false; - if (runner->r.require_int64 && !runner->supports_int64) - return false; - if (runner->r.require_rov) - return false; - - return true; -} - #define VK_CALL(f) (runner->f) static void begin_command_buffer(struct vulkan_shader_runner *runner) @@ -1225,7 +1209,6 @@ static void vulkan_runner_release_readback(struct shader_runner *r, struct resou static const struct shader_runner_ops vulkan_runner_ops = { - .check_requirements = vulkan_runner_check_requirements, .create_resource = vulkan_runner_create_resource, .destroy_resource = vulkan_runner_destroy_resource, .dispatch = vulkan_runner_dispatch, @@ -1396,13 +1379,13 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) if (ret_features.shaderFloat64) { features.shaderFloat64 = VK_TRUE; - runner->supports_float64 = true; + runner->caps.float64 = true; } trace("shaderInt64: %u.\n", ret_features.shaderInt64); if (ret_features.shaderInt64) { features.shaderInt64 = VK_TRUE; - runner->supports_int64 = true; + runner->caps.int64 = true; } if ((vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device)))) @@ -1470,11 +1453,15 @@ void run_shader_tests_vulkan(void) if (!init_vulkan_runner(&runner)) return; + runner.caps.minimum_shader_model = SHADER_MODEL_2_0; + runner.caps.maximum_shader_model = SHADER_MODEL_3_0; trace("Compiling SM2-SM3 shaders with vkd3d-shader and executing with Vulkan\n"); - run_shader_tests(&runner.r, &vulkan_runner_ops, NULL, SHADER_MODEL_2_0, SHADER_MODEL_3_0); + run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL); + runner.caps.minimum_shader_model = SHADER_MODEL_4_0; + runner.caps.maximum_shader_model = SHADER_MODEL_5_1; trace("Compiling SM4-SM5 shaders with vkd3d-shader and executing with Vulkan\n"); - run_shader_tests(&runner.r, &vulkan_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1); + run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL); cleanup_vulkan_runner(&runner); }