-- v9: 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.
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 a1065c8bc..6e232635d 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3246,6 +3246,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 dc3d96313..9ecab4a84 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6780,8 +6780,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 9ecab4a84..bbbba83de 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4511,7 +4511,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 for register id %u. " "The target environment does not support stencil export.", reg->idx[0].offset); } @@ -5518,6 +5518,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
--- libs/vkd3d/device.c | 1 + tests/hlsl/cast-64-bit.shader_test | 1 + tests/shader_runner.c | 5 +++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d12.c | 9 +++++++++ 5 files changed, 17 insertions(+)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 5c801ca46..32b51ac3d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1450,6 +1450,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
*device_extension_count = 0;
+ FIXME("Device name %s.\n", physical_device_info->properties2.properties.deviceName); vkd3d_trace_physical_device(physical_device, physical_device_info, vk_procs); vkd3d_trace_physical_device_features(physical_device_info); vkd3d_trace_physical_device_limits(physical_device_info); 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 bbbba83de..e59f22eda 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2387,6 +2387,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; @@ -2544,6 +2545,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; @@ -5520,9 +5525,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; }
@@ -7158,6 +7170,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);