HLSL: Deal with casting for WaveActiveMin/Max.

This commit is contained in:
Hans-Kristian Arntzen 2020-01-09 12:10:59 +01:00
parent 5253da9e63
commit 88ddeec49a
3 changed files with 118 additions and 4 deletions

View File

@ -0,0 +1,30 @@
static int index;
static uint FragColor;
struct SPIRV_Cross_Input
{
nointerpolation int index : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
uint FragColor : SV_Target0;
};
void frag_main()
{
uint _17 = uint(index);
FragColor = uint(WaveActiveMin(index));
FragColor = uint(WaveActiveMax(int(_17)));
FragColor = WaveActiveMin(uint(index));
FragColor = WaveActiveMax(_17);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
index = stage_input.index;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,65 @@
; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 78
; Schema: 0
OpCapability Shader
OpCapability GroupNonUniform
OpCapability GroupNonUniformArithmetic
OpCapability GroupNonUniformClustered
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %index %FragColor
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_KHR_shader_subgroup_arithmetic"
OpSourceExtension "GL_KHR_shader_subgroup_basic"
OpSourceExtension "GL_KHR_shader_subgroup_clustered"
OpName %main "main"
OpName %index "index"
OpName %FragColor "FragColor"
OpDecorate %index Flat
OpDecorate %index Location 0
OpDecorate %FragColor Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
%uint_0 = OpConstant %uint 0
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%index = OpVariable %_ptr_Input_int Input
%uint_3 = OpConstant %uint 3
%uint_4 = OpConstant %uint 4
%_ptr_Output_uint = OpTypePointer Output %uint
%FragColor = OpVariable %_ptr_Output_uint Output
%main = OpFunction %void None %3
%5 = OpLabel
%i = OpLoad %int %index
%u = OpBitcast %uint %i
%res0 = OpGroupNonUniformSMin %uint %uint_3 Reduce %i
%res1 = OpGroupNonUniformSMax %uint %uint_3 Reduce %u
%res2 = OpGroupNonUniformUMin %uint %uint_3 Reduce %i
%res3 = OpGroupNonUniformUMax %uint %uint_3 Reduce %u
;%res4 = OpGroupNonUniformSMax %uint %uint_3 InclusiveScan %i
;%res5 = OpGroupNonUniformSMin %uint %uint_3 InclusiveScan %u
;%res6 = OpGroupNonUniformUMax %uint %uint_3 ExclusiveScan %i
;%res7 = OpGroupNonUniformUMin %uint %uint_3 ExclusiveScan %u
;%res8 = OpGroupNonUniformSMin %uint %uint_3 ClusteredReduce %i %uint_4
;%res9 = OpGroupNonUniformSMax %uint %uint_3 ClusteredReduce %u %uint_4
;%res10 = OpGroupNonUniformUMin %uint %uint_3 ClusteredReduce %i %uint_4
;%res11 = OpGroupNonUniformUMax %uint %uint_3 ClusteredReduce %u %uint_4
OpStore %FragColor %res0
OpStore %FragColor %res1
OpStore %FragColor %res2
OpStore %FragColor %res3
;OpStore %FragColor %res4
;OpStore %FragColor %res5
;OpStore %FragColor %res6
;OpStore %FragColor %res7
;OpStore %FragColor %res8
;OpStore %FragColor %res9
;OpStore %FragColor %res10
;OpStore %FragColor %res11
OpReturn
OpFunctionEnd

View File

@ -4079,6 +4079,11 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i)
return join(expr, " * ", to_expression(ops[4]));
};
// If we need to do implicit bitcasts, make sure we do it with the correct type.
uint32_t integer_width = get_integer_width_for_instruction(i);
auto int_type = to_signed_basetype(integer_width);
auto uint_type = to_unsigned_basetype(integer_width);
#define make_inclusive_BitAnd(expr) ""
#define make_inclusive_BitOr(expr) ""
#define make_inclusive_BitXor(expr) ""
@ -4187,20 +4192,34 @@ case OpGroupNonUniform##op: \
SPIRV_CROSS_THROW("Invalid group operation."); \
break; \
}
#define HLSL_GROUP_OP_CAST(op, hlsl_op, type) \
case OpGroupNonUniform##op: \
{ \
auto operation = static_cast<GroupOperation>(ops[3]); \
if (operation == GroupOperationReduce) \
emit_unary_func_op_cast(result_type, id, ops[4], "WaveActive" #hlsl_op, type, type); \
else \
SPIRV_CROSS_THROW("Invalid group operation."); \
break; \
}
HLSL_GROUP_OP(FAdd, Sum, true)
HLSL_GROUP_OP(FMul, Product, true)
HLSL_GROUP_OP(FMin, Min, false)
HLSL_GROUP_OP(FMax, Max, false)
HLSL_GROUP_OP(IAdd, Sum, true)
HLSL_GROUP_OP(IMul, Product, true)
HLSL_GROUP_OP(SMin, Min, false)
HLSL_GROUP_OP(SMax, Max, false)
HLSL_GROUP_OP(UMin, Min, false)
HLSL_GROUP_OP(UMax, Max, false)
HLSL_GROUP_OP_CAST(SMin, Min, int_type)
HLSL_GROUP_OP_CAST(SMax, Max, int_type)
HLSL_GROUP_OP_CAST(UMin, Min, uint_type)
HLSL_GROUP_OP_CAST(UMax, Max, uint_type)
HLSL_GROUP_OP(BitwiseAnd, BitAnd, false)
HLSL_GROUP_OP(BitwiseOr, BitOr, false)
HLSL_GROUP_OP(BitwiseXor, BitXor, false)
#undef HLSL_GROUP_OP
#undef HLSL_GROUP_OP_CAST
// clang-format on
case OpGroupNonUniformQuadSwap: