Goes atop !489. The last 8 commits belong to this MR. Many of these patches are small, but the series can be split further if necessary.
-- v2: vkd3d-shader/spirv: Handle ITOI and UTOU in spirv_compiler_map_alu_instruction(). vkd3d-shader/spirv: Support UINT64 source in spirv_compiler_emit_bool_cast(). vkd3d-shader/spirv: Support 64-bit sources in spirv_compiler_emit_int_div(). vkd3d-shader/spirv: Introduce a UINT64 component type. vkd3d-shader/spirv: Introduce a data_type_is_64_bit() helper function. vkd3d-shader/spirv: Use data_type_is_integer() in spirv_compiler_emit_neg(). vkd3d: Pass int64 capability info to vkd3d-shader. 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 'shader int64' requirement directive. vkd3d-shader/spirv: Emit an error if 64-bit integers are used. vkd3d-shader/dxil: 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 beb9ae574..50afc91a0 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3167,6 +3167,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 2197b74dd..10d5d8b1c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6712,8 +6712,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 d3989672b..faea815f1 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -740,6 +740,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 | 8 ++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 9 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 10d5d8b1c..8a8163eb6 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5441,6 +5441,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_INT64_UNSUPPORTED, + "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 faea815f1..fe57cc6cf 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -96,6 +96,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED = 2008, + VKD3D_SHADER_ERROR_SPV_INT64_UNSUPPORTED = 2009,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/shader_runner.c | 5 +++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d12.c | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 0e6104ce3..1670fc26c 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, "shader 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
--- .../hlsl/arithmetic-float-uniform.shader_test | 49 ++++++++++++ tests/hlsl/arithmetic-int-uniform.shader_test | 77 +++++++++++++++++++ 2 files changed, 126 insertions(+)
diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 4812d053a..bf6f92e29 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -90,3 +90,52 @@ 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 + +[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..f27aff037 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 +shader 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..095c9f77d 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 +shader 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 | 10 ++++++++++ libs/vkd3d-shader/spirv.c | 25 ++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index c43b619dc..aa05f81c5 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -195,6 +195,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 { /** @@ -252,6 +260,8 @@ enum vkd3d_shader_compile_option_name * \since 1.10 */ VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009, + /** \a value is a member of enum vkd3d_shader_compile_option_feature_flags. */ + 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 8a8163eb6..f81876c06 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2376,6 +2376,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; @@ -2533,6 +2534,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; @@ -5443,9 +5448,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_INT64_UNSUPPORTED, - "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_INT64_UNSUPPORTED, + "The target environment does not support 64-bit integers."); + } flags &= ~VKD3DSGF_ENABLE_INT64; }
@@ -7090,6 +7102,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_INT64_UNSUPPORTED, + "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);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d/state.c | 2 ++ tests/hlsl/bitwise.shader_test | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 6665a1fd6..1f8c3637d 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -2145,6 +2145,8 @@ static HRESULT create_shader_stage(struct d3d12_device *device, {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_9}, {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, + {VKD3D_SHADER_COMPILE_OPTION_FEATURE, device->feature_options1.Int64ShaderOps + ? VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 : 0}, };
stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index 095c9f77d..6dd89eebe 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -243,5 +243,5 @@ float4 main() : sv_target
[test] uniform 0 uint64_t2 0x300000000 0x500000000 -todo draw quad -probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1 +draw quad +todo probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index f81876c06..cd07b6188 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3909,7 +3909,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); - else if (reg->data_type == VKD3D_DATA_INT || reg->data_type == VKD3D_DATA_UINT) + else if (data_type_is_integer(reg->data_type)) return vkd3d_spirv_build_op_snegate(builder, type_id, val_id);
FIXME("Unhandled data type %#x.\n", reg->data_type);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 4 ++-- libs/vkd3d-shader/vkd3d_shader_private.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index cd07b6188..18030b82c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3841,7 +3841,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE); spirv_compiler_emit_dereference_register(compiler, reg, ®_info);
- write_mask32 = (reg->data_type == VKD3D_DATA_DOUBLE) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask; + write_mask32 = data_type_is_64_bit(reg->data_type) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask;
/* Intermediate value (no storage class). */ if (reg_info.storage_class == SpvStorageClassMax) @@ -4057,7 +4057,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, component_type = vkd3d_component_type_from_data_type(reg->data_type); if (component_type != reg_info.component_type) { - if (reg->data_type == VKD3D_DATA_DOUBLE) + if (data_type_is_64_bit(reg->data_type)) src_write_mask = vkd3d_write_mask_32_from_64(write_mask); type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, vkd3d_write_mask_component_count(src_write_mask)); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index fe57cc6cf..9de12e866 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -619,6 +619,17 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type) return data_type == VKD3D_DATA_BOOL; }
+static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) +{ + switch (data_type) + { + case VKD3D_DATA_DOUBLE: + return true; + default: + return false; + } +} + enum vsir_dimension { VSIR_DIMENSION_NONE,
From: Conor McCarthy cmccarthy@codeweavers.com
--- include/vkd3d_shader.h | 2 ++ libs/vkd3d-shader/spirv.c | 6 +++++- libs/vkd3d-shader/vkd3d_shader_private.h | 3 +++ tests/hlsl/bitwise.shader_test | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index aa05f81c5..5b47ba789 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -1560,6 +1560,8 @@ enum vkd3d_shader_component_type VKD3D_SHADER_COMPONENT_BOOL = 0x4, /** 64-bit IEEE floating-point. */ VKD3D_SHADER_COMPONENT_DOUBLE = 0x5, + /** 64-bit unsigned integer. \since 1.11 */ + VKD3D_SHADER_COMPONENT_UINT64 = 0x6,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), }; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 18030b82c..3ee9b252f 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1783,6 +1783,8 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, break; case VKD3D_SHADER_COMPONENT_DOUBLE: return vkd3d_spirv_get_op_type_float(builder, 64); + case VKD3D_SHADER_COMPONENT_UINT64: + return vkd3d_spirv_get_op_type_int(builder, 64, 0); default: FIXME("Unhandled component type %#x.\n", component_type); return 0; @@ -1816,6 +1818,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder break; case VKD3D_DATA_DOUBLE: return vkd3d_spirv_get_op_type_float(builder, 64); + case VKD3D_DATA_UINT64: + return vkd3d_spirv_get_op_type_int(builder, 64, 0); case VKD3D_DATA_BOOL: return vkd3d_spirv_get_op_type_bool(builder); default: @@ -2960,7 +2964,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, assert(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
- if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE) + if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) { FIXME("Unhandled component_type %#x.\n", component_type); return vkd3d_spirv_get_op_undef(builder, type_id); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 9de12e866..d5eb52c24 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -624,6 +624,7 @@ static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) switch (data_type) { case VKD3D_DATA_DOUBLE: + case VKD3D_DATA_UINT64: return true; default: return false; @@ -1452,6 +1453,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty return VKD3D_SHADER_COMPONENT_INT; case VKD3D_DATA_DOUBLE: return VKD3D_SHADER_COMPONENT_DOUBLE; + case VKD3D_DATA_UINT64: + return VKD3D_SHADER_COMPONENT_UINT64; case VKD3D_DATA_BOOL: return VKD3D_SHADER_COMPONENT_BOOL; default: diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index 6dd89eebe..b9dec0804 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -244,4 +244,4 @@ float4 main() : sv_target [test] uniform 0 uint64_t2 0x300000000 0x500000000 draw quad -todo probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1 +probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 45 +++++++++++-------- tests/hlsl/arithmetic-int-uniform.shader_test | 8 ++-- 2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 3ee9b252f..47bc7cf0b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3024,6 +3024,13 @@ static uint32_t spirv_compiler_get_constant_double_vector(struct spirv_compiler component_count, (const uint64_t *)values); }
+static uint32_t spirv_compiler_get_constant_uint64_vector(struct spirv_compiler *compiler, + uint64_t value, unsigned int component_count) +{ + const uint64_t values[] = {value, value}; + return spirv_compiler_get_constant64(compiler, VKD3D_SHADER_COMPONENT_UINT64, component_count, values); +} + static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask) { @@ -4235,7 +4242,8 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler }
static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - enum vkd3d_shader_conditional_op condition, unsigned int component_count, uint32_t val_id) + enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, + unsigned int component_count, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; @@ -4246,7 +4254,9 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); + data_type == VKD3D_DATA_UINT64 + ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) + : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); }
static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, @@ -6919,7 +6929,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler,
if (src[0].reg.data_type != VKD3D_DATA_BOOL) condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id);
spirv_compiler_emit_store_dst(compiler, dst, val_id); @@ -6944,7 +6954,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count);
condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id);
val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src2_id, src1_id); spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); @@ -7106,13 +7116,6 @@ 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_INT64_UNSUPPORTED, - "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); @@ -7122,9 +7125,11 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask);
condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id); - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, - 0xffffffff, component_count); + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); + if (dst[0].reg.data_type == VKD3D_DATA_UINT64) + uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, 0xffffffffffffffff, component_count); + else + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ @@ -7144,9 +7149,11 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask);
condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id); - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, - 0xffffffff, component_count); + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); + if (dst[1].reg.data_type == VKD3D_DATA_UINT64) + uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, 0xffffffffffffffff, component_count); + else + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); }
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); @@ -7437,7 +7444,7 @@ static uint32_t spirv_compiler_emit_conditional_branch(struct spirv_compiler *co uint32_t condition_id, merge_block_id;
condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, condition_id); + condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, condition_id);
merge_block_id = vkd3d_spirv_alloc_id(builder);
@@ -7570,7 +7577,7 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c return VKD3D_ERROR_OUT_OF_MEMORY;
val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, val_id); + condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, val_id);
true_label = vkd3d_spirv_alloc_id(builder); merge_block_id = vkd3d_spirv_alloc_id(builder); diff --git a/tests/hlsl/arithmetic-int-uniform.shader_test b/tests/hlsl/arithmetic-int-uniform.shader_test index f27aff037..62e7013f6 100644 --- a/tests/hlsl/arithmetic-int-uniform.shader_test +++ b/tests/hlsl/arithmetic-int-uniform.shader_test @@ -136,7 +136,7 @@ float4 main() : SV_TARGET
[test] uniform 0 int64_t2 5000000000 16000000000 -todo draw quad +draw quad probe all rgba (21.0e9, -11.0e9, 5.0e18, 0.0) 1
[pixel shader] @@ -151,7 +151,7 @@ float4 main() : SV_TARGET
[test] uniform 0 int64_t2 5000000000 16000000000 -todo draw quad +draw quad probe all rgba (5.0e9, 5.0e9, -5.0e9, 3.0)
[pixel shader] @@ -166,7 +166,7 @@ float4 main() : SV_TARGET
[test] uniform 0 int64_t2 42000000000 5000000000 -todo draw quad +draw quad probe all rgba (8.0, -8.0, -8.0, 8.0)
[pixel shader] @@ -181,7 +181,7 @@ float4 main() : SV_TARGET
[test] uniform 0 int64_t2 42000000000 5000000000 -todo draw quad +draw quad probe all rgba (2.0e9, -2.0e9, 2.0e9, -2.0e9)
[pixel shader]
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 47bc7cf0b..c3a683fa5 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4271,6 +4271,19 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); }
+static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, + unsigned int component_count, uint32_t val_id, bool signedness) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, true_id, false_id; + + true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? 0xffffffffffffffffull : 1, + component_count); + false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +} + static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, unsigned int component_count, uint32_t val_id, bool signedness) { @@ -6681,6 +6694,10 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, { val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI); } + else if (dst->reg.data_type == VKD3D_DATA_UINT64) + { + val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI); + } else { WARN("Unhandled data type %u.\n", dst->reg.data_type);
From: Conor McCarthy cmccarthy@codeweavers.com
These instructions perform integer casts to/from 64 bits. --- libs/vkd3d-shader/spirv.c | 2 ++ tests/hlsl/bitwise.shader_test | 8 ++++---- tests/hlsl/cast-64-bit.shader_test | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index c3a683fa5..e3860c628 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6637,12 +6637,14 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, {VKD3DSIH_ITOD, SpvOpConvertSToF}, {VKD3DSIH_ITOF, SpvOpConvertSToF}, + {VKD3DSIH_ITOI, SpvOpSConvert}, {VKD3DSIH_MUL, SpvOpFMul}, {VKD3DSIH_NOT, SpvOpNot}, {VKD3DSIH_OR, SpvOpBitwiseOr}, {VKD3DSIH_USHR, SpvOpShiftRightLogical}, {VKD3DSIH_UTOD, SpvOpConvertUToF}, {VKD3DSIH_UTOF, SpvOpConvertUToF}, + {VKD3DSIH_UTOU, SpvOpUConvert}, {VKD3DSIH_XOR, SpvOpBitwiseXor}, }; unsigned int i; diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index b9dec0804..1233d7c88 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -183,11 +183,11 @@ float4 main() : sv_target [test] uniform 0 int64_t2 9223372036854775807 -1 uniform 4 int4 34 66 0 0 -todo draw quad +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 +draw quad probe all rgba (-1.0, -1.0, -1.0, -1.0) 1
[pixel shader] @@ -207,7 +207,7 @@ float4 main() : sv_target [test] uniform 0 uint64_t2 0xffffffffffffffff 1 uniform 4 uint4 34 66 0 0 -todo draw quad +draw quad probe all rgba (9.223372036e18, 1.0, 1073741823.0, 4.611686018e18) 1
[pixel shader] @@ -227,7 +227,7 @@ float4 main() : sv_target [test] uniform 0 uint64_t2 0x83 1 uniform 4 uint4 34 66 0 0 -todo draw quad +draw quad probe all rgba (262.0, 9.223372036e18, 2250562863104.0, 524.0) 1
[pixel shader] diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test index 813cce108..5d9ce69c2 100644 --- a/tests/hlsl/cast-64-bit.shader_test +++ b/tests/hlsl/cast-64-bit.shader_test @@ -35,8 +35,8 @@ float4 main() : sv_target [test] uniform 0 uint64_t2 0x500000001 0x100000002 uniform 4 uint4 10 4 0 0 -todo draw quad -todo probe all rgba (1.0, 2.0, 2147483648.0, 1073741824.0) +draw quad +probe all rgba (1.0, 2.0, 2147483648.0, 1073741824.0)
[pixel shader] @@ -53,5 +53,5 @@ float4 main() : sv_target [test] uniform 0 int64_t2 -21474836481 0x100000002 uniform 4 int4 -20 8 0 0 -todo draw quad -todo probe all rgba (-1.0, 2.0, 1073741824.0, 536870912.0) +draw quad +probe all rgba (-1.0, 2.0, 1073741824.0, 536870912.0)