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
}

View File

@ -0,0 +1,123 @@
spv.shaderFragMaskAMD.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 80
Capability Shader
Capability StorageImageMultisample
Capability InputAttachment
Capability FragmentMaskAMD
Extension "SPV_AMD_shader_fragment_mask"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 78
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_AMD_shader_fragment_mask"
Name 4 "main"
Name 9 "f4"
Name 14 "fragMask"
Name 18 "s2DMS"
Name 27 "fragIndex"
Name 42 "is2DMSArray"
Name 62 "usubpassMS"
Name 78 "fragColor"
Decorate 18(s2DMS) DescriptorSet 0
Decorate 18(s2DMS) Binding 0
Decorate 42(is2DMSArray) DescriptorSet 0
Decorate 42(is2DMSArray) Binding 1
Decorate 62(usubpassMS) DescriptorSet 0
Decorate 62(usubpassMS) Binding 2
Decorate 62(usubpassMS) InputAttachmentIndex 0
Decorate 78(fragColor) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
10: 6(float) Constant 0
11: 7(fvec4) ConstantComposite 10 10 10 10
12: TypeInt 32 0
13: TypePointer Function 12(int)
15: TypeImage 6(float) 2D multi-sampled sampled format:Unknown
16: TypeSampledImage 15
17: TypePointer UniformConstant 16
18(s2DMS): 17(ptr) Variable UniformConstant
20: TypeInt 32 1
21: TypeVector 20(int) 2
22: 20(int) Constant 2
23: 20(int) Constant 3
24: 21(ivec2) ConstantComposite 22 23
29: 12(int) Constant 240
31: 20(int) Constant 4
34: 12(int) Constant 1
39: TypeImage 20(int) 2D array multi-sampled sampled format:Unknown
40: TypeSampledImage 39
41: TypePointer UniformConstant 40
42(is2DMSArray): 41(ptr) Variable UniformConstant
44: TypeVector 20(int) 3
45: 20(int) Constant 1
46: 44(ivec3) ConstantComposite 22 23 45
55: TypeVector 20(int) 4
60: TypeImage 12(int) SubpassData multi-sampled nonsampled format:Unknown
61: TypePointer UniformConstant 60
62(usubpassMS): 61(ptr) Variable UniformConstant
64: 20(int) Constant 0
65: 21(ivec2) ConstantComposite 64 64
72: TypeVector 12(int) 4
77: TypePointer Output 7(fvec4)
78(fragColor): 77(ptr) Variable Output
4(main): 2 Function None 3
5: Label
9(f4): 8(ptr) Variable Function
14(fragMask): 13(ptr) Variable Function
27(fragIndex): 13(ptr) Variable Function
Store 9(f4) 11
19: 16 Load 18(s2DMS)
25: 15 Image 19
26: 12(int) FragmentMaskFetchAMD 25 24
Store 14(fragMask) 26
28: 12(int) Load 14(fragMask)
30: 12(int) BitwiseAnd 28 29
32: 12(int) ShiftRightLogical 30 31
Store 27(fragIndex) 32
33: 16 Load 18(s2DMS)
35: 15 Image 33
36: 7(fvec4) FragmentFetchAMD 35 24 34
37: 7(fvec4) Load 9(f4)
38: 7(fvec4) FAdd 37 36
Store 9(f4) 38
43: 40 Load 42(is2DMSArray)
47: 39 Image 43
48: 12(int) FragmentMaskFetchAMD 47 46
Store 14(fragMask) 48
49: 12(int) Load 14(fragMask)
50: 12(int) BitwiseAnd 49 29
51: 12(int) ShiftRightLogical 50 31
Store 27(fragIndex) 51
52: 40 Load 42(is2DMSArray)
53: 12(int) Load 27(fragIndex)
54: 39 Image 52
56: 55(ivec4) FragmentFetchAMD 54 46 53
57: 7(fvec4) ConvertSToF 56
58: 7(fvec4) Load 9(f4)
59: 7(fvec4) FAdd 58 57
Store 9(f4) 59
63: 60 Load 62(usubpassMS)
66: 12(int) FragmentMaskFetchAMD 63 65
Store 14(fragMask) 66
67: 12(int) Load 14(fragMask)
68: 12(int) BitwiseAnd 67 29
69: 12(int) ShiftRightLogical 68 31
Store 27(fragIndex) 69
70: 60 Load 62(usubpassMS)
71: 12(int) Load 27(fragIndex)
73: 72(ivec4) FragmentFetchAMD 70 65 71
74: 7(fvec4) ConvertUToF 73
75: 7(fvec4) Load 9(f4)
76: 7(fvec4) FAdd 75 74
Store 9(f4) 76
79: 7(fvec4) Load 9(f4)
Store 78(fragColor) 79
Return
FunctionEnd

View File

@ -0,0 +1,29 @@
#version 450 core
#extension GL_AMD_shader_fragment_mask: enable
layout(binding = 0) uniform sampler2DMS s2DMS;
layout(binding = 1) uniform isampler2DMSArray is2DMSArray;
layout(binding = 2, input_attachment_index = 0) uniform usubpassInputMS usubpassMS;
layout(location = 0) out vec4 fragColor;
void main()
{
vec4 f4 = vec4(0.0);
uint fragMask = fragmentMaskFetchAMD(s2DMS, ivec2(2, 3));
uint fragIndex = (fragMask & 0xF0) >> 4;
f4 += fragmentFetchAMD(s2DMS, ivec2(2, 3), 1);
fragMask = fragmentMaskFetchAMD(is2DMSArray, ivec3(2, 3, 1));
fragIndex = (fragMask & 0xF0) >> 4;
f4 += fragmentFetchAMD(is2DMSArray, ivec3(2, 3, 1), fragIndex);
fragMask = fragmentMaskFetchAMD(usubpassMS);
fragIndex = (fragMask & 0xF0) >> 4;
f4 += fragmentFetchAMD(usubpassMS, fragIndex);
fragColor = f4;
}

View File

@ -198,6 +198,7 @@ enum TBuiltInVariable {
EbvSamplePosition,
EbvSampleMask,
EbvHelperInvocation,
#ifdef AMD_EXTENSIONS
EbvBaryCoordNoPersp,
EbvBaryCoordNoPerspCentroid,
@ -334,6 +335,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvSamplePosition: return "SamplePosition";
case EbvSampleMask: return "SampleMaskIn";
case EbvHelperInvocation: return "HelperInvocation";
#ifdef AMD_EXTENSIONS
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";

View File

@ -653,6 +653,8 @@ enum TOperator {
EOpTextureGatherLod,
EOpTextureGatherLodOffset,
EOpTextureGatherLodOffsets,
EOpFragmentMaskFetch,
EOpFragmentFetch,
#endif
EOpSparseTextureGuardBegin,
@ -1032,6 +1034,9 @@ struct TCrackedTextureOp {
bool grad;
bool subpass;
bool lodClamp;
#ifdef AMD_EXTENSIONS
bool fragMask;
#endif
};
//
@ -1079,6 +1084,9 @@ public:
cracked.grad = false;
cracked.subpass = false;
cracked.lodClamp = false;
#ifdef AMD_EXTENSIONS
cracked.fragMask = false;
#endif
switch (op) {
case EOpImageQuerySize:
@ -1210,6 +1218,14 @@ public:
case EOpSparseImageLoadLod:
cracked.lod = true;
break;
case EOpFragmentMaskFetch:
cracked.subpass = sampler.dim == EsdSubpass;
cracked.fragMask = true;
break;
case EOpFragmentFetch:
cracked.subpass = sampler.dim == EsdSubpass;
cracked.fragMask = true;
break;
#endif
case EOpSubpassLoad:
case EOpSubpassLoadMS:

View File

@ -2283,7 +2283,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"float cubeFaceIndexAMD(vec3);"
"vec2 cubeFaceCoordAMD(vec3);"
"vec2 cubeFaceCoordAMD(vec3);"
"uint64_t timeAMD();"
"\n");
@ -2787,6 +2787,29 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// GL_AMD_shader_fragment_mask
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"uint fragmentMaskFetchAMD(sampler2DMS, ivec2);"
"uint fragmentMaskFetchAMD(isampler2DMS, ivec2);"
"uint fragmentMaskFetchAMD(usampler2DMS, ivec2);"
"uint fragmentMaskFetchAMD(sampler2DMSArray, ivec3);"
"uint fragmentMaskFetchAMD(isampler2DMSArray, ivec3);"
"uint fragmentMaskFetchAMD(usampler2DMSArray, ivec3);"
"vec4 fragmentFetchAMD(sampler2DMS, ivec2, uint);"
"ivec4 fragmentFetchAMD(isampler2DMS, ivec2, uint);"
"uvec4 fragmentFetchAMD(usampler2DMS, ivec2, uint);"
"vec4 fragmentFetchAMD(sampler2DMSArray, ivec3, uint);"
"ivec4 fragmentFetchAMD(isampler2DMSArray, ivec3, uint);"
"uvec4 fragmentFetchAMD(usampler2DMSArray, ivec3, uint);"
"\n");
}
#endif
//============================================================================
@ -3126,6 +3149,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
// GL_AMD_shader_fragment_mask
if (profile != EEsProfile && version >= 450 && spvVersion.vulkan >= 100) {
stageBuiltins[EShLangFragment].append(
"uint fragmentMaskFetchAMD(subpassInputMS);"
"uint fragmentMaskFetchAMD(isubpassInputMS);"
"uint fragmentMaskFetchAMD(usubpassInputMS);"
"vec4 fragmentFetchAMD(subpassInputMS, uint);"
"ivec4 fragmentFetchAMD(isubpassInputMS, uint);"
"uvec4 fragmentFetchAMD(usubpassInputMS, uint);"
"\n");
}
#endif
//============================================================================
@ -5372,6 +5409,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("cubeFaceCoordAMD", 1, &E_GL_AMD_gcn_shader);
symbolTable.setFunctionExtensions("timeAMD", 1, &E_GL_AMD_gcn_shader);
}
if (profile != EEsProfile) {
symbolTable.setFunctionExtensions("fragmentMaskFetchAMD", 1, &E_GL_AMD_shader_fragment_mask);
symbolTable.setFunctionExtensions("fragmentFetchAMD", 1, &E_GL_AMD_shader_fragment_mask);
}
#endif
// Compatibility variables, vertex only
@ -6210,6 +6252,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("imageLoadLodAMD", EOpImageLoadLod);
symbolTable.relateToOperator("imageStoreLodAMD", EOpImageStoreLod);
symbolTable.relateToOperator("sparseImageLoadLodAMD", EOpSparseImageLoadLod);
symbolTable.relateToOperator("fragmentMaskFetchAMD", EOpFragmentMaskFetch);
symbolTable.relateToOperator("fragmentFetchAMD", EOpFragmentFetch);
#endif
}
if (profile == EEsProfile) {

View File

@ -201,6 +201,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_AMD_texture_gather_bias_lod] = EBhDisable;
extensionBehavior[E_GL_AMD_gpu_shader_int16] = EBhDisable;
extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable;
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
#endif
#ifdef NV_EXTENSIONS
@ -333,6 +334,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_AMD_texture_gather_bias_lod 1\n"
"#define GL_AMD_gpu_shader_int16 1\n"
"#define GL_AMD_shader_image_load_store_lod 1\n"
"#define GL_AMD_shader_fragment_mask 1\n"
#endif
#ifdef NV_EXTENSIONS

View File

@ -171,6 +171,7 @@ const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_sh
const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod";
const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16";
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
#endif
#ifdef NV_EXTENSIONS

View File

@ -431,10 +431,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpMaxInvocationsExclusiveScanNonUniform: out.debug << "maxInvocationsExclusiveScanNonUniform"; break;
case EOpAddInvocationsExclusiveScanNonUniform: out.debug << "addInvocationsExclusiveScanNonUniform"; break;
case EOpMbcnt: out.debug << "mbcnt"; break;
case EOpMbcnt: out.debug << "mbcnt"; break;
case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
case EOpFragmentMaskFetch: out.debug << "fragmentMaskFetchAMD"; break;
case EOpFragmentFetch: out.debug << "fragmentFetchAMD"; break;
case EOpConvBoolToFloat16: out.debug << "Convert bool to float16"; break;
case EOpConvIntToFloat16: out.debug << "Convert int to float16"; break;

View File

@ -409,6 +409,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.imageLoadStoreLod.frag",
"spv.int16.frag",
"spv.shaderBallotAMD.comp",
"spv.shaderFragMaskAMD.frag",
"spv.textureGatherBiasLod.frag"
})),
FileNameAsCustomTestSuffix