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)