From d39e840c144a1982fac6d77ecb630d47eca06f50 Mon Sep 17 00:00:00 2001 From: Elizabeth Figura Date: Sat, 5 Oct 2024 07:46:00 -0500 Subject: [PATCH] tests/shader_runner: Store shader caps using an array. --- tests/hlsl/wave-ops-float.shader_test | 2 +- tests/hlsl/wave-ops-int.shader_test | 2 +- tests/hlsl/wave-ops-uint.shader_test | 2 +- tests/shader_runner.c | 143 ++++++++++++++------------ tests/shader_runner.h | 37 ++++--- tests/shader_runner_d3d11.c | 4 +- tests/shader_runner_d3d12.c | 12 +-- tests/shader_runner_d3d9.c | 4 +- tests/shader_runner_gl.c | 8 +- tests/shader_runner_vulkan.c | 20 ++-- 10 files changed, 120 insertions(+), 114 deletions(-) diff --git a/tests/hlsl/wave-ops-float.shader_test b/tests/hlsl/wave-ops-float.shader_test index a4b30005..e6dcf050 100644 --- a/tests/hlsl/wave-ops-float.shader_test +++ b/tests/hlsl/wave-ops-float.shader_test @@ -1,6 +1,6 @@ [require] shader model >= 6.0 -wave ops +wave-ops format r32g32b32a32-float uav-load format r32g32b32a32-uint uav-load diff --git a/tests/hlsl/wave-ops-int.shader_test b/tests/hlsl/wave-ops-int.shader_test index 7102db1b..e6bf267f 100644 --- a/tests/hlsl/wave-ops-int.shader_test +++ b/tests/hlsl/wave-ops-int.shader_test @@ -1,6 +1,6 @@ [require] shader model >= 6.0 -wave ops +wave-ops format r32g32b32a32-sint uav-load [uav 0] diff --git a/tests/hlsl/wave-ops-uint.shader_test b/tests/hlsl/wave-ops-uint.shader_test index 9047f52b..c5d27359 100644 --- a/tests/hlsl/wave-ops-uint.shader_test +++ b/tests/hlsl/wave-ops-uint.shader_test @@ -1,6 +1,6 @@ [require] shader model >= 6.0 -wave ops +wave-ops format r32-uint uav-load [uav 0] diff --git a/tests/shader_runner.c b/tests/shader_runner.c index d34de21e..0b570c27 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 Zebediah Figura for CodeWeavers + * Copyright 2020-2024 Elizabeth Figura for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -329,8 +329,34 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t fatal_error("Unknown format '%s'.\n", line); } +static const char *const shader_cap_strings[] = +{ + [SHADER_CAP_CLIP_PLANES] = "clip-planes", + [SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds", + [SHADER_CAP_FLOAT64] = "float64", + [SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader", + [SHADER_CAP_INT64] = "int64", + [SHADER_CAP_POINT_SIZE] = "point-size", + [SHADER_CAP_ROV] = "rov", + [SHADER_CAP_WAVE_OPS] = "wave-ops", +}; + +static bool match_shader_cap_string(const char *line, enum shader_cap *cap) +{ + for (enum shader_cap i = 0; i < SHADER_CAP_COUNT; ++i) + { + if (match_string(line, shader_cap_strings[i], &line)) + { + *cap = i; + return true; + } + } + return false; +} + static void parse_require_directive(struct shader_runner *runner, const char *line) { + enum shader_cap shader_cap; bool less_than = false; unsigned int i; @@ -392,37 +418,9 @@ static void parse_require_directive(struct shader_runner *runner, const char *li fatal_error("Unknown format cap '%s'.\n", line); } } - else if (match_string(line, "geometry-shader", &line)) + else if (match_shader_cap_string(line, &shader_cap)) { - runner->require_geometry_shader = true; - } - else if (match_string(line, "float64", &line)) - { - runner->require_float64 = true; - } - else if (match_string(line, "int64", &line)) - { - runner->require_int64 = true; - } - else if (match_string(line, "rov", &line)) - { - runner->require_rov = true; - } - else if (match_string(line, "wave ops", &line)) - { - runner->require_wave_ops = true; - } - else if (match_string(line, "depth-bounds", &line)) - { - runner->require_depth_bounds = true; - } - else if (match_string(line, "clip-planes", &line)) - { - runner->require_clip_planes = true; - } - else if (match_string(line, "point-size", &line)) - { - runner->require_point_size = true; + runner->require_shader_caps[shader_cap] = true; } else { @@ -932,7 +930,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) { if (sscanf(line, "%f %f", &runner->depth_min, &runner->depth_max) != 2) fatal_error("Malformed depth-bounds arguments '%s'.\n", line); - if (!runner->caps->depth_bounds) + if (!runner->caps->shader_caps[SHADER_CAP_DEPTH_BOUNDS]) fatal_error("depth-bounds set but runner does not support depth bounds testing."); runner->depth_bounds = true; } @@ -1591,22 +1589,11 @@ static bool check_capabilities(const struct shader_runner *runner, const struct { unsigned int i; - if (runner->require_geometry_shader && !caps->geometry_shader) - 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; - if (runner->require_wave_ops && !caps->wave_ops) - return false; - if (runner->require_depth_bounds && !caps->depth_bounds) - return false; - if (runner->require_clip_planes && !caps->clip_planes) - return false; - if (runner->require_point_size && !caps->point_size) - return false; + for (i = 0; i < SHADER_CAP_COUNT; ++i) + { + if (runner->require_shader_caps[i] && !caps->shader_caps[i]) + return false; + } for (i = 0; i < ARRAY_SIZE(runner->require_format_caps); ++i) { @@ -1624,7 +1611,7 @@ static void trace_tags(const struct shader_runner_caps *caps) p = tags; rem = ARRAY_SIZE(tags); - rc = snprintf(p, rem, " tags:"); + rc = snprintf(p, rem, "%8s:", "tags"); p += rc; rem -= rc; @@ -1638,7 +1625,7 @@ static void trace_tags(const struct shader_runner_caps *caps) p = tags; rem = ARRAY_SIZE(tags); - rc = snprintf(p, rem, " "); + rc = snprintf(p, rem, "%8s ", ""); --i; } p += rc; @@ -1647,6 +1634,40 @@ static void trace_tags(const struct shader_runner_caps *caps) trace("%s.\n", tags); } +static void trace_shader_caps(const bool *caps) +{ + char buffer[80], *p; + size_t rem; + int rc; + + p = buffer; + rem = ARRAY_SIZE(buffer); + rc = snprintf(p, rem, "%8s:", "caps"); + p += rc; + rem -= rc; + + for (size_t i = 0; i < SHADER_CAP_COUNT; ++i) + { + if (!caps[i]) + continue; + + rc = snprintf(p, rem, " %s", shader_cap_strings[i]); + if (!(rc >= 0 && (size_t)rc < rem)) + { + *p = 0; + trace("%s\n", buffer); + + p = buffer; + rem = ARRAY_SIZE(buffer); + rc = snprintf(p, rem, "%8s ", ""); + --i; + } + p += rc; + rem -= rc; + } + trace("%s.\n", buffer); +} + static void trace_format_cap(const struct shader_runner_caps *caps, enum format_cap cap, const char *cap_name) { bool show_none = true; @@ -1656,7 +1677,7 @@ static void trace_format_cap(const struct shader_runner_caps *caps, enum format_ p = buffer; rem = ARRAY_SIZE(buffer); - rc = snprintf(p, rem, "%15s:", cap_name); + rc = snprintf(p, rem, "%8s:", cap_name); p += rc; rem -= rc; @@ -1672,7 +1693,7 @@ static void trace_format_cap(const struct shader_runner_caps *caps, enum format_ p = buffer; rem = ARRAY_SIZE(buffer); - rc = snprintf(p, rem, " "); + rc = snprintf(p, rem, "%8s ", ""); --i; } p += rc; @@ -1718,14 +1739,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c dxc_compiler ? "dxcompiler" : HLSL_COMPILER, caps->runner); if (caps->tag_count) trace_tags(caps); - trace("geometry-shader: %u.\n", caps->geometry_shader); - trace(" float64: %u.\n", caps->float64); - trace(" int64: %u.\n", caps->int64); - trace(" rov: %u.\n", caps->rov); - trace(" wave-ops: %u.\n", caps->wave_ops); - trace(" depth-bounds: %u.\n", caps->depth_bounds); - trace(" clip-planes: %u.\n", caps->clip_planes); - trace(" point-size: %u.\n", caps->point_size); + trace_shader_caps(caps->shader_caps); trace_format_cap(caps, FORMAT_CAP_UAV_LOAD, "uav-load"); if (!test_options.filename) @@ -1987,14 +2001,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c state = STATE_REQUIRE; runner->minimum_shader_model = caps->minimum_shader_model; runner->maximum_shader_model = caps->maximum_shader_model; - runner->require_geometry_shader = false; - runner->require_float64 = false; - runner->require_int64 = false; - runner->require_rov = false; - runner->require_wave_ops = false; - runner->require_depth_bounds = false; - runner->require_clip_planes = false; - runner->require_point_size = false; + memset(runner->require_shader_caps, 0, sizeof(runner->require_shader_caps)); memset(runner->require_format_caps, 0, sizeof(runner->require_format_caps)); runner->compile_options = 0; test_action = TEST_ACTION_RUN; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 0ffce38f..58fb2dba 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 Zebediah Figura for CodeWeavers + * Copyright 2021-2024 Elizabeth Figura for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -135,6 +135,19 @@ enum format_cap FORMAT_CAP_UAV_LOAD = 0x00000001, }; +enum shader_cap +{ + SHADER_CAP_CLIP_PLANES, + SHADER_CAP_DEPTH_BOUNDS, + SHADER_CAP_FLOAT64, + SHADER_CAP_GEOMETRY_SHADER, + SHADER_CAP_INT64, + SHADER_CAP_POINT_SIZE, + SHADER_CAP_ROV, + SHADER_CAP_WAVE_OPS, + SHADER_CAP_COUNT, +}; + struct shader_runner_caps { const char *runner; @@ -142,14 +155,7 @@ struct shader_runner_caps size_t tag_count; enum shader_model minimum_shader_model; enum shader_model maximum_shader_model; - bool geometry_shader; - bool float64; - bool int64; - bool rov; - bool wave_ops; - bool depth_bounds; - bool clip_planes; - bool point_size; + bool shader_caps[SHADER_CAP_COUNT]; uint32_t format_caps[DXGI_FORMAT_COUNT]; }; @@ -158,9 +164,9 @@ static inline unsigned int shader_runner_caps_get_feature_flags(const struct sha { unsigned int flags = 0; - if (caps->int64) + if (caps->shader_caps[SHADER_CAP_INT64]) flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64; - if (caps->float64) + if (caps->shader_caps[SHADER_CAP_FLOAT64]) flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; return flags; @@ -182,14 +188,7 @@ struct shader_runner char *gs_source; enum shader_model minimum_shader_model; enum shader_model maximum_shader_model; - bool require_geometry_shader; - bool require_float64; - bool require_int64; - bool require_rov; - bool require_wave_ops; - bool require_depth_bounds; - bool require_clip_planes; - bool require_point_size; + bool require_shader_caps[SHADER_CAP_COUNT]; uint32_t require_format_caps[DXGI_FORMAT_COUNT]; bool last_render_failed; diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 0b492ab9..91d816ce 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -316,13 +316,13 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) 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); - runner->caps.float64 = doubles.DoublePrecisionFloatShaderOps; + runner->caps.shader_caps[SHADER_CAP_FLOAT64] = doubles.DoublePrecisionFloatShaderOps; hr = ID3D11Device_CheckFeatureSupport(runner->device, D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2)); ok(hr == S_OK, "Failed to check feature options2 support, hr %#lx.\n", hr); - runner->caps.rov = options2.ROVsSupported; + runner->caps.shader_caps[SHADER_CAP_ROV] = options2.ROVsSupported; for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i) { runner->caps.format_caps[formats[i]] = get_format_support(runner->device, formats[i]); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 9d50d36f..5d687f4a 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -1028,12 +1028,12 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, #endif runner->caps.minimum_shader_model = minimum_shader_model; runner->caps.maximum_shader_model = maximum_shader_model; - runner->caps.geometry_shader = true; - runner->caps.float64 = options.DoublePrecisionFloatShaderOps; - runner->caps.int64 = options1.Int64ShaderOps; - runner->caps.rov = options.ROVsSupported; - runner->caps.wave_ops = options1.WaveOps; - runner->caps.depth_bounds = options2.DepthBoundsTestSupported; + runner->caps.shader_caps[SHADER_CAP_DEPTH_BOUNDS] = options2.DepthBoundsTestSupported; + runner->caps.shader_caps[SHADER_CAP_FLOAT64] = options.DoublePrecisionFloatShaderOps; + runner->caps.shader_caps[SHADER_CAP_GEOMETRY_SHADER] = true; + runner->caps.shader_caps[SHADER_CAP_INT64] = options1.Int64ShaderOps; + runner->caps.shader_caps[SHADER_CAP_ROV] = options.ROVsSupported; + runner->caps.shader_caps[SHADER_CAP_WAVE_OPS] = options1.WaveOps; if (is_mvk_device(device)) { diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 549a5f37..4400f18f 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -152,8 +152,8 @@ static bool init_test_context(struct d3d9_shader_runner *runner) runner->caps.runner = "d3d9.dll"; runner->caps.minimum_shader_model = SHADER_MODEL_2_0; runner->caps.maximum_shader_model = SHADER_MODEL_3_0; - runner->caps.clip_planes = true; - runner->caps.point_size = true; + runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true; + runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true; return true; } diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index 86887d57..d84e89f7 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -131,11 +131,11 @@ static bool check_gl_extensions(struct gl_runner *runner) } if (check_gl_extension("GL_ARB_gpu_shader_fp64", count)) - runner->caps.float64 = true; + runner->caps.shader_caps[SHADER_CAP_FLOAT64] = true; if (check_gl_extension("GL_ARB_gpu_shader_int64", count)) - runner->caps.int64 = true; + runner->caps.shader_caps[SHADER_CAP_INT64] = true; if (check_gl_extension("GL_EXT_depth_bounds_test", count)) - runner->caps.depth_bounds = true; + runner->caps.shader_caps[SHADER_CAP_DEPTH_BOUNDS] = true; return true; } @@ -346,7 +346,7 @@ static bool gl_runner_init(struct gl_runner *runner, enum shading_language langu runner->caps.tag_count = runner->language == GLSL; runner->caps.minimum_shader_model = SHADER_MODEL_4_0; runner->caps.maximum_shader_model = SHADER_MODEL_5_1; - runner->caps.geometry_shader = true; + runner->caps.shader_caps[SHADER_CAP_GEOMETRY_SHADER] = true; glGetIntegerv(GL_NUM_EXTENSIONS, &extension_count); if (check_gl_extension("GL_ARB_internalformat_query2", extension_count)) diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 257cc383..51f17f50 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -365,7 +365,7 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour spirv_info.extensions = spirv_extensions; spirv_info.extension_count = 0; - if (runner->caps.rov) + if (runner->caps.shader_caps[SHADER_CAP_ROV]) spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_FRAGMENT_SHADER_INTERLOCK; if (runner->demote_to_helper_invocation) spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION; @@ -1433,7 +1433,7 @@ static bool check_device_extensions(struct vulkan_shader_runner *runner, { enabled_extensions->names[enabled_extensions->count++] = name; if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) - runner->caps.rov = true; + runner->caps.shader_caps[SHADER_CAP_ROV] = true; if (!strcmp(name, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) runner->demote_to_helper_invocation = true; if (!strcmp(name, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) @@ -1460,7 +1460,7 @@ static void get_physical_device_info(struct vulkan_shader_runner *runner, struct memset(info, 0, sizeof(*info)); info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - if (runner->caps.rov) + if (runner->caps.shader_caps[SHADER_CAP_ROV]) { info->features2.pNext = &info->interlock_features; info->interlock_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; @@ -1602,8 +1602,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) runner->caps.tag_count = ARRAY_SIZE(tags); } - runner->caps.clip_planes = true; - runner->caps.point_size = true; + runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true; + runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true; device_desc.pEnabledFeatures = &features; memset(&features, 0, sizeof(features)); @@ -1626,25 +1626,25 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) if (ret_features->geometryShader) { features.geometryShader = VK_TRUE; - runner->caps.geometry_shader = true; + runner->caps.shader_caps[SHADER_CAP_GEOMETRY_SHADER] = true; } if (ret_features->shaderFloat64) { features.shaderFloat64 = VK_TRUE; - runner->caps.float64 = true; + runner->caps.shader_caps[SHADER_CAP_FLOAT64] = true; } if (ret_features->shaderInt64) { features.shaderInt64 = VK_TRUE; - runner->caps.int64 = true; + runner->caps.shader_caps[SHADER_CAP_INT64] = true; } if (ret_features->depthBounds) { features.depthBounds = VK_TRUE; - runner->caps.depth_bounds = true; + runner->caps.shader_caps[SHADER_CAP_DEPTH_BOUNDS] = true; } if (device_info.interlock_features.fragmentShaderSampleInterlock @@ -1659,7 +1659,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) } else { - runner->caps.rov = false; + runner->caps.shader_caps[SHADER_CAP_ROV] = false; } if (device_info.demote_to_helper_invocation_features.shaderDemoteToHelperInvocation)