-- v4: vkd3d-shader/dxil: Implement DX intrinsic Saturate. vkd3d-shader/dxil: Implement DX intrinsic FAbs. vkd3d-shader/dxil: Implement DX intrinsics FMa, FMad, IMad and UMad. vkd3d-shader/spirv: Use dst register data type in spirv_compiler_emit_imad(). tests/hlsl: Add tests for mad() and fma().
From: Conor McCarthy cmccarthy@codeweavers.com
--- .../hlsl/arithmetic-float-uniform.shader_test | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 38e37b3fa..506375ebc 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -91,6 +91,38 @@ uniform 0 float4 1.0 0.0 0.0 0.0 draw quad probe all rgba (1e99, 1e99, 1e99, 1e99)
+[pixel shader todo] +uniform float4 a, b, c; + +float4 main() : sv_target +{ + return mad(a, b, c); +} + +[test] +uniform 0 float4 1.00000007 -42.1 4.0 45.0 +uniform 4 float4 1.625 -5.0 4.125 5.0 +uniform 8 float4 1.00000007 -1.0 0.5 -0.5 +todo draw quad +probe all rgba (2.62500024, 209.5, 17.0, 224.5) 1 + +% precise mad() is not allowed to fuse, even though unfused is less precise. +[pixel shader todo] +uniform float4 a, b, c; + +float4 main() : sv_target +{ + precise float4 ret = mad(a, b, c); + return ret; +} + +[test] +uniform 0 float4 1.00000007 -42.1 4.0 45.0 +uniform 4 float4 1.625 -5.0 4.125 5.0 +uniform 8 float4 1.00000007 -1.0 0.5 -0.5 +todo draw quad +todo probe all rgba (2.62500048, 209.5, 17.0, 224.5) + [require] shader model >= 5.0 float64 @@ -140,3 +172,18 @@ float4 main() : SV_TARGET uniform 0 double2 1.5e300 2.0e299 todo(sm<6) draw quad probe all rgba (7.5, 7.5, 7.5, 7.5) + +[pixel shader todo] +uniform double2 a, b, c; + +float4 main() : sv_target +{ + return float4(fma(a, b, c), 0, 0); +} + +[test] +uniform 0 double2 1.00000007 -42.1 +uniform 4 double2 1.625 -5.0 +uniform 8 double2 1.00000007 -1.0 +todo draw quad +probe all rgba (2.62500024, 209.5, 0.0, 0.0)
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 bd0bfb8e0..34de9b9fb 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -7474,7 +7474,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, unsigned int i, component_count;
component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, component_count); + type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count);
for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 40 +++++++++++++++++++ .../hlsl/arithmetic-float-uniform.shader_test | 6 +-- tests/hlsl/majority-pragma.shader_test | 9 +++-- tests/hlsl/majority-typedef.shader_test | 2 +- 4 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index de51588b5..e79220006 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -374,6 +374,10 @@ enum dx_intrinsic_opcode DX_IMIN = 38, DX_UMAX = 39, DX_UMIN = 40, + DX_FMAD = 46, + DX_FMA = 47, + DX_IMAD = 48, + DX_UMAD = 49, DX_IBFE = 51, DX_UBFE = 52, DX_CREATE_HANDLE = 57, @@ -4080,6 +4084,38 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int ins->handler_idx = VKD3DSIH_NOP; }
+static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type) +{ + switch (op) + { + case DX_FMA: + return VKD3DSIH_DFMA; + case DX_FMAD: + return VKD3DSIH_MAD; + case DX_IMAD: + case DX_UMAD: + return VKD3DSIH_IMAD; + default: + vkd3d_unreachable(); + } +} + +static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + unsigned int i; + + vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_ma_op(op, operands[0]->type)); + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + for (i = 0; i < 3; ++i) + src_param_init_from_value(&src_params[i], operands[i]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -4833,6 +4869,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary}, + [DX_FMA ] = {"g", "RRR", sm6_parser_emit_dx_ma}, + [DX_FMAD ] = {"g", "RRR", sm6_parser_emit_dx_ma}, [DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary}, [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, @@ -4841,6 +4879,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma}, [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, @@ -4873,6 +4912,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load}, [DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store}, [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, + [DX_UMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma}, [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, }; diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 506375ebc..7fcf8493d 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -103,7 +103,7 @@ float4 main() : sv_target uniform 0 float4 1.00000007 -42.1 4.0 45.0 uniform 4 float4 1.625 -5.0 4.125 5.0 uniform 8 float4 1.00000007 -1.0 0.5 -0.5 -todo draw quad +todo(sm<6) draw quad probe all rgba (2.62500024, 209.5, 17.0, 224.5) 1
% precise mad() is not allowed to fuse, even though unfused is less precise. @@ -120,7 +120,7 @@ float4 main() : sv_target uniform 0 float4 1.00000007 -42.1 4.0 45.0 uniform 4 float4 1.625 -5.0 4.125 5.0 uniform 8 float4 1.00000007 -1.0 0.5 -0.5 -todo draw quad +todo(sm<6) draw quad todo probe all rgba (2.62500048, 209.5, 17.0, 224.5)
[require] @@ -185,5 +185,5 @@ float4 main() : sv_target uniform 0 double2 1.00000007 -42.1 uniform 4 double2 1.625 -5.0 uniform 8 double2 1.00000007 -1.0 -todo draw quad +todo(sm<6) draw quad probe all rgba (2.62500024, 209.5, 0.0, 0.0) diff --git a/tests/hlsl/majority-pragma.shader_test b/tests/hlsl/majority-pragma.shader_test index 84dff63e0..4d40d8f60 100644 --- a/tests/hlsl/majority-pragma.shader_test +++ b/tests/hlsl/majority-pragma.shader_test @@ -17,7 +17,7 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1
@@ -66,7 +66,7 @@ probe all rgba (0.5, 0.6, 0.7, 0.8)
% The documentation claims these strings are subject to macro expansion. -% They are not. +% In SM < 6.0 they are not.
[pixel shader]
@@ -90,8 +90,9 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 -todo(sm>=6) draw quad -probe all rgba (0.23, 0.34, 0.5, 0.5) 1 +draw quad +if(sm<6) probe all rgba (0.23, 0.34, 0.5, 0.5) 1 +if(sm>=6) probe all rgba (0.17, 0.39, 0.5, 0.5) 1
% The majority that applies to a typedef is the latent majority at the time diff --git a/tests/hlsl/majority-typedef.shader_test b/tests/hlsl/majority-typedef.shader_test index fa62dd5f7..1460e9a08 100644 --- a/tests/hlsl/majority-typedef.shader_test +++ b/tests/hlsl/majority-typedef.shader_test @@ -18,5 +18,5 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 17 +++++++++++++++++ tests/hlsl/abs.shader_test | 4 ++-- tests/hlsl/fmod.shader_test | 8 ++++---- tests/hlsl/fwidth.shader_test | 2 +- tests/hlsl/length.shader_test | 4 ++-- 5 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index e79220006..2549c0a98 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -342,6 +342,7 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, + DX_FABS = 6, DX_ISNAN = 8, DX_ISINF = 9, DX_ISFINITE = 10, @@ -4084,6 +4085,21 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int ins->handler_idx = VKD3DSIH_NOP; }
+static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + src_param->modifiers = VKD3DSPSM_ABS; + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type) { switch (op) @@ -4866,6 +4882,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_DERIV_FINEX ] = {"e", "R", sm6_parser_emit_dx_unary}, [DX_DERIV_FINEY ] = {"e", "R", sm6_parser_emit_dx_unary}, [DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs}, [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary}, diff --git a/tests/hlsl/abs.shader_test b/tests/hlsl/abs.shader_test index 4d1d1e33e..46acdea85 100644 --- a/tests/hlsl/abs.shader_test +++ b/tests/hlsl/abs.shader_test @@ -8,8 +8,8 @@ float4 main() : sv_target
[test] uniform 0 float4 0.1 0.7 0.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (0.1, 0.7, 0.4, 0.4) uniform 0 float4 -0.7 0.1 0.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (0.7, 0.1, 1.2, 0.4) diff --git a/tests/hlsl/fmod.shader_test b/tests/hlsl/fmod.shader_test index d21301fee..62f7573de 100644 --- a/tests/hlsl/fmod.shader_test +++ b/tests/hlsl/fmod.shader_test @@ -8,10 +8,10 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 0.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (-0.5, 0.0, 0.0, 0.0) 4 uniform 0 float4 1.1 0.3 0.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (0.2, 0.0, 0.0, 0.0) 4
[pixel shader todo(sm<4)] @@ -24,8 +24,8 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 2.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (-0.5, 0.5, 0.0, 0.0) 4 uniform 0 float4 1.1 0.3 3.0 0.0 -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (1.1, 0.3, 0.0, 0.0) 4 diff --git a/tests/hlsl/fwidth.shader_test b/tests/hlsl/fwidth.shader_test index 10ed712d2..99fb1421d 100644 --- a/tests/hlsl/fwidth.shader_test +++ b/tests/hlsl/fwidth.shader_test @@ -18,7 +18,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe (10, 10) rgba (8.0, 8.0, 8.0, 8.0) probe (11, 10) rgba (8.0, 8.0, 8.0, 8.0) probe (12, 10) rgba (10.0, 10.0, 10.0, 10.0) diff --git a/tests/hlsl/length.shader_test b/tests/hlsl/length.shader_test index ec48300f6..4080ff406 100644 --- a/tests/hlsl/length.shader_test +++ b/tests/hlsl/length.shader_test @@ -47,7 +47,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, 2.0, 2.0, 2.0)
[pixel shader] @@ -60,7 +60,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, 2.0, 2.0, 2.0)
[pixel shader fail]
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 25 +++++++++++++++++++++++-- tests/hlsl/saturate.shader_test | 4 ++-- 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2549c0a98..e86c8488e 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -343,6 +343,7 @@ enum dx_intrinsic_opcode DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, DX_FABS = 6, + DX_SATURATE = 7, DX_ISNAN = 8, DX_ISINF = 9, DX_ISFINITE = 10, @@ -2356,14 +2357,18 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, } }
-static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) +static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) { - struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); struct sm6_value *dst = sm6_parser_get_current_value(sm6); + struct vkd3d_shader_dst_param *param; + + if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) + return false;
dst_param_init_ssa_scalar(param, dst->type, dst, sm6); param->write_mask = VKD3DSP_WRITEMASK_0; dst->u.reg = param->reg; + return true; }
static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instruction *ins, @@ -4588,6 +4593,21 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ instruction_dst_param_init_ssa_vector(ins, component_count, sm6); }
+static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + + if (instruction_dst_param_init_ssa_scalar(ins, sm6)) + ins->dst->modifiers = VKD3DSPDM_SATURATE; +} + static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -4919,6 +4939,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_SAMPLE_C_LZ ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, [DX_SAMPLE_GRAD ] = {"o", "HHffffiiifffffff", sm6_parser_emit_dx_sample}, [DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, + [DX_SATURATE ] = {"g", "R", sm6_parser_emit_dx_saturate}, [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, diff --git a/tests/hlsl/saturate.shader_test b/tests/hlsl/saturate.shader_test index 2ed83cf66..e3ccce768 100644 --- a/tests/hlsl/saturate.shader_test +++ b/tests/hlsl/saturate.shader_test @@ -8,7 +8,7 @@ float4 main() : sv_target
[test] uniform 0 float4 0.7 -0.1 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.7, 0.0, 1.0, 0.0)
[pixel shader] @@ -22,5 +22,5 @@ float4 main() : sv_target
[test] uniform 0 float4 -2 0 2 -1 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 1.0, 0.0)
This merge request was approved by Henri Verbeet.