From b701f8d39333c539b06765e615b3e4397ef0fcaf Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Thu, 1 Aug 2024 19:13:31 -0400 Subject: [PATCH] tests/shader_runner: Explicitly require UAV load support. The used UAV formats are explicitly added in the [require] section of every test that uses them. Some of these tests were failing on Intel UHD graphics 770 because of missing support for additional UAV load types, explicitly requiring these formats allows these tests to be skipped. --- tests/hlsl/compute.shader_test | 1 + tests/hlsl/coverage.shader_test | 1 + tests/hlsl/discard.shader_test | 1 + tests/hlsl/numthreads.shader_test | 4 + tests/hlsl/sm6-uav-rwtexture.shader_test | 4 +- tests/hlsl/static-initializer.shader_test | 1 + tests/hlsl/uav-atomics.shader_test | 2 + tests/hlsl/uav-counter.shader_test | 1 - tests/hlsl/uav-load.shader_test | 1 + tests/hlsl/uav-rwbuffer.shader_test | 4 + tests/hlsl/uav-rwtexture.shader_test | 2 + tests/hlsl/wave-ops-float.shader_test | 2 + tests/hlsl/wave-ops-int.shader_test | 1 + tests/hlsl/wave-ops-uint.shader_test | 1 + tests/hlsl/wave-reconvergence.shader_test | 1 + tests/shader_runner.c | 63 ++++++++++++++- tests/shader_runner.h | 9 +++ tests/shader_runner_d3d11.c | 45 ++++++++++- tests/shader_runner_d3d12.c | 43 ++++++++++ tests/shader_runner_gl.c | 96 +++++++++++++++-------- tests/shader_runner_vulkan.c | 41 ++++++++++ 21 files changed, 289 insertions(+), 35 deletions(-) diff --git a/tests/hlsl/compute.shader_test b/tests/hlsl/compute.shader_test index 379bd12a..bd378e93 100644 --- a/tests/hlsl/compute.shader_test +++ b/tests/hlsl/compute.shader_test @@ -1,5 +1,6 @@ [require] shader model >= 5.0 +format r32-float uav-load [uav 0] format r32-float diff --git a/tests/hlsl/coverage.shader_test b/tests/hlsl/coverage.shader_test index c7b3c01a..f09476c4 100644 --- a/tests/hlsl/coverage.shader_test +++ b/tests/hlsl/coverage.shader_test @@ -24,6 +24,7 @@ probe (0, 0) rgba (0.25, 0.25, 0.25, 0.25) [require] shader model >= 5.0 +format r32-uint uav-load [uav 1] format r32-uint diff --git a/tests/hlsl/discard.shader_test b/tests/hlsl/discard.shader_test index 0da6d256..633bcb9e 100644 --- a/tests/hlsl/discard.shader_test +++ b/tests/hlsl/discard.shader_test @@ -42,6 +42,7 @@ probe (3, 1) rgba (1, 0, 0, 1) [require] shader model >= 5.0 +format r32-float uav-load [uav 1] format r32-float diff --git a/tests/hlsl/numthreads.shader_test b/tests/hlsl/numthreads.shader_test index 89b979c5..3f1914d9 100644 --- a/tests/hlsl/numthreads.shader_test +++ b/tests/hlsl/numthreads.shader_test @@ -164,6 +164,10 @@ void func() {} [numthreads(1, 1, 1)] void main() { func(); } +[require] +shader model >= 5.0 +format r32-float uav-load + [uav 0] format r32-float size (2d, 2, 2) diff --git a/tests/hlsl/sm6-uav-rwtexture.shader_test b/tests/hlsl/sm6-uav-rwtexture.shader_test index 7f8c88e3..49d5137b 100644 --- a/tests/hlsl/sm6-uav-rwtexture.shader_test +++ b/tests/hlsl/sm6-uav-rwtexture.shader_test @@ -1,5 +1,6 @@ [require] shader model >= 6.0 +format r32g32b32a32-float uav-load [uav 0] format r32-float @@ -17,7 +18,8 @@ RWTexture2D u : register(u1); float4 main() : sv_target { - /* Unlike SM < 6.0, all four components are not required to be written in a single statement. */ + /* Unlike SM < 6.0, all four components are not required to be written in a single statement. + * but this requires Typed UAV Load Additional Formats. */ u[uint2(0, 0)].xy = float2(1, 2); u[uint2(0, 0)].zw = float2(3, 4); return 0; diff --git a/tests/hlsl/static-initializer.shader_test b/tests/hlsl/static-initializer.shader_test index 54934847..897510e8 100644 --- a/tests/hlsl/static-initializer.shader_test +++ b/tests/hlsl/static-initializer.shader_test @@ -169,6 +169,7 @@ probe (0, 0) rgba (1, 2, 3, 4) [require] shader model >= 5.0 +format r32-float uav-load [uav 1] diff --git a/tests/hlsl/uav-atomics.shader_test b/tests/hlsl/uav-atomics.shader_test index 860351eb..2c073ce9 100644 --- a/tests/hlsl/uav-atomics.shader_test +++ b/tests/hlsl/uav-atomics.shader_test @@ -1,5 +1,7 @@ [require] shader model >= 5.0 +format r32-sint uav-load +format r32-uint uav-load [uav 1] format r32-uint diff --git a/tests/hlsl/uav-counter.shader_test b/tests/hlsl/uav-counter.shader_test index 2e5bf55d..739d7060 100644 --- a/tests/hlsl/uav-counter.shader_test +++ b/tests/hlsl/uav-counter.shader_test @@ -18,7 +18,6 @@ void main() todo(sm<6) dispatch 3 1 1 probe uav 1 (0) rui (12) - [uav 1] size (counter_buffer, 1) 0 diff --git a/tests/hlsl/uav-load.shader_test b/tests/hlsl/uav-load.shader_test index 85857780..6d0a9e7d 100644 --- a/tests/hlsl/uav-load.shader_test +++ b/tests/hlsl/uav-load.shader_test @@ -1,5 +1,6 @@ [require] shader model >= 5.0 +format r32-float uav-load [uav 0] format r32-float diff --git a/tests/hlsl/uav-rwbuffer.shader_test b/tests/hlsl/uav-rwbuffer.shader_test index d699effc..edbc25a7 100644 --- a/tests/hlsl/uav-rwbuffer.shader_test +++ b/tests/hlsl/uav-rwbuffer.shader_test @@ -164,6 +164,10 @@ float4 main() : sv_target1 return 0; } + +[require] +shader model >= 5.0 + [uav 1] format r32g32b32a32-sint size (buffer, 2) diff --git a/tests/hlsl/uav-rwtexture.shader_test b/tests/hlsl/uav-rwtexture.shader_test index 7bdd563c..f22161c0 100644 --- a/tests/hlsl/uav-rwtexture.shader_test +++ b/tests/hlsl/uav-rwtexture.shader_test @@ -1,6 +1,8 @@ [require] shader model >= 5.0 shader model < 6.0 +format r32-float uav-load +format r32g32b32a32-float uav-load [pixel shader fail] RWTexture2D u; diff --git a/tests/hlsl/wave-ops-float.shader_test b/tests/hlsl/wave-ops-float.shader_test index a4e48390..a4b30005 100644 --- a/tests/hlsl/wave-ops-float.shader_test +++ b/tests/hlsl/wave-ops-float.shader_test @@ -1,6 +1,8 @@ [require] shader model >= 6.0 wave ops +format r32g32b32a32-float uav-load +format r32g32b32a32-uint uav-load [uav 0] format r32g32b32a32-float diff --git a/tests/hlsl/wave-ops-int.shader_test b/tests/hlsl/wave-ops-int.shader_test index b3dd51c0..7102db1b 100644 --- a/tests/hlsl/wave-ops-int.shader_test +++ b/tests/hlsl/wave-ops-int.shader_test @@ -1,6 +1,7 @@ [require] shader model >= 6.0 wave ops +format r32g32b32a32-sint uav-load [uav 0] format r32g32b32a32-sint diff --git a/tests/hlsl/wave-ops-uint.shader_test b/tests/hlsl/wave-ops-uint.shader_test index f2b7dd9c..9047f52b 100644 --- a/tests/hlsl/wave-ops-uint.shader_test +++ b/tests/hlsl/wave-ops-uint.shader_test @@ -1,6 +1,7 @@ [require] shader model >= 6.0 wave ops +format r32-uint uav-load [uav 0] format r32-uint diff --git a/tests/hlsl/wave-reconvergence.shader_test b/tests/hlsl/wave-reconvergence.shader_test index a5a4c3f6..727c7cde 100644 --- a/tests/hlsl/wave-reconvergence.shader_test +++ b/tests/hlsl/wave-reconvergence.shader_test @@ -1,5 +1,6 @@ [require] shader model >= 6.0 +format r32-uint uav-load [uav 0] format r32-uint diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 7ee616fc..60d7f8ce 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -302,6 +302,7 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t {"r32-sint", TEXTURE_DATA_SINT, 4, DXGI_FORMAT_R32_SINT}, {"r32-uint", TEXTURE_DATA_UINT, 4, DXGI_FORMAT_R32_UINT}, {"r32-typeless", TEXTURE_DATA_UINT, 4, DXGI_FORMAT_R32_TYPELESS}, + {"unknown", TEXTURE_DATA_UINT, 0, DXGI_FORMAT_UNKNOWN}, }; unsigned int i; @@ -311,7 +312,8 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t { if (data_type) *data_type = formats[i].data_type; - *texel_size = formats[i].texel_size; + if (texel_size) + *texel_size = formats[i].texel_size; if (is_shadow) *is_shadow = formats[i].is_shadow; return formats[i].format; @@ -372,6 +374,18 @@ static void parse_require_directive(struct shader_runner *runner, const char *li runner->compile_options |= options[i].option; } } + else if (match_string(line, "format", &line)) + { + DXGI_FORMAT format = parse_format(line, NULL, NULL, NULL, &line); + + while (line[0] != '\0') + { + if (match_string(line, "uav-load", &line)) + runner->require_format_caps[format] |= FORMAT_CAP_UAV_LOAD; + else + fatal_error("Unknown format cap '%s'.\n", line); + } + } else if (match_string(line, "float64", &line)) { runner->require_float64 = true; @@ -1571,6 +1585,8 @@ static enum parse_state read_shader_directive(struct shader_runner *runner, enum static bool check_capabilities(const struct shader_runner *runner, const struct shader_runner_caps *caps) { + unsigned int i; + if (runner->require_float64 && !caps->float64) return false; if (runner->require_int64 && !caps->int64) @@ -1580,6 +1596,11 @@ static bool check_capabilities(const struct shader_runner *runner, const struct if (runner->require_wave_ops && !caps->wave_ops) return false; + for (i = 0; i < ARRAY_SIZE(runner->require_format_caps); ++i) + { + if (runner->require_format_caps[i] & ~caps->format_caps[i]) + return false; + } return true; } @@ -1614,6 +1635,44 @@ static void trace_tags(const struct shader_runner_caps *caps) trace("%s.\n", tags); } +static void trace_format_cap(const struct shader_runner_caps *caps, enum format_cap cap, const char *cap_name) +{ + bool show_none = true; + char buffer[80], *p; + size_t rem; + int rc; + + p = buffer; + rem = ARRAY_SIZE(buffer); + rc = snprintf(p, rem, "%10s:", cap_name); + p += rc; + rem -= rc; + + for (unsigned int i = 0; i < ARRAY_SIZE(caps->format_caps); ++i) + { + if (caps->format_caps[i] & cap) + { + rc = snprintf(p, rem, " 0x%x", i); + if (!(rc >= 0 && (size_t)rc < rem)) + { + *p = 0; + trace("%s\n", buffer); + + p = buffer; + rem = ARRAY_SIZE(buffer); + rc = snprintf(p, rem, " "); + --i; + } + p += rc; + rem -= rc; + show_none = false; + } + } + if (show_none) + snprintf(p, rem, " (none)"); + trace("%s.\n", buffer); +} + static void update_line_number_context(const char *testname, unsigned int line_number) { vkd3d_test_pop_context(); @@ -1651,6 +1710,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c trace(" int64: %u.\n", caps->int64); trace(" rov: %u.\n", caps->rov); trace(" wave_ops: %u.\n", caps->wave_ops); + trace_format_cap(caps, FORMAT_CAP_UAV_LOAD, "uav-load"); if (!test_options.filename) fatal_error("No filename specified.\n"); @@ -1909,6 +1969,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c runner->require_int64 = false; runner->require_rov = false; runner->require_wave_ops = false; + 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 14f691aa..c4051bee 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -128,6 +128,12 @@ struct input_element #define MAX_RESOURCES 32 #define MAX_SAMPLERS 32 +#define DXGI_FORMAT_COUNT (DXGI_FORMAT_B4G4R4A4_UNORM + 1) + +enum format_cap +{ + FORMAT_CAP_UAV_LOAD = 0x00000001, +}; struct shader_runner_caps { @@ -140,6 +146,8 @@ struct shader_runner_caps bool int64; bool rov; bool wave_ops; + + uint32_t format_caps[DXGI_FORMAT_COUNT]; }; static inline unsigned int shader_runner_caps_get_feature_flags(const struct shader_runner_caps *caps) @@ -174,6 +182,7 @@ struct shader_runner bool require_int64; bool require_rov; bool require_wave_ops; + 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 00ac853c..0b492ab9 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -253,6 +253,22 @@ static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window) return swapchain; } +static bool get_format_support(ID3D11Device *device, enum DXGI_FORMAT format) +{ + D3D11_FEATURE_DATA_FORMAT_SUPPORT2 format_support2 = {.InFormat = format}; + uint32_t ret = 0; + HRESULT hr; + + hr = ID3D11Device_CheckFeatureSupport(device, D3D11_FEATURE_FORMAT_SUPPORT2, + &format_support2, sizeof(format_support2)); + ok(hr == S_OK, "Failed to query format support2, hr %#lx.\n", hr); + + if (format_support2.OutFormatSupport2 & D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD) + ret |= FORMAT_CAP_UAV_LOAD; + + return ret; +} + static BOOL init_test_context(struct d3d11_shader_runner *runner) { D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2 = {0}; @@ -263,6 +279,28 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) HRESULT hr; RECT rect; + static const enum DXGI_FORMAT formats[] = + { + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_SINT, + }; + memset(runner, 0, sizeof(*runner)); if (!(runner->device = create_device())) @@ -282,8 +320,13 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) hr = ID3D11Device_CheckFeatureSupport(runner->device, D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2)); - ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Failed to check feature options2 support, hr %#lx.\n", hr); + runner->caps.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]); + } rt_width = RENDER_TARGET_WIDTH; rt_height = RENDER_TARGET_HEIGHT; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 7c80a3a4..d2438946 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -767,6 +767,22 @@ static const struct shader_runner_ops d3d12_runner_ops = .release_readback = d3d12_runner_release_readback, }; +static uint32_t get_format_support(ID3D12Device *device, enum DXGI_FORMAT format) +{ + D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = {.Format = format}; + uint32_t ret = 0; + HRESULT hr; + + hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_SUPPORT, + &format_support, sizeof(format_support)); + ok(hr == S_OK, "Failed to query format support, hr %#x.\n", hr); + + if (format_support.Support2 & D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD) + ret |= FORMAT_CAP_UAV_LOAD; + + return ret; +} + static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, enum shader_model minimum_shader_model, enum shader_model maximum_shader_model) { @@ -775,6 +791,28 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, D3D12_FEATURE_DATA_D3D12_OPTIONS options; HRESULT hr; + static const enum DXGI_FORMAT formats[] = + { + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_SINT, + }; + 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); hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)); @@ -791,6 +829,11 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, runner->caps.int64 = options1.Int64ShaderOps; runner->caps.rov = options.ROVsSupported; runner->caps.wave_ops = options1.WaveOps; + + for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i) + { + runner->caps.format_caps[formats[i]] = get_format_support(device, formats[i]); + } } static bool device_supports_shader_model_6_0(ID3D12Device *device) diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index f0c66e2f..752cf248 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -159,15 +159,59 @@ static bool check_egl_client_extension(const char *extension) return false; } +static const struct format_info *get_format_info(enum DXGI_FORMAT format, bool is_shadow) +{ + size_t i; + + static const struct format_info format_info[] = + { + {DXGI_FORMAT_UNKNOWN, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, + {DXGI_FORMAT_R32G32B32A32_FLOAT, 4, false, false, GL_RGBA32F, GL_RGBA, GL_FLOAT}, + {DXGI_FORMAT_R32G32B32A32_UINT, 4, true, false, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, + {DXGI_FORMAT_R32G32B32A32_SINT, 4, true, false, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, + {DXGI_FORMAT_R32G32_FLOAT, 2, false, false, GL_RG32F, GL_RG, GL_FLOAT}, + {DXGI_FORMAT_R32G32_UINT, 2, true, false, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, + {DXGI_FORMAT_R32G32_SINT, 2, true, false, GL_RG32I, GL_RG_INTEGER, GL_INT}, + {DXGI_FORMAT_R32_FLOAT, 1, false, false, GL_R32F, GL_RED, GL_FLOAT}, + {DXGI_FORMAT_R32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, + {DXGI_FORMAT_D32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, + {DXGI_FORMAT_R32_UINT, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, + {DXGI_FORMAT_R32_SINT, 1, true, false, GL_R32I, GL_RED_INTEGER, GL_INT}, + {DXGI_FORMAT_R32_TYPELESS, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, + }; + + for (i = 0; i < ARRAY_SIZE(format_info); ++i) + { + if (format_info[i].f == format && format_info[i].is_shadow == is_shadow) + return &format_info[i]; + } + + fatal_error("Failed to find format info for format %#x.\n", format); +} + +static uint32_t get_format_support(struct gl_runner *runner, enum DXGI_FORMAT format) +{ + GLenum gl_format = get_format_info(format, false)->internal_format; + uint32_t ret = 0; + GLint support; + + /* TODO: Probably check for more targets instead of just GL_TEXTURE_2D. */ + glGetInternalformativ(GL_TEXTURE_2D, gl_format, GL_SHADER_IMAGE_LOAD, 1, &support); + if (support != GL_NONE) + ret |= FORMAT_CAP_UAV_LOAD; + + return ret; +} + static bool gl_runner_init(struct gl_runner *runner, enum shading_language language) { PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT; const char *glsl_version = NULL; + EGLint count, extension_count; EGLDeviceEXT *devices; EGLContext context; EGLDisplay display; EGLBoolean ret; - EGLint count; GLuint vao; static const char *const tags[] = @@ -184,6 +228,17 @@ static bool gl_runner_init(struct gl_runner *runner, enum shading_language langu EGL_NONE, }; + static const enum DXGI_FORMAT formats[] = + { + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_SINT, + }; + memset(runner, 0, sizeof(*runner)); runner->language = language; @@ -267,6 +322,15 @@ static bool gl_runner_init(struct gl_runner *runner, enum shading_language langu runner->caps.minimum_shader_model = SHADER_MODEL_4_0; runner->caps.maximum_shader_model = SHADER_MODEL_5_1; + glGetIntegerv(GL_NUM_EXTENSIONS, &extension_count); + if (check_gl_extension("GL_ARB_internalformat_query2", extension_count)) + { + for (unsigned int j = 0; j < ARRAY_SIZE(formats); ++j) + { + runner->caps.format_caps[formats[j]] = get_format_support(runner, formats[j]); + } + } + trace("Using device %u.\n", i); runner->display = display; runner->context = context; @@ -323,36 +387,6 @@ static void gl_runner_cleanup(struct gl_runner *runner) ok(ret, "Failed to terminate EGL display connection.\n"); } -static const struct format_info *get_format_info(enum DXGI_FORMAT format, bool is_shadow) -{ - size_t i; - - static const struct format_info format_info[] = - { - {DXGI_FORMAT_UNKNOWN, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, - {DXGI_FORMAT_R32G32B32A32_FLOAT, 4, false, false, GL_RGBA32F, GL_RGBA, GL_FLOAT}, - {DXGI_FORMAT_R32G32B32A32_UINT, 4, true, false, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, - {DXGI_FORMAT_R32G32B32A32_SINT, 4, true, false, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, - {DXGI_FORMAT_R32G32_FLOAT, 2, false, false, GL_RG32F, GL_RG, GL_FLOAT}, - {DXGI_FORMAT_R32G32_UINT, 2, true, false, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, - {DXGI_FORMAT_R32G32_SINT, 2, true, false, GL_RG32I, GL_RG_INTEGER, GL_INT}, - {DXGI_FORMAT_R32_FLOAT, 1, false, false, GL_R32F, GL_RED, GL_FLOAT}, - {DXGI_FORMAT_R32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, - {DXGI_FORMAT_D32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, - {DXGI_FORMAT_R32_UINT, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, - {DXGI_FORMAT_R32_SINT, 1, true, false, GL_R32I, GL_RED_INTEGER, GL_INT}, - {DXGI_FORMAT_R32_TYPELESS, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, - }; - - for (i = 0; i < ARRAY_SIZE(format_info); ++i) - { - if (format_info[i].f == format && format_info[i].is_shadow == is_shadow) - return &format_info[i]; - } - - fatal_error("Failed to find format info for format %#x.\n", format); -} - static bool init_resource_2d(struct gl_resource *resource, const struct resource_params *params) { GLenum target = params->desc.sample_count > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 708a9502..18864732 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -1664,6 +1664,18 @@ static void get_physical_device_info(struct vulkan_shader_runner *runner, struct VK_CALL(vkGetPhysicalDeviceFeatures(runner->phys_device, &info->features2.features)); } +static uint32_t get_format_support(const struct vulkan_shader_runner *runner, enum DXGI_FORMAT format) +{ + VkFormatProperties properties; + uint32_t ret = 0; + + VK_CALL(vkGetPhysicalDeviceFormatProperties(runner->phys_device, vkd3d_get_vk_format(format), &properties)); + if ((properties.linearTilingFeatures | properties.optimalTilingFeatures) & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) + ret |= FORMAT_CAP_UAV_LOAD; + + return ret; +} + static bool init_vulkan_runner(struct vulkan_shader_runner *runner) { VkDescriptorPoolCreateInfo descriptor_pool_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; @@ -1686,6 +1698,28 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) void *libvulkan; VkResult vr; + static const enum DXGI_FORMAT formats[] = + { + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_SINT, + }; + if (!(libvulkan = vkd3d_dlopen(SONAME_LIBVULKAN))) { skip("Failed to load %s: %s.\n", SONAME_LIBVULKAN, vkd3d_dlerror()); @@ -1812,6 +1846,13 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) runner->demote_to_helper_invocation = false; } + if (device_info.features2.features.shaderStorageImageReadWithoutFormat) + runner->caps.format_caps[DXGI_FORMAT_UNKNOWN] |= FORMAT_CAP_UAV_LOAD; + for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i) + { + runner->caps.format_caps[formats[i]] = get_format_support(runner, formats[i]); + } + vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device)); free(enabled_extensions.names); if (vr)