mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-09 22:00:05 +00:00
Add support for new extensions.
This commit is contained in:
parent
ac607e5382
commit
6671f52334
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_fragment_mask : require
|
||||
|
||||
layout(binding = 0) uniform sampler2DMS t;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 test2 = fragmentFetchAMD(t, 4u);
|
||||
uint testi2 = fragmentMaskFetchAMD(t);
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_fragment_mask : require
|
||||
|
||||
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS t;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 test2 = fragmentFetchAMD(t, 4u);
|
||||
uint testi2 = fragmentMaskFetchAMD(t);
|
||||
}
|
||||
|
13
reference/shaders/amd/fs.frag
Normal file
13
reference/shaders/amd/fs.frag
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_fragment_mask : require
|
||||
#extension GL_AMD_shader_explicit_vertex_parameter : require
|
||||
|
||||
uniform sampler2DMS texture1;
|
||||
|
||||
void main()
|
||||
{
|
||||
uint testi1 = fragmentMaskFetchAMD(texture1, ivec2(0));
|
||||
vec4 test1 = fragmentFetchAMD(texture1, ivec2(1), 2u);
|
||||
vec4 pos = interpolateAtVertexAMD(vec4(0.0), 0u);
|
||||
}
|
||||
|
12
reference/shaders/amd/gcn_shader.comp
Normal file
12
reference/shaders/amd/gcn_shader.comp
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
#extension GL_AMD_gcn_shader : require
|
||||
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
float cubeFace = cubeFaceIndexAMD(vec3(0.0));
|
||||
vec2 cubeFaceCoord = cubeFaceCoordAMD(vec3(1.0));
|
||||
uint64_t time = timeAMD();
|
||||
}
|
||||
|
32
reference/shaders/amd/shader_ballot.comp
Normal file
32
reference/shaders/amd/shader_ballot.comp
Normal file
@ -0,0 +1,32 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_ballot : require
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
#extension GL_AMD_shader_ballot : require
|
||||
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
layout(binding = 0, std430) buffer inputData
|
||||
{
|
||||
float inputDataArray[];
|
||||
} _12;
|
||||
|
||||
layout(binding = 1, std430) buffer outputData
|
||||
{
|
||||
float outputDataArray[];
|
||||
} _74;
|
||||
|
||||
void main()
|
||||
{
|
||||
float thisLaneData = _12.inputDataArray[gl_LocalInvocationID.x];
|
||||
bool laneActive = thisLaneData > 0.0;
|
||||
uint thisLaneOutputSlot = mbcntAMD(packUint2x32(uvec2(unpackUint2x32(ballotARB(laneActive)).xy)));
|
||||
int firstInvocation = readFirstInvocationARB(1);
|
||||
int invocation = readInvocationARB(1, 0u);
|
||||
vec3 swizzleInvocations = swizzleInvocationsAMD(vec3(0.0, 2.0, 1.0), uvec4(3u));
|
||||
vec3 swizzelInvocationsMasked = swizzleInvocationsMaskedAMD(vec3(0.0, 2.0, 1.0), uvec3(2u));
|
||||
vec3 writeInvocation = writeInvocationAMD(swizzleInvocations, swizzelInvocationsMasked, 0u);
|
||||
if (laneActive)
|
||||
{
|
||||
_74.outputDataArray[thisLaneOutputSlot] = thisLaneData;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_ballot : require
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
float addInvocations = addInvocationsNonUniformAMD(0.0);
|
||||
int minInvocations = minInvocationsNonUniformAMD(1);
|
||||
uint maxInvocations = uint(maxInvocationsNonUniformAMD(4));
|
||||
}
|
||||
|
18
reference/shaders/amd/shader_group_vote.comp
Normal file
18
reference/shaders/amd/shader_group_vote.comp
Normal file
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_group_vote : require
|
||||
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
layout(binding = 0, std430) buffer inputData
|
||||
{
|
||||
float inputDataArray[];
|
||||
} _12;
|
||||
|
||||
void main()
|
||||
{
|
||||
float thisLaneData = _12.inputDataArray[gl_LocalInvocationID.x];
|
||||
bool laneActive = thisLaneData > 0.0;
|
||||
bool allInvocations = allInvocationsARB(laneActive);
|
||||
bool anyInvocations = anyInvocationARB(laneActive);
|
||||
bool allInvocationsEqual = allInvocationsEqualARB(laneActive);
|
||||
}
|
||||
|
11
reference/shaders/amd/shader_trinary_minmax.comp
Normal file
11
reference/shaders/amd/shader_trinary_minmax.comp
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_trinary_minmax : require
|
||||
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
int t11 = min3(0, 3, 2);
|
||||
int t12 = max3(0, 3, 2);
|
||||
int t13 = mid3(0, 3, 2);
|
||||
}
|
||||
|
10
shaders/amd/fragmentMaskFetch_subpassInput.vk.nocompat.frag
Normal file
10
shaders/amd/fragmentMaskFetch_subpassInput.vk.nocompat.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_fragment_mask : require
|
||||
|
||||
layout(input_attachment_index = 0, binding = 0) uniform subpassInputMS t;
|
||||
|
||||
void main ()
|
||||
{
|
||||
vec4 test2 = fragmentFetchAMD(t, 4);
|
||||
uint testi2 = fragmentMaskFetchAMD(t);
|
||||
}
|
13
shaders/amd/fs.frag
Normal file
13
shaders/amd/fs.frag
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_fragment_mask : require
|
||||
#extension GL_AMD_shader_explicit_vertex_parameter : require
|
||||
|
||||
uniform sampler2DMS texture1;
|
||||
|
||||
void main ()
|
||||
{
|
||||
uint testi1 = fragmentMaskFetchAMD(texture1, ivec2(0));
|
||||
vec4 test1 = fragmentFetchAMD(texture1, ivec2(1), 2);
|
||||
|
||||
vec4 pos = interpolateAtVertexAMD(vec4(0.0), 0);
|
||||
}
|
13
shaders/amd/gcn_shader.comp
Normal file
13
shaders/amd/gcn_shader.comp
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#extension GL_AMD_gcn_shader : require
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
|
||||
layout (local_size_x = 64) in;
|
||||
|
||||
void main ()
|
||||
{
|
||||
float cubeFace = cubeFaceIndexAMD(vec3(0.0));
|
||||
vec2 cubeFaceCoord = cubeFaceCoordAMD(vec3(1.0));
|
||||
|
||||
uint64_t time = timeAMD();
|
||||
}
|
33
shaders/amd/shader_ballot.comp
Normal file
33
shaders/amd/shader_ballot.comp
Normal file
@ -0,0 +1,33 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_ballot : require
|
||||
#extension GL_ARB_shader_ballot : require
|
||||
|
||||
layout (local_size_x = 64) in;
|
||||
layout (std430, binding = 0) buffer inputData
|
||||
{
|
||||
float inputDataArray[];
|
||||
};
|
||||
|
||||
layout (std430, binding = 1) buffer outputData
|
||||
{
|
||||
float outputDataArray[];
|
||||
};
|
||||
|
||||
void main ()
|
||||
{
|
||||
float thisLaneData = inputDataArray [gl_LocalInvocationID.x];
|
||||
bool laneActive = (thisLaneData > 0);
|
||||
|
||||
uint thisLaneOutputSlot = mbcntAMD (ballotARB (laneActive));
|
||||
|
||||
int firstInvocation = readFirstInvocationARB(1);
|
||||
int invocation = readInvocationARB(1, 0);
|
||||
|
||||
vec3 swizzleInvocations = swizzleInvocationsAMD(vec3(0.0, 2.0, 1.0), uvec4(3));
|
||||
vec3 swizzelInvocationsMasked = swizzleInvocationsMaskedAMD(vec3(0.0, 2.0, 1.0), uvec3(2));
|
||||
vec3 writeInvocation = writeInvocationAMD(swizzleInvocations, swizzelInvocationsMasked, 0);
|
||||
|
||||
if (laneActive) {
|
||||
outputDataArray[thisLaneOutputSlot] = thisLaneData;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_ballot : require
|
||||
|
||||
void main ()
|
||||
{
|
||||
float addInvocations = addInvocationsNonUniformAMD(0.0);
|
||||
int minInvocations = minInvocationsNonUniformAMD(1);
|
||||
uint maxInvocations = maxInvocationsNonUniformAMD(4);
|
||||
}
|
18
shaders/amd/shader_group_vote.comp
Normal file
18
shaders/amd/shader_group_vote.comp
Normal file
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_group_vote : require
|
||||
|
||||
layout (local_size_x = 64) in;
|
||||
layout (std430, binding = 0) buffer inputData
|
||||
{
|
||||
float inputDataArray[];
|
||||
};
|
||||
|
||||
void main ()
|
||||
{
|
||||
float thisLaneData = inputDataArray [gl_LocalInvocationID.x];
|
||||
bool laneActive = (thisLaneData > 0);
|
||||
|
||||
bool allInvocations = allInvocationsARB(laneActive);
|
||||
bool anyInvocations = anyInvocationARB(laneActive);
|
||||
bool allInvocationsEqual = allInvocationsEqualARB(laneActive);
|
||||
}
|
11
shaders/amd/shader_trinary_minmax.comp
Normal file
11
shaders/amd/shader_trinary_minmax.comp
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_AMD_shader_trinary_minmax : require
|
||||
|
||||
layout (local_size_x = 64) in;
|
||||
|
||||
void main ()
|
||||
{
|
||||
int t11 = min3(0, 3, 2);
|
||||
int t12 = max3(0, 3, 2);
|
||||
int t13 = mid3(0, 3, 2);
|
||||
}
|
10
spirv.hpp
10
spirv.hpp
@ -938,6 +938,16 @@ enum Op {
|
||||
OpSubgroupAnyKHR = 4429,
|
||||
OpSubgroupAllEqualKHR = 4430,
|
||||
OpSubgroupReadInvocationKHR = 4432,
|
||||
OpGroupIAddNonUniformAMD = 5000,
|
||||
OpGroupFAddNonUniformAMD = 5001,
|
||||
OpGroupFMinNonUniformAMD = 5002,
|
||||
OpGroupUMinNonUniformAMD = 5003,
|
||||
OpGroupSMinNonUniformAMD = 5004,
|
||||
OpGroupFMaxNonUniformAMD = 5005,
|
||||
OpGroupUMaxNonUniformAMD = 5006,
|
||||
OpGroupSMaxNonUniformAMD = 5007,
|
||||
OpFragmentMaskFetchAMD = 5011,
|
||||
OpFragmentFetchAMD = 5012,
|
||||
OpMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -326,7 +326,11 @@ struct SPIRExtension : IVariant
|
||||
enum Extension
|
||||
{
|
||||
Unsupported,
|
||||
GLSL
|
||||
GLSL,
|
||||
SPV_AMD_shader_ballot,
|
||||
SPV_AMD_shader_explicit_vertex_parameter,
|
||||
SPV_AMD_shader_trinary_minmax,
|
||||
SPV_AMD_gcn_shader
|
||||
};
|
||||
|
||||
SPIRExtension(Extension ext_)
|
||||
|
@ -1324,6 +1324,14 @@ void Compiler::parse(const Instruction &instruction)
|
||||
auto ext = extract_string(spirv, instruction.offset + 1);
|
||||
if (ext == "GLSL.std.450")
|
||||
set<SPIRExtension>(id, SPIRExtension::GLSL);
|
||||
else if (ext == "SPV_AMD_shader_ballot")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_ballot);
|
||||
else if (ext == "SPV_AMD_shader_explicit_vertex_parameter")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter);
|
||||
else if (ext == "SPV_AMD_shader_trinary_minmax")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_shader_trinary_minmax);
|
||||
else if (ext == "SPV_AMD_gcn_shader")
|
||||
set<SPIRExtension>(id, SPIRExtension::SPV_AMD_gcn_shader);
|
||||
else
|
||||
set<SPIRExtension>(id, SPIRExtension::Unsupported);
|
||||
|
||||
|
309
spirv_glsl.cpp
309
spirv_glsl.cpp
@ -3868,6 +3868,142 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t)
|
||||
{
|
||||
require_extension("GL_AMD_shader_ballot");
|
||||
|
||||
enum AMDShaderBallot {
|
||||
SwizzleInvocationsAMD = 1,
|
||||
SwizzleInvocationsMaskedAMD = 2,
|
||||
WriteInvocationAMD = 3,
|
||||
MbcntAMD = 4
|
||||
};
|
||||
|
||||
auto op = static_cast<AMDShaderBallot>(eop);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case SwizzleInvocationsAMD:
|
||||
emit_binary_func_op(result_type, id, args[0], args[1], "swizzleInvocationsAMD");
|
||||
break;
|
||||
|
||||
case SwizzleInvocationsMaskedAMD:
|
||||
emit_binary_func_op(result_type, id, args[0], args[1], "swizzleInvocationsMaskedAMD");
|
||||
break;
|
||||
|
||||
case WriteInvocationAMD:
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "writeInvocationAMD");
|
||||
break;
|
||||
|
||||
case MbcntAMD:
|
||||
emit_unary_func_op(result_type, id, args[0], "mbcntAMD");
|
||||
break;
|
||||
|
||||
default:
|
||||
statement("// unimplemented SPV AMD shader ballot op ", eop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_spv_amd_shader_explicit_vertex_parameter_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t)
|
||||
{
|
||||
require_extension("GL_AMD_shader_explicit_vertex_parameter");
|
||||
|
||||
enum AMDShaderExplicitVertexParameter {
|
||||
InterpolateAtVertexAMD = 1
|
||||
};
|
||||
|
||||
auto op = static_cast<AMDShaderExplicitVertexParameter>(eop);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case InterpolateAtVertexAMD:
|
||||
emit_binary_func_op(result_type, id, args[0], args[1], "interpolateAtVertexAMD");
|
||||
break;
|
||||
|
||||
default:
|
||||
statement("// unimplemented SPV AMD shader explicit vertex parameter op ", eop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_spv_amd_shader_trinary_minmax_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t)
|
||||
{
|
||||
require_extension("GL_AMD_shader_trinary_minmax");
|
||||
|
||||
enum AMDShaderTrinaryMinMax {
|
||||
FMin3AMD = 1,
|
||||
UMin3AMD = 2,
|
||||
SMin3AMD = 3,
|
||||
FMax3AMD = 4,
|
||||
UMax3AMD = 5,
|
||||
SMax3AMD = 6,
|
||||
FMid3AMD = 7,
|
||||
UMid3AMD = 8,
|
||||
SMid3AMD = 9
|
||||
};
|
||||
|
||||
auto op = static_cast<AMDShaderTrinaryMinMax>(eop);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case FMin3AMD:
|
||||
case UMin3AMD:
|
||||
case SMin3AMD:
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "min3");
|
||||
break;
|
||||
|
||||
case FMax3AMD:
|
||||
case UMax3AMD:
|
||||
case SMax3AMD:
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "max3");
|
||||
break;
|
||||
|
||||
case FMid3AMD:
|
||||
case UMid3AMD:
|
||||
case SMid3AMD:
|
||||
emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "mid3");
|
||||
break;
|
||||
|
||||
default:
|
||||
statement("// unimplemented SPV AMD shader trinary minmax op ", eop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::emit_spv_amd_gcn_shader_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t)
|
||||
{
|
||||
require_extension("GL_AMD_gcn_shader");
|
||||
|
||||
enum AMDGCNShader {
|
||||
CubeFaceIndexAMD = 1,
|
||||
CubeFaceCoordAMD = 2,
|
||||
TimeAMD = 3
|
||||
};
|
||||
|
||||
auto op = static_cast<AMDGCNShader>(eop);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case CubeFaceIndexAMD:
|
||||
emit_unary_func_op(result_type, id, args[0], "cubeFaceIndexAMD");
|
||||
break;
|
||||
case CubeFaceCoordAMD:
|
||||
emit_unary_func_op(result_type, id, args[0], "cubeFaceCoordAMD");
|
||||
break;
|
||||
case TimeAMD:
|
||||
{
|
||||
string expr = "timeAMD()";
|
||||
emit_op(result_type, id, expr, true);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
statement("// unimplemented SPV AMD gcn shader op ", eop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerGLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in_type)
|
||||
{
|
||||
if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Int)
|
||||
@ -3894,6 +4030,11 @@ string CompilerGLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
|
||||
return "int64BitsToDouble";
|
||||
else if (out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::UInt64)
|
||||
return "uint64BitsToDouble";
|
||||
else if (out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::UInt && in_type.vecsize == 2)
|
||||
{
|
||||
require_extension("GL_ARB_gpu_shader_int64");
|
||||
return "packUint2x32";
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
@ -4225,6 +4366,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
}
|
||||
else
|
||||
SPIRV_CROSS_THROW("Cannot subdivide a scalar value!");
|
||||
|
||||
}
|
||||
|
||||
if (pending_array_enclose)
|
||||
@ -6372,13 +6514,176 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
case OpExtInst:
|
||||
{
|
||||
uint32_t extension_set = ops[2];
|
||||
if (get<SPIRExtension>(extension_set).ext != SPIRExtension::GLSL)
|
||||
|
||||
if (get<SPIRExtension>(extension_set).ext == SPIRExtension::GLSL)
|
||||
{
|
||||
emit_glsl_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
}
|
||||
else if (get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_shader_ballot)
|
||||
{
|
||||
emit_spv_amd_shader_ballot_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
}
|
||||
else if (get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter)
|
||||
{
|
||||
emit_spv_amd_shader_explicit_vertex_parameter_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
}
|
||||
else if (get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_shader_trinary_minmax)
|
||||
{
|
||||
emit_spv_amd_shader_trinary_minmax_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
}
|
||||
else if (get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_gcn_shader)
|
||||
{
|
||||
emit_spv_amd_gcn_shader_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
}
|
||||
else {
|
||||
statement("// unimplemented ext op ", instruction.op);
|
||||
break;
|
||||
}
|
||||
|
||||
emit_glsl_op(ops[0], ops[1], ops[3], &ops[4], length - 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupBallotKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
string expr;
|
||||
expr = join("unpackUint2x32(ballotARB(" + to_expression(ops[2]) +"))");
|
||||
emit_op(result_type, id, expr, true);
|
||||
|
||||
require_extension("GL_ARB_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupFirstInvocationKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[2], "readFirstInvocationARB");
|
||||
|
||||
require_extension("GL_ARB_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupReadInvocationKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_binary_func_op(result_type, id, ops[2], ops[3], "readInvocationARB");
|
||||
|
||||
require_extension("GL_ARB_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupAllKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[2], "allInvocationsARB");
|
||||
|
||||
require_extension("GL_ARB_shader_group_vote");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupAnyKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[2], "anyInvocationARB");
|
||||
|
||||
require_extension("GL_ARB_shader_group_vote");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpSubgroupAllEqualKHR:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[2], "allInvocationsEqualARB");
|
||||
|
||||
require_extension("GL_ARB_shader_group_vote");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpGroupIAddNonUniformAMD:
|
||||
case OpGroupFAddNonUniformAMD:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[4], "addInvocationsNonUniformAMD");
|
||||
|
||||
require_extension("GL_AMD_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpGroupFMinNonUniformAMD:
|
||||
case OpGroupUMinNonUniformAMD:
|
||||
case OpGroupSMinNonUniformAMD:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[4], "minInvocationsNonUniformAMD");
|
||||
|
||||
require_extension("GL_AMD_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpGroupFMaxNonUniformAMD:
|
||||
case OpGroupUMaxNonUniformAMD:
|
||||
case OpGroupSMaxNonUniformAMD:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
emit_unary_func_op(result_type, id, ops[4], "maxInvocationsNonUniformAMD");
|
||||
|
||||
require_extension("GL_AMD_shader_ballot");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFragmentMaskFetchAMD:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
|
||||
if (type.image.dim == spv::DimSubpassData)
|
||||
{
|
||||
emit_unary_func_op(result_type, id, ops[2], "fragmentMaskFetchAMD");
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_binary_func_op(result_type, id, ops[2], ops[3], "fragmentMaskFetchAMD");
|
||||
}
|
||||
|
||||
require_extension("GL_AMD_shader_fragment_mask");
|
||||
break;
|
||||
}
|
||||
|
||||
case OpFragmentFetchAMD:
|
||||
{
|
||||
auto &type = expression_type(ops[2]);
|
||||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
|
||||
if (type.image.dim == spv::DimSubpassData)
|
||||
{
|
||||
emit_binary_func_op(result_type, id, ops[2], ops[4], "fragmentFetchAMD");
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_trinary_func_op(result_type, id, ops[2], ops[3], ops[4], "fragmentFetchAMD");
|
||||
}
|
||||
|
||||
require_extension("GL_AMD_shader_fragment_mask");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace spirv_cross
|
||||
@ -189,6 +190,14 @@ protected:
|
||||
void emit_block_instructions(const SPIRBlock &block);
|
||||
virtual void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_spv_amd_shader_explicit_vertex_parameter_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_spv_amd_shader_trinary_minmax_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_spv_amd_gcn_shader_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count);
|
||||
virtual void emit_header();
|
||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||
virtual void emit_texture_op(const Instruction &i);
|
||||
@ -445,7 +454,7 @@ protected:
|
||||
std::unordered_map<uint32_t, uint32_t> expression_usage_counts;
|
||||
void track_expression_read(uint32_t id);
|
||||
|
||||
std::unordered_set<std::string> forced_extensions;
|
||||
std::set<std::string> forced_extensions;
|
||||
std::vector<std::string> header_lines;
|
||||
|
||||
uint32_t statement_count;
|
||||
|
Loading…
Reference in New Issue
Block a user