-- v10: vkd3d-shader/spirv: Introduce a compiler feature flag for int64 capability. tests/shader-runner: Add 64-bit bitwise tests. tests/shader-runner: Add 64-bit arithmetic tests. tests/shader-runner: Introduce a 'float64' requirement directive. tests/shader-runner: Introduce an 'int64' requirement directive. vkd3d-shader/spirv: Emit an error if 64-bit integers are used. vkd3d-shader: Introduce an instruction flag to suppress masking of bitwise shift counts.
From: Conor McCarthy cmccarthy@codeweavers.com
DXIL does not use implicit masking of shift counts. --- libs/vkd3d-shader/d3d_asm.c | 6 ++++++ libs/vkd3d-shader/dxil.c | 6 ++++++ libs/vkd3d-shader/spirv.c | 4 ++-- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 82d1d71d9..d7b406acb 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -1577,6 +1577,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile shader_addline(buffer, "p"); break;
+ case VKD3DSIH_ISHL: + case VKD3DSIH_ISHR: + case VKD3DSIH_USHR: + if (ins->flags & VKD3DSI_SHIFT_UNMASKED) + shader_addline(buffer, "_unmasked"); + /* fall through */ default: shader_dump_precise_flags(compiler, ins->flags); break; diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 4175a1af0..602056e25 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3279,6 +3279,12 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco } else { + if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR) + { + /* DXC emits AND instructions where necessary to mask shift counts. Shift binops + * do not imply masking the shift as the TPF equivalents do. */ + ins->flags |= VKD3DSI_SHIFT_UNMASKED; + } instruction_dst_param_init_ssa_scalar(ins, sm6); } } diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index a60246fd4..945b9b484 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6764,8 +6764,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * Microsoft fxc will compile immediate constants larger than 5 bits. * Fixing up the constants would be more elegant, but the simplest way is * to let this handle constants too. */ - if (instruction->handler_idx == VKD3DSIH_ISHL || instruction->handler_idx == VKD3DSIH_ISHR - || instruction->handler_idx == VKD3DSIH_USHR) + if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->handler_idx == VKD3DSIH_ISHL + || instruction->handler_idx == VKD3DSIH_ISHR || instruction->handler_idx == VKD3DSIH_USHR)) { uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, vkd3d_write_mask_component_count(dst->write_mask), 0x1f); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 102d49a38..66c93f025 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -741,6 +741,7 @@ enum vkd3d_tessellator_domain #define VKD3DSI_RESINFO_UINT 0x2 #define VKD3DSI_SAMPLE_INFO_UINT 0x1 #define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1 +#define VKD3DSI_SHIFT_UNMASKED 0x1
#define VKD3DSI_PRECISE_X 0x100 #define VKD3DSI_PRECISE_Y 0x200
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 10 +++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 945b9b484..8e9705066 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4520,7 +4520,7 @@ static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *c VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT)) { FIXME("The target environment does not support stencil export.\n"); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, "Cannot export stencil reference value. " "The target environment does not support stencil export."); } @@ -5526,6 +5526,14 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler flags &= ~(VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS); }
+ if (flags & VKD3DSGF_ENABLE_INT64) + { + FIXME("Unsupported 64-bit integer ops.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, + "Support for 64-bit integers is not implemented."); + flags &= ~VKD3DSGF_ENABLE_INT64; + } + if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS)) FIXME("Unhandled global flags %#"PRIx64".\n", (uint64_t)flags); else diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 66c93f025..a69205f4e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -91,7 +91,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING = 2002, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003, - VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004, + VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE = 2004, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007,
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/hlsl/cast-64-bit.shader_test | 1 + tests/shader_runner.c | 5 +++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d12.c | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+)
diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test index 813cce108..eb320b0d4 100644 --- a/tests/hlsl/cast-64-bit.shader_test +++ b/tests/hlsl/cast-64-bit.shader_test @@ -20,6 +20,7 @@ probe all rgba (-4.5, 8.5, 2.0, 2.0)
[require] shader model >= 6.0 +int64
[pixel shader] uniform uint64_t2 l; diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 0e6104ce3..d592d2cdb 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -191,6 +191,10 @@ static void parse_require_directive(struct shader_runner *runner, const char *li runner->compile_options |= options[i].option; } } + else if (match_string(line, "int64", &line)) + { + runner->require_int64 = true; + } else { fatal_error("Unknown require directive '%s'.\n", line); @@ -1311,6 +1315,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o state = STATE_REQUIRE; runner->minimum_shader_model = minimum_shader_model; runner->maximum_shader_model = maximum_shader_model; + runner->require_int64 = false; runner->compile_options = 0; skip_tests = false; } diff --git a/tests/shader_runner.h b/tests/shader_runner.h index a4f0d2fd5..1caf4bbf5 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -122,6 +122,7 @@ struct shader_runner char *fx_source; enum shader_model minimum_shader_model; enum shader_model maximum_shader_model; + bool require_int64;
bool last_render_failed;
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index a05dfd059..857f3679a 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -52,6 +52,8 @@ struct d3d12_shader_runner ID3D12GraphicsCommandList *compute_list;
IDxcCompiler3 *dxc_compiler; + + D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; };
static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r) @@ -96,6 +98,16 @@ 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_int64 && !runner->options1.Int64ShaderOps) + 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) @@ -561,6 +573,7 @@ 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, @@ -602,6 +615,12 @@ 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);
+ 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); + if (maximum_shader_model >= SHADER_MODEL_6_0) + trace("Int64ShaderOps: %u.\n", runner.options1.Int64ShaderOps); + run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, minimum_shader_model, maximum_shader_model);
ID3D12GraphicsCommandList_Release(runner.compute_list);
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/hlsl/cast-64-bit.shader_test | 1 + tests/shader_runner.c | 5 +++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d12.c | 9 +++++++++ 4 files changed, 16 insertions(+)
diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test index eb320b0d4..f2a0468b3 100644 --- a/tests/hlsl/cast-64-bit.shader_test +++ b/tests/hlsl/cast-64-bit.shader_test @@ -1,5 +1,6 @@ [require] shader model >= 5.0 +float64
[pixel shader todo] uniform double2 d; diff --git a/tests/shader_runner.c b/tests/shader_runner.c index d592d2cdb..4847ec75b 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -191,6 +191,10 @@ static void parse_require_directive(struct shader_runner *runner, const char *li runner->compile_options |= options[i].option; } } + else if (match_string(line, "float64", &line)) + { + runner->require_float64 = true; + } else if (match_string(line, "int64", &line)) { runner->require_int64 = true; @@ -1315,6 +1319,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o state = STATE_REQUIRE; runner->minimum_shader_model = minimum_shader_model; runner->maximum_shader_model = maximum_shader_model; + runner->require_float64 = false; runner->require_int64 = false; runner->compile_options = 0; skip_tests = false; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 1caf4bbf5..163439477 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -122,6 +122,7 @@ struct shader_runner char *fx_source; enum shader_model minimum_shader_model; enum shader_model maximum_shader_model; + bool require_float64; bool require_int64;
bool last_render_failed; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 857f3679a..d6b80d9ea 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -53,6 +53,7 @@ struct d3d12_shader_runner
IDxcCompiler3 *dxc_compiler;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS options; D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; };
@@ -102,6 +103,9 @@ 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;
@@ -615,6 +619,11 @@ 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);
+ 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); + 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);
From: Conor McCarthy cmccarthy@codeweavers.com
--- .../hlsl/arithmetic-float-uniform.shader_test | 50 ++++++++++++ tests/hlsl/arithmetic-int-uniform.shader_test | 77 +++++++++++++++++++ 2 files changed, 127 insertions(+)
diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 4812d053a..75684cc60 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -90,3 +90,53 @@ float4 main() : SV_TARGET uniform 0 float4 1.0 0.0 0.0 0.0 draw quad probe all rgba (1e99, 1e99, 1e99, 1e99) + +[require] +shader model >= 5.0 +float64 + +[pixel shader todo] +uniform double2 a; + +float4 main() : SV_TARGET +{ + double x = a.x; + double y = a.y; + return float4(x + y, x - y, x * y, x / y); +} + +[test] +uniform 0 double2 7.5 -2.5 +todo(sm<6) draw quad +probe all rgba (5.0, 10.0, -18.75, -3.0) + +[pixel shader todo] +uniform double2 a; + +float4 main() : SV_TARGET +{ + double x = a.x; + double y = a.y; + return x * y; +} + +[test] +uniform 0 double2 3.0e-300 2.5e300 +todo(sm<6) draw quad +probe all rgba (7.5, 7.5, 7.5, 7.5) + +% Note: DXC does not support modulo on doubles. +[pixel shader todo] +uniform double2 a; + +float4 main() : SV_TARGET +{ + double x = a.x; + double y = a.y; + return x / y; +} + +[test] +uniform 0 double2 1.5e300 2.0e299 +todo(sm<6) draw quad +probe all rgba (7.5, 7.5, 7.5, 7.5) diff --git a/tests/hlsl/arithmetic-int-uniform.shader_test b/tests/hlsl/arithmetic-int-uniform.shader_test index 7f5cdaaa6..0463b27e7 100644 --- a/tests/hlsl/arithmetic-int-uniform.shader_test +++ b/tests/hlsl/arithmetic-int-uniform.shader_test @@ -119,3 +119,80 @@ uniform 0 float4 45.0 5.0 50.0 10.0 uniform 4 float4 3.0 8.0 2.0 5.0 draw quad probe all rgba (9.0, 5.0, 1.0, 3.0) + +[require] +shader model >= 6.0 +int64 + +[pixel shader] +uniform int64_t2 a; + +float4 main() : SV_TARGET +{ + int64_t x = a.x; + int64_t y = a.y; + return float4(x + y, x - y, x * (y >> 4), x / y); +} + +[test] +uniform 0 int64_t2 5000000000 16000000000 +todo draw quad +probe all rgba (21.0e9, -11.0e9, 5.0e18, 0.0) 1 + +[pixel shader] +uniform int64_t2 a; + +float4 main() : SV_TARGET +{ + int64_t x = a.x; + int64_t y = a.y; + return float4(x % y, +x, -x, y / x); +} + +[test] +uniform 0 int64_t2 5000000000 16000000000 +todo draw quad +probe all rgba (5.0e9, 5.0e9, -5.0e9, 3.0) + +[pixel shader] +uniform int64_t2 a; + +float4 main() : SV_TARGET +{ + int64_t x = a.x; + int64_t y = a.y; + return float4(x / y, -x / y, x / -y, -x / -y); +} + +[test] +uniform 0 int64_t2 42000000000 5000000000 +todo draw quad +probe all rgba (8.0, -8.0, -8.0, 8.0) + +[pixel shader] +uniform int64_t2 a; + +float4 main() : SV_TARGET +{ + int64_t x = a.x; + int64_t y = a.y; + return float4(x % y, -x % y, x % -y, -x % -y); +} + +[test] +uniform 0 int64_t2 42000000000 5000000000 +todo draw quad +probe all rgba (2.0e9, -2.0e9, 2.0e9, -2.0e9) + +[pixel shader] +uniform int64_t2 a; + +float4 main() : SV_TARGET +{ + return float4(abs(a), 0, 0); +} + +[test] +uniform 0 int64_t2 5000000000 -7000000000 +todo draw quad +probe all rgba (5.0, 7.0, 0.0, 10.0)
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/hlsl/bitwise.shader_test | 85 ++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+)
diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index 20a9db55f..6b4515e27 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -160,3 +160,88 @@ float4 main() : SV_TARGET [test] draw quad probe all rgba (0.0, 1.0, 1.0, 0.0) + + +[require] +shader model >= 6.0 +int64 + +[pixel shader] +int64_t2 a; +int2 s; + +float4 main() : sv_target +{ + int64_t x = a.x; + int64_t y = a.y; + int z = s.x; + int w = s.y; + + return float4(x >> y, x >> -y, x >> z, x >> w); +} + +[test] +uniform 0 int64_t2 9223372036854775807 -1 +uniform 4 int4 34 66 0 0 +todo draw quad +probe all rgba (0.0, 4.611686018e18, 536870912.0, 2.305843009e18) 1 +uniform 0 int64_t2 -1 -1 +uniform 4 int4 34 66 0 0 +todo draw quad +probe all rgba (-1.0, -1.0, -1.0, -1.0) 1 + +[pixel shader] +uint64_t2 a; +uint2 s; + +float4 main() : sv_target +{ + uint64_t x = a.x; + uint64_t y = a.y; + uint z = s.x; + uint w = s.y; + + return float4(x >> y, x >> -y, x >> z, x >> w); +} + +[test] +uniform 0 uint64_t2 0xffffffffffffffff 1 +uniform 4 uint4 34 66 0 0 +todo draw quad +probe all rgba (9.223372036e18, 1.0, 1073741823.0, 4.611686018e18) 1 + +[pixel shader] +uint64_t2 a; +uint2 s; + +float4 main() : sv_target +{ + uint64_t x = a.x; + uint64_t y = a.y; + uint z = s.x; + uint w = s.y; + + return float4(x << y, x << -y, x << z, x << w); +} + +[test] +uniform 0 uint64_t2 0x83 1 +uniform 4 uint4 34 66 0 0 +todo draw quad +probe all rgba (262.0, 9.223372036e18, 2250562863104.0, 524.0) 1 + +[pixel shader] +uint64_t2 a; + +float4 main() : sv_target +{ + uint64_t x = a.x; + uint64_t y = a.y; + + return float4(x ^ y, x & y, x | y, ~x); +} + +[test] +uniform 0 uint64_t2 0x300000000 0x500000000 +todo draw quad +probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1
From: Conor McCarthy cmccarthy@codeweavers.com
--- include/vkd3d_shader.h | 18 ++++++++++++++++++ libs/vkd3d-shader/spirv.c | 25 ++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 290f9085d..a6bf89641 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -196,6 +196,14 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN), };
+/** Advertises feature availability. \since 1.11 */ +enum vkd3d_shader_compile_option_feature_flags +{ + VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS), +}; + enum vkd3d_shader_compile_option_name { /** @@ -253,6 +261,16 @@ enum vkd3d_shader_compile_option_name * \since 1.10 */ VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009, + /** + * This option specifies the shader features available in the target + * environment. These are not extensions, i.e. they are always supported + * by the driver, but may not be supported by the available hardware. + * + * \a value is a member of enum vkd3d_shader_compile_option_feature_flags. + * + * \since 1.11 + */ + VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 8e9705066..62ee1bef3 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2396,6 +2396,7 @@ struct spirv_compiler struct vkd3d_shader_spec_constant *spec_constants; size_t spec_constants_size; enum vkd3d_shader_compile_option_formatting_flags formatting; + enum vkd3d_shader_compile_option_feature_flags features; bool write_tess_geom_point_size;
struct vkd3d_string_buffer_cache string_buffers; @@ -2553,6 +2554,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name); break;
+ case VKD3D_SHADER_COMPILE_OPTION_FEATURE: + compiler->features = option->value; + break; + default: WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value); break; @@ -5528,9 +5533,16 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler
if (flags & VKD3DSGF_ENABLE_INT64) { - FIXME("Unsupported 64-bit integer ops.\n"); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, - "Support for 64-bit integers is not implemented."); + if (compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64) + { + vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityInt64); + } + else + { + WARN("Unsupported 64-bit integer ops.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, + "The target environment does not support 64-bit integers."); + } flags &= ~VKD3DSGF_ENABLE_INT64; }
@@ -7147,6 +7159,13 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, div_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv; mod_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod;
+ if (dst[0].reg.data_type == VKD3D_DATA_UINT64 || dst[1].reg.data_type == VKD3D_DATA_UINT64) + { + FIXME("Unsupported 64-bit result.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, + "Bool cast to 64-bit integer is not supported."); + } + if (dst[0].reg.type != VKD3DSPR_NULL) { component_count = vkd3d_write_mask_component_count(dst[0].write_mask);
Are we going to have separate error codes for each missing feature? Or could we e.g. have VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE? I suppose we have precedent in VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED and VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED, but in theory we could e.g. decide to rename VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED to VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE and then use that going forward.
How much do we care about API stability? Maybe we should retain the old name as an alias?
This is not the first test to use doubles, but the preceding commit makes the issue here perhaps more obvious: doubles aren't universally supported. Direct3D 12 has D3D12_FEATURE_DATA_D3D12_OPTIONS.DoublePrecisionFloatShaderOps, Direct3D 11 has D3D11_FEATURE_DATA_DOUBLES.DoublePrecisionFloatShaderOps, Vulkan has VkPhysicalDeviceFeatures.shaderFloat64, and OpenGL has GL_ARB_gpu_shader_fp64.
Right now the code only checks in Vulkan, maybe we should check in the other backends too.
Are we going to have separate error codes for each missing feature? Or could we e.g. have VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE? I suppose we have precedent in VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED and VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED, but in theory we could e.g. decide to rename VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED to VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE and then use that going forward.
How much do we care about API stability? Maybe we should retain the old name as an alias?
The error code is externally visible, but that's not true for the name of the enum element; that's internal.
This is not the first test to use doubles, but the preceding commit makes the issue here perhaps more obvious: doubles aren't universally supported. Direct3D 12 has D3D12_FEATURE_DATA_D3D12_OPTIONS.DoublePrecisionFloatShaderOps, Direct3D 11 has D3D11_FEATURE_DATA_DOUBLES.DoublePrecisionFloatShaderOps, Vulkan has VkPhysicalDeviceFeatures.shaderFloat64, and OpenGL has GL_ARB_gpu_shader_fp64.
Right now the code only checks in Vulkan, maybe we should check in the other backends too.
Yes, we should. I don't mind doing that in a separate MR though, as long as it actually happens.
This merge request was approved by Henri Verbeet.