Implement the extension GL_AMD_shader_fragment_mask

This commit is contained in:
amhagan
2017-06-13 16:53:02 -04:00
committed by Rex Xu
parent d004e5ca4c
commit 05506bb874
12 changed files with 288 additions and 8 deletions

View File

@@ -33,7 +33,7 @@ enum Decoration;
enum Op;
static const int GLSLextAMDVersion = 100;
static const int GLSLextAMDRevision = 5;
static const int GLSLextAMDRevision = 6;
// SPV_AMD_shader_ballot
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
@@ -106,4 +106,12 @@ static const char* const E_SPV_AMD_shader_image_load_store_lod = "SPV_AMD_shader
static const Capability CapabilityImageReadWriteLodAMD = static_cast<Capability>(5015);
// SPV_AMD_shader_fragment_mask
static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
static const Capability CapabilityFragmentMaskAMD = static_cast<Capability>(5010);
static const Op OpFragmentMaskFetchAMD = static_cast<Op>(5011);
static const Op OpFragmentFetchAMD = static_cast<Op>(5012);
#endif // #ifndef GLSLextAMD_H

View File

@@ -3204,9 +3204,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
glslang::TCrackedTextureOp cracked;
node->crackTexture(sampler, cracked);
const bool isUnsignedResult =
node->getType().getBasicType() == glslang::EbtUint64 ||
node->getType().getBasicType() == glslang::EbtUint;
const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint;
// Check for queries
if (cracked.query) {
@@ -3358,6 +3356,45 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
}
}
#ifdef AMD_EXTENSIONS
// Check for fragment mask functions other than queries
if (cracked.fragMask) {
assert(sampler.ms);
auto opIt = arguments.begin();
std::vector<spv::Id> operands;
// Extract the image if necessary
if (builder.isSampledImage(params.sampler))
params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
operands.push_back(params.sampler);
++opIt;
if (sampler.isSubpass()) {
// add on the (0,0) coordinate
spv::Id zero = builder.makeIntConstant(0);
std::vector<spv::Id> comps;
comps.push_back(zero);
comps.push_back(zero);
operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps));
}
for (; opIt != arguments.end(); ++opIt)
operands.push_back(*opIt);
spv::Op fragMaskOp = spv::OpNop;
if (node->getOp() == glslang::EOpFragmentMaskFetch)
fragMaskOp = spv::OpFragmentMaskFetchAMD;
else if (node->getOp() == glslang::EOpFragmentFetch)
fragMaskOp = spv::OpFragmentFetchAMD;
builder.addExtension(spv::E_SPV_AMD_shader_fragment_mask);
builder.addCapability(spv::CapabilityFragmentMaskAMD);
return builder.createOp(fragMaskOp, resultType(), operands);
}
#endif
// Check for texture functions other than queries
bool sparse = node->isSparseTexture();
bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;

View File

@@ -847,6 +847,7 @@ const char* CapabilityString(int info)
#ifdef AMD_EXTENSIONS
case 5009: return "ImageGatherBiasLodAMD";
case 5010: return "FragmentMaskAMD";
case 5015: return "ImageReadWriteLodAMD";
#endif
@@ -1207,6 +1208,9 @@ const char* OpcodeString(int op)
case 5005: return "OpGroupFMaxNonUniformAMD";
case 5006: return "OpGroupUMaxNonUniformAMD";
case 5007: return "OpGroupSMaxNonUniformAMD";
case 5011: return "OpFragmentMaskFetchAMD";
case 5012: return "OpFragmentFetchAMD";
#endif
case OpcodeCeiling:
@@ -2869,6 +2873,15 @@ void Parameterize()
InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'");
InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandId, "X");
InstructionDesc[OpFragmentMaskFetchAMD].capabilities.push_back(CapabilityFragmentMaskAMD);
InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Image'");
InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpFragmentFetchAMD].capabilities.push_back(CapabilityFragmentMaskAMD);
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'");
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'");
#endif
}