Merge pull request #151 from Kode/fix
Transform more functions for HLSL
This commit is contained in:
Коммит
f4749df09a
|
@ -0,0 +1,27 @@
|
|||
static float2 value;
|
||||
static float4 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float2 value : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
int i = asint(value.x);
|
||||
FragColor = float4(1.0f, 0.0f, asfloat(i), 1.0f);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
value = stage_input.value;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -5,14 +5,14 @@ static float4 vColor;
|
|||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float4 gl_FragCoord : SV_Position;
|
||||
float4 vColor : TEXCOORD0;
|
||||
float4 gl_FragCoord : SV_Position;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float gl_FragDepth : SV_Depth;
|
||||
float4 FragColor : SV_Target0;
|
||||
float gl_FragDepth : SV_Depth;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
static float2 value;
|
||||
static float4 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float2 value : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
bool2 _25 = bool2(value.x == 0.0f, value.y == 0.0f);
|
||||
bool2 bools1 = bool2(!_25.x, !_25.y);
|
||||
bool2 bools2 = bool2(value.x <= float2(1.5f, 0.5f).x, value.y <= float2(1.5f, 0.5f).y);
|
||||
FragColor = float4(1.0f, 0.0f, float(bools1.x), float(bools2.x));
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
value = stage_input.value;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
static float2 interpolant;
|
||||
static float4 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float2 interpolant : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
float4 color = float4(0.0f, 0.0f, 0.0f, EvaluateAttributeSnapped(interpolant, float2(0.100000001490116119384765625f, 0.100000001490116119384765625f)).x);
|
||||
color += float4(0.0f, 0.0f, 0.0f, ddx_coarse(interpolant.x));
|
||||
FragColor = color;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
interpolant = stage_input.interpolant;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -21,8 +21,8 @@ struct SPIRV_Cross_Input
|
|||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : SV_Position;
|
||||
float3 vNormal : TEXCOORD0;
|
||||
float4 gl_Position : SV_Position;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
|
|
|
@ -32,12 +32,12 @@ struct SPIRV_Cross_Input
|
|||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : SV_Position;
|
||||
float vLocation0 : TEXCOORD0;
|
||||
float vLocation1 : TEXCOORD1;
|
||||
float vLocation2[2] : TEXCOORD2;
|
||||
Foo vLocation4 : TEXCOORD4;
|
||||
float vLocation9 : TEXCOORD9;
|
||||
float4 gl_Position : SV_Position;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
|
|
|
@ -16,11 +16,11 @@ static Block vout;
|
|||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : SV_Position;
|
||||
nointerpolation float vFlat : TEXCOORD0;
|
||||
centroid float vCentroid : TEXCOORD1;
|
||||
sample float vSample : TEXCOORD2;
|
||||
noperspective float vNoperspective : TEXCOORD3;
|
||||
float4 gl_Position : SV_Position;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(location = 0) in vec2 value;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
int i = floatBitsToInt(value.x);
|
||||
FragColor = vec4(1.0, 0.0, intBitsToFloat(i), 1.0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(location = 0) in vec2 value;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
bvec2 bools1 = not(bvec2(value.x == 0.0, value.y == 0.0));
|
||||
bvec2 bools2 = lessThanEqual(value, vec2(1.5, 0.5));
|
||||
FragColor = vec4(1.0, 0.0, bools1.x ? 1.0 : 0.0, bools2.x ? 1.0 : 0.0);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#version 450
|
||||
|
||||
in vec2 interpolant;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, interpolateAtOffset(interpolant, vec2(0.1, 0.1)));
|
||||
|
||||
// glslang's HLSL parser currently fails here
|
||||
//color += vec4(0.0, 0.0, 0.0, interpolateAtSample(interpolant, gl_SampleID));
|
||||
//color += vec4(0.0, 0.0, 0.0, interpolateAtCentroid(interpolant));
|
||||
|
||||
color += vec4(0.0, 0.0, 0.0, dFdxCoarse(interpolant.x));
|
||||
FragColor = color;
|
||||
}
|
|
@ -2268,6 +2268,29 @@ void CompilerGLSL::emit_binary_op(uint32_t result_type, uint32_t result_id, uint
|
|||
inherit_expression_dependencies(result_id, op1);
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_unrolled_unary_op(uint32_t result_type, uint32_t result_id, uint32_t operand, const char *op)
|
||||
{
|
||||
auto &type = get<SPIRType>(result_type);
|
||||
auto expr = type_to_glsl_constructor(type);
|
||||
expr += '(';
|
||||
for (uint32_t i = 0; i < type.vecsize; i++)
|
||||
{
|
||||
// Make sure to call to_expression multiple times to ensure
|
||||
// that these expressions are properly flushed to temporaries if needed.
|
||||
expr += op;
|
||||
expr += to_enclosed_expression(operand);
|
||||
expr += '.';
|
||||
expr += index_to_swizzle(i);
|
||||
|
||||
if (i + 1 < type.vecsize)
|
||||
expr += ", ";
|
||||
}
|
||||
expr += ')';
|
||||
emit_op(result_type, result_id, expr, should_forward(operand));
|
||||
|
||||
inherit_expression_dependencies(result_id, operand);
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_unrolled_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1,
|
||||
const char *op)
|
||||
{
|
||||
|
@ -5032,6 +5055,46 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
require_extension("GL_OES_standard_derivatives");
|
||||
break;
|
||||
|
||||
case OpDPdxFine:
|
||||
UFOP(dFdxFine);
|
||||
if (options.es)
|
||||
{
|
||||
SPIRV_CROSS_THROW("GL_ARB_derivative_control is unavailable in OpenGL ES.");
|
||||
}
|
||||
if (options.version < 450)
|
||||
require_extension("GL_ARB_derivative_control");
|
||||
break;
|
||||
|
||||
case OpDPdyFine:
|
||||
UFOP(dFdyFine);
|
||||
if (options.es)
|
||||
{
|
||||
SPIRV_CROSS_THROW("GL_ARB_derivative_control is unavailable in OpenGL ES.");
|
||||
}
|
||||
if (options.version < 450)
|
||||
require_extension("GL_ARB_derivative_control");
|
||||
break;
|
||||
|
||||
case OpDPdxCoarse:
|
||||
if (options.es)
|
||||
{
|
||||
SPIRV_CROSS_THROW("GL_ARB_derivative_control is unavailable in OpenGL ES.");
|
||||
}
|
||||
UFOP(dFdxCoarse);
|
||||
if (options.version < 450)
|
||||
require_extension("GL_ARB_derivative_control");
|
||||
break;
|
||||
|
||||
case OpDPdyCoarse:
|
||||
UFOP(dFdyCoarse);
|
||||
if (options.es)
|
||||
{
|
||||
SPIRV_CROSS_THROW("GL_ARB_derivative_control is unavailable in OpenGL ES.");
|
||||
}
|
||||
if (options.version < 450)
|
||||
require_extension("GL_ARB_derivative_control");
|
||||
break;
|
||||
|
||||
case OpFwidth:
|
||||
UFOP(fwidth);
|
||||
if (is_legacy_es())
|
||||
|
|
|
@ -309,6 +309,7 @@ protected:
|
|||
void emit_binary_func_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op,
|
||||
SPIRType::BaseType input_type, bool skip_cast_if_equal_type);
|
||||
void emit_unary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op);
|
||||
void emit_unrolled_unary_op(uint32_t result_type, uint32_t result_id, uint32_t operand, const char *op);
|
||||
void emit_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
void emit_unrolled_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
void emit_binary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op,
|
||||
|
@ -371,7 +372,7 @@ protected:
|
|||
uint32_t type_to_std430_size(const SPIRType &type, uint64_t flags);
|
||||
|
||||
std::string bitcast_glsl(const SPIRType &result_type, uint32_t arg);
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type);
|
||||
virtual std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type);
|
||||
std::string build_composite_combiner(const uint32_t *elems, uint32_t length);
|
||||
bool remove_duplicate_swizzle(std::string &op);
|
||||
bool remove_unity_swizzle(uint32_t base, std::string &op);
|
||||
|
|
290
spirv_hlsl.cpp
290
spirv_hlsl.cpp
|
@ -22,6 +22,27 @@ using namespace spv;
|
|||
using namespace spirv_cross;
|
||||
using namespace std;
|
||||
|
||||
// Returns true if an arithmetic operation does not change behavior depending on signedness.
|
||||
static bool opcode_is_sign_invariant(Op opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case OpIEqual:
|
||||
case OpINotEqual:
|
||||
case OpISub:
|
||||
case OpIAdd:
|
||||
case OpIMul:
|
||||
case OpShiftLeftLogical:
|
||||
case OpBitwiseOr:
|
||||
case OpBitwiseXor:
|
||||
case OpBitwiseAnd:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerHLSL::type_to_glsl(const SPIRType &type)
|
||||
{
|
||||
// Ignore the pointer type since GLSL doesn't have pointers.
|
||||
|
@ -219,6 +240,13 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
|||
semantic = "SV_InstanceID";
|
||||
break;
|
||||
|
||||
case BuiltInSampleId:
|
||||
if (legacy)
|
||||
SPIRV_CROSS_THROW("Sample ID not supported in SM 3.0 or lower.");
|
||||
type = "uint";
|
||||
semantic = "SV_SampleIndex";
|
||||
break;
|
||||
|
||||
default:
|
||||
SPIRV_CROSS_THROW("Unsupported builtin in HLSL.");
|
||||
break;
|
||||
|
@ -395,6 +423,7 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
|
||||
case BuiltInVertexIndex:
|
||||
case BuiltInInstanceIndex:
|
||||
case BuiltInSampleId:
|
||||
type = "int";
|
||||
break;
|
||||
|
||||
|
@ -608,9 +637,9 @@ void CompilerHLSL::emit_resources()
|
|||
|
||||
begin_scope();
|
||||
sort(input_variables.begin(), input_variables.end(), variable_compare);
|
||||
emit_builtin_inputs_in_struct();
|
||||
for (auto var : input_variables)
|
||||
emit_interface_block_in_struct(*var, active_inputs);
|
||||
emit_builtin_inputs_in_struct();
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
}
|
||||
|
@ -623,9 +652,9 @@ void CompilerHLSL::emit_resources()
|
|||
begin_scope();
|
||||
// FIXME: Use locations properly if they exist.
|
||||
sort(output_variables.begin(), output_variables.end(), variable_compare);
|
||||
emit_builtin_outputs_in_struct();
|
||||
for (auto var : output_variables)
|
||||
emit_interface_block_in_struct(*var, active_outputs);
|
||||
emit_builtin_outputs_in_struct();
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
}
|
||||
|
@ -1213,6 +1242,36 @@ void CompilerHLSL::emit_uniform(const SPIRVariable &var)
|
|||
statement(variable_decl(var), ";");
|
||||
}
|
||||
|
||||
string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in_type)
|
||||
{
|
||||
if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Int)
|
||||
return type_to_glsl(out_type);
|
||||
else if (out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::Int64)
|
||||
return type_to_glsl(out_type);
|
||||
else if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Float)
|
||||
return "asuint";
|
||||
else if (out_type.basetype == SPIRType::Int && in_type.basetype == SPIRType::UInt)
|
||||
return type_to_glsl(out_type);
|
||||
else if (out_type.basetype == SPIRType::Int64 && in_type.basetype == SPIRType::UInt64)
|
||||
return type_to_glsl(out_type);
|
||||
else if (out_type.basetype == SPIRType::Int && in_type.basetype == SPIRType::Float)
|
||||
return "asint";
|
||||
else if (out_type.basetype == SPIRType::Float && in_type.basetype == SPIRType::UInt)
|
||||
return "asfloat";
|
||||
else if (out_type.basetype == SPIRType::Float && in_type.basetype == SPIRType::Int)
|
||||
return "asfloat";
|
||||
else if (out_type.basetype == SPIRType::Int64 && in_type.basetype == SPIRType::Double)
|
||||
SPIRV_CROSS_THROW("Double to Int64 is not supported in HLSL.");
|
||||
else if (out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::Double)
|
||||
SPIRV_CROSS_THROW("Double to UInt64 is not supported in HLSL.");
|
||||
else if (out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::Int64)
|
||||
return "asdouble";
|
||||
else if (out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::UInt64)
|
||||
return "asdouble";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t count)
|
||||
{
|
||||
GLSLstd450 op = static_cast<GLSLstd450>(eop);
|
||||
|
@ -1220,26 +1279,36 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
|
|||
switch (op)
|
||||
{
|
||||
case GLSLstd450InverseSqrt:
|
||||
{
|
||||
emit_unary_func_op(result_type, id, args[0], "rsqrt");
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSLstd450Fract:
|
||||
{
|
||||
emit_unary_func_op(result_type, id, args[0], "frac");
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSLstd450FMix:
|
||||
case GLSLstd450IMix:
|
||||
{
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "lerp");
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSLstd450Atan2:
|
||||
{
|
||||
emit_binary_func_op(result_type, id, args[1], args[0], "atan2");
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSLstd450Fma:
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "mad");
|
||||
break;
|
||||
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
emit_unary_func_op(result_type, id, args[0], "EvaluateAttributeAtCentroid");
|
||||
break;
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
emit_binary_func_op(result_type, id, args[0], args[1], "EvaluateAttributeAtSample");
|
||||
break;
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
emit_binary_func_op(result_type, id, args[0], args[1], "EvaluateAttributeSnapped");
|
||||
break;
|
||||
|
||||
default:
|
||||
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
|
||||
break;
|
||||
|
@ -1252,12 +1321,14 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||
auto opcode = static_cast<Op>(instruction.op);
|
||||
|
||||
#define BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BOP_CAST(op, type, skip_cast) emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, skip_cast)
|
||||
#define BOP_CAST(op, type) \
|
||||
emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||
#define UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||
#define QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||
#define TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BFOP_CAST(op, type, skip_cast) emit_binary_func_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, skip_cast)
|
||||
#define BFOP_CAST(op, type) \
|
||||
emit_binary_func_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||
|
||||
|
@ -1268,22 +1339,217 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||
emit_binary_func_op(ops[0], ops[1], ops[3], ops[2], "mul");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpVectorTimesMatrix:
|
||||
{
|
||||
emit_binary_func_op(ops[0], ops[1], ops[3], ops[2], "mul");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpMatrixTimesMatrix:
|
||||
{
|
||||
emit_binary_func_op(ops[0], ops[1], ops[3], ops[2], "mul");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFMod:
|
||||
{
|
||||
requires_op_fmod = true;
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpDPdx:
|
||||
UFOP(ddx);
|
||||
break;
|
||||
|
||||
case OpDPdy:
|
||||
UFOP(ddy);
|
||||
break;
|
||||
|
||||
case OpDPdxFine:
|
||||
UFOP(ddx_fine);
|
||||
break;
|
||||
|
||||
case OpDPdyFine:
|
||||
UFOP(ddy_fine);
|
||||
break;
|
||||
|
||||
case OpDPdxCoarse:
|
||||
UFOP(ddx_coarse);
|
||||
break;
|
||||
|
||||
case OpDPdyCoarse:
|
||||
UFOP(ddy_coarse);
|
||||
break;
|
||||
|
||||
case OpLogicalNot:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
auto &type = get<SPIRType>(result_type);
|
||||
|
||||
if (type.vecsize > 1)
|
||||
emit_unrolled_unary_op(result_type, id, ops[2], "!");
|
||||
else
|
||||
UOP(!);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpIEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "==");
|
||||
else
|
||||
BOP_CAST(== , SPIRType::Int);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpLogicalEqual:
|
||||
case OpFOrdEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "==");
|
||||
else
|
||||
BOP(== );
|
||||
break;
|
||||
}
|
||||
|
||||
case OpINotEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "!=");
|
||||
else
|
||||
BOP_CAST(!= , SPIRType::Int);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpLogicalNotEqual:
|
||||
case OpFOrdNotEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "!=");
|
||||
else
|
||||
BOP(!= );
|
||||
break;
|
||||
}
|
||||
|
||||
case OpUGreaterThan:
|
||||
case OpSGreaterThan:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
auto type = opcode == OpUGreaterThan ? SPIRType::UInt : SPIRType::Int;
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">");
|
||||
else
|
||||
BOP_CAST(>, type);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFOrdGreaterThan:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">");
|
||||
else
|
||||
BOP(>);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpUGreaterThanEqual:
|
||||
case OpSGreaterThanEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
auto type = opcode == OpUGreaterThanEqual ? SPIRType::UInt : SPIRType::Int;
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">=");
|
||||
else
|
||||
BOP_CAST(>= , type);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFOrdGreaterThanEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">=");
|
||||
else
|
||||
BOP(>= );
|
||||
break;
|
||||
}
|
||||
|
||||
case OpULessThan:
|
||||
case OpSLessThan:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
auto type = opcode == OpULessThan ? SPIRType::UInt : SPIRType::Int;
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<");
|
||||
else
|
||||
BOP_CAST(<, type);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFOrdLessThan:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<");
|
||||
else
|
||||
BOP(<);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpULessThanEqual:
|
||||
case OpSLessThanEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
auto type = opcode == OpULessThanEqual ? SPIRType::UInt : SPIRType::Int;
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<=");
|
||||
else
|
||||
BOP_CAST(<= , type);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFOrdLessThanEqual:
|
||||
{
|
||||
auto result_type = ops[0];
|
||||
auto id = ops[1];
|
||||
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<=");
|
||||
else
|
||||
BOP(<= );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
break;
|
||||
|
|
|
@ -69,6 +69,7 @@ private:
|
|||
void emit_uniform(const SPIRVariable &var) override;
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
|
||||
std::string to_interpolation_qualifiers(uint64_t flags) override;
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
|
||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче