-- v3: vkd3d-shader/spirv: Handle the ISINF and ISNAN instructions in spirv_compiler_emit_alu_instruction(). vkd3d-shader/spirv: Implement the ISFINITE instruction. tests/shader-runner: Add tests for floating point special values. vkd3d-shader/dxil: Handle floating point special value comparisons in sm6_parser_emit_dx_unary().
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 3 +++ libs/vkd3d-shader/dxil.c | 15 +++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 3 +++ 3 files changed, 21 insertions(+)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index d9751945d..6ec7a9c99 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -198,8 +198,11 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_IMUL ] = "imul", [VKD3DSIH_INE ] = "ine", [VKD3DSIH_INEG ] = "ineg", + [VKD3DSIH_ISFINITE ] = "isfinite", [VKD3DSIH_ISHL ] = "ishl", [VKD3DSIH_ISHR ] = "ishr", + [VKD3DSIH_ISINF ] = "isinf", + [VKD3DSIH_ISNAN ] = "isnan", [VKD3DSIH_ITOD ] = "itod", [VKD3DSIH_ITOF ] = "itof", [VKD3DSIH_ITOI ] = "itoi", diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2a0ff61cf..c089d132c 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -328,6 +328,9 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, + DX_ISNAN = 8, + DX_ISINF = 9, + DX_ISFINITE = 10, DX_EXP = 21, DX_FRC = 22, DX_LOG = 23, @@ -3494,6 +3497,12 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) { switch (op) { + case DX_ISNAN: + return VKD3DSIH_ISNAN; + case DX_ISINF: + return VKD3DSIH_ISINF; + case DX_ISFINITE: + return VKD3DSIH_ISFINITE; case DX_EXP: return VKD3DSIH_EXP; case DX_FRC: @@ -3806,6 +3815,7 @@ struct sm6_dx_opcode_info };
/* + 1 -> int1 8 -> int8 b -> constant int1 c -> constant int8/16/32 @@ -3839,6 +3849,9 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, [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}, + [DX_ISINF ] = {"1", "g", sm6_parser_emit_dx_unary}, + [DX_ISNAN ] = {"1", "g", sm6_parser_emit_dx_unary}, [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary}, [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, @@ -3867,6 +3880,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 0: FIXME("Invalid operand count.\n"); return false; + case '1': + return sm6_type_is_bool(type); case '8': return sm6_type_is_i8(type); case 'b': diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 9a00b7bc2..688b53bb9 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -392,8 +392,11 @@ enum vkd3d_shader_opcode VKD3DSIH_IMUL, VKD3DSIH_INE, VKD3DSIH_INEG, + VKD3DSIH_ISFINITE, VKD3DSIH_ISHL, VKD3DSIH_ISHR, + VKD3DSIH_ISINF, + VKD3DSIH_ISNAN, VKD3DSIH_ITOD, VKD3DSIH_ITOF, VKD3DSIH_ITOI,
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/hlsl/float-comparison.shader_test | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test index ee4b5eb7c..02fae69c6 100644 --- a/tests/hlsl/float-comparison.shader_test +++ b/tests/hlsl/float-comparison.shader_test @@ -65,3 +65,32 @@ shader model >= 6.0 uniform 0 float4 0.0 1.5 1.5 0.0 draw quad probe all rgba (1010101.0, 11110000.0, 1101001.0, 0.0) + + +[pixel shader] +uniform float4 f; + +float4 main() : sv_target +{ + float4 result = float4(isinf(f.x / f.y), isnan(sqrt(f.w)), isinf(sqrt(f.w)), isnan(f.x / f.y)); + return result + float4(isinf(f.x / f.z), isnan(sqrt(f.y)), isinf(f.y / f.z), isnan(sqrt(f.z))) * 10.0; +} + +[test] +uniform 0 float4 1.5 0.0 1.0 -1.0 +todo draw quad +probe all rgba (1.0, 1.0, 0.0, 0.0) + + +[pixel shader] +uniform float4 f; + +float4 main() : sv_target +{ + return float4(isfinite(f.x / f.y), isfinite(sqrt(f.w)), isfinite(f.x / f.z), 0.0); +} + +[test] +uniform 0 float4 1.5 0.0 1.0 -1.0 +todo draw quad +probe all rgba (0.0, 0.0, 1.0, 0.0)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 39 +++++++++++++++++++++++++ tests/hlsl/float-comparison.shader_test | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2acf3b27b..4b70a0586 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1515,6 +1515,25 @@ static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder SpvOpULessThanEqual, result_type, operand0, operand1); }
+static uint32_t vkd3d_spirv_build_op_is_inf(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t operand) +{ + return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsInf, result_type, operand); +} + +static uint32_t vkd3d_spirv_build_op_is_nan(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t operand) +{ + return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, result_type, operand); +} + +static uint32_t vkd3d_spirv_build_op_logical_equal(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t operand0, uint32_t operand1) +{ + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpLogicalEqual, result_type, operand0, operand1); +} + static uint32_t vkd3d_spirv_build_op_convert_utof(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t unsigned_value) { @@ -6896,6 +6915,23 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil return VKD3D_OK; }
+static void spirv_compiler_emit_isfinite(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t type_id, src_id, isinf_id, isnan_id, val_id; + + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + /* OpIsFinite is only available in Kernel mode. */ + isinf_id = vkd3d_spirv_build_op_is_inf(builder, type_id, src_id); + isnan_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src_id); + val_id = vkd3d_spirv_build_op_logical_equal(builder, type_id, isinf_id, isnan_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( const struct vkd3d_shader_instruction *instruction) { @@ -9465,6 +9501,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_XOR: ret = spirv_compiler_emit_alu_instruction(compiler, instruction); break; + case VKD3DSIH_ISFINITE: + spirv_compiler_emit_isfinite(compiler, instruction); + break; case VKD3DSIH_DFMA: case VKD3DSIH_DMAX: case VKD3DSIH_DMIN: diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test index 02fae69c6..abb66674b 100644 --- a/tests/hlsl/float-comparison.shader_test +++ b/tests/hlsl/float-comparison.shader_test @@ -92,5 +92,5 @@ float4 main() : sv_target
[test] uniform 0 float4 1.5 0.0 1.0 -1.0 -todo draw quad +draw quad probe all rgba (0.0, 0.0, 1.0, 0.0)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 4 ++++ tests/hlsl/float-comparison.shader_test | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 4b70a0586..c31217dfe 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6768,6 +6768,8 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_INEG, SpvOpSNegate}, {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, + {VKD3DSIH_ISINF, SpvOpIsInf}, + {VKD3DSIH_ISNAN, SpvOpIsNan}, {VKD3DSIH_ITOD, SpvOpConvertSToF}, {VKD3DSIH_ITOF, SpvOpConvertSToF}, {VKD3DSIH_ITOI, SpvOpSConvert}, @@ -9488,6 +9490,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_INEG: case VKD3DSIH_ISHL: case VKD3DSIH_ISHR: + case VKD3DSIH_ISINF: + case VKD3DSIH_ISNAN: case VKD3DSIH_ITOD: case VKD3DSIH_ITOF: case VKD3DSIH_ITOI: diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test index abb66674b..0e8988dff 100644 --- a/tests/hlsl/float-comparison.shader_test +++ b/tests/hlsl/float-comparison.shader_test @@ -78,7 +78,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.5 0.0 1.0 -1.0 -todo draw quad +draw quad probe all rgba (1.0, 1.0, 0.0, 0.0)
This merge request was approved by Henri Verbeet.