Implement the extension GL_AMD_gpu_shader_half_float_fetch
- Support new opaque types: f16sampler*, f16image*, f16subpassInput*.
- Add new built-in GLSL texture/image functions.
diff --git a/SPIRV/GLSL.ext.AMD.h b/SPIRV/GLSL.ext.AMD.h
index d4f57ef..e20642b 100644
--- a/SPIRV/GLSL.ext.AMD.h
+++ b/SPIRV/GLSL.ext.AMD.h
@@ -27,13 +27,8 @@
#ifndef GLSLextAMD_H
#define GLSLextAMD_H
-enum BuiltIn;
-enum Capability;
-enum Decoration;
-enum Op;
-
static const int GLSLextAMDVersion = 100;
-static const int GLSLextAMDRevision = 6;
+static const int GLSLextAMDRevision = 7;
// SPV_AMD_shader_ballot
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
@@ -107,4 +102,10 @@
// SPV_AMD_shader_fragment_mask
static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
+// SPV_AMD_gpu_shader_half_float_fetch
+static const char* const E_SPV_AMD_gpu_shader_half_float_fetch = "SPV_AMD_gpu_shader_half_float_fetch";
+
+enum Capability;
+static const Capability CapabilityFloat16ImageAMD = static_cast<Capability>(5008);
+
#endif // #ifndef GLSLextAMD_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 420c38e..92c60a8 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2340,6 +2340,12 @@
{
switch (sampler.type) {
case glslang::EbtFloat: return builder.makeFloatType(32);
+#ifdef AMD_EXTENSIONS
+ case glslang::EbtFloat16:
+ builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
+ builder.addCapability(spv::CapabilityFloat16ImageAMD);
+ return builder.makeFloatType(16);
+#endif
case glslang::EbtInt: return builder.makeIntType(32);
case glslang::EbtUint: return builder.makeUintType(32);
default:
@@ -3159,9 +3165,15 @@
glslang::TSampler sampler = {};
bool cubeCompare = false;
+#ifdef AMD_EXTENSIONS
+ bool f16ShadowCompare = false;
+#endif
if (node.isTexture() || node.isImage()) {
sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
+#ifdef AMD_EXTENSIONS
+ f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
+#endif
}
for (int i = 0; i < (int)glslangArguments.size(); ++i) {
@@ -3186,6 +3198,21 @@
if ((sampler.ms && i == 3) || (! sampler.ms && i == 2))
lvalue = true;
break;
+#ifdef AMD_EXTENSIONS
+ case glslang::EOpSparseTexture:
+ if (((cubeCompare || f16ShadowCompare) && i == 3) || (! (cubeCompare || f16ShadowCompare) && i == 2))
+ lvalue = true;
+ break;
+ case glslang::EOpSparseTextureClamp:
+ if (((cubeCompare || f16ShadowCompare) && i == 4) || (! (cubeCompare || f16ShadowCompare) && i == 3))
+ lvalue = true;
+ break;
+ case glslang::EOpSparseTextureLod:
+ case glslang::EOpSparseTextureOffset:
+ if ((f16ShadowCompare && i == 4) || (! f16ShadowCompare && i == 3))
+ lvalue = true;
+ break;
+#else
case glslang::EOpSparseTexture:
if ((cubeCompare && i == 3) || (! cubeCompare && i == 2))
lvalue = true;
@@ -3199,6 +3226,7 @@
if (i == 3)
lvalue = true;
break;
+#endif
case glslang::EOpSparseTextureFetch:
if ((sampler.dim != glslang::EsdRect && i == 3) || (sampler.dim == glslang::EsdRect && i == 2))
lvalue = true;
@@ -3207,6 +3235,23 @@
if ((sampler.dim != glslang::EsdRect && i == 4) || (sampler.dim == glslang::EsdRect && i == 3))
lvalue = true;
break;
+#ifdef AMD_EXTENSIONS
+ case glslang::EOpSparseTextureLodOffset:
+ case glslang::EOpSparseTextureGrad:
+ case glslang::EOpSparseTextureOffsetClamp:
+ if ((f16ShadowCompare && i == 5) || (! f16ShadowCompare && i == 4))
+ lvalue = true;
+ break;
+ case glslang::EOpSparseTextureGradOffset:
+ case glslang::EOpSparseTextureGradClamp:
+ if ((f16ShadowCompare && i == 6) || (! f16ShadowCompare && i == 5))
+ lvalue = true;
+ break;
+ case glslang::EOpSparseTextureGradOffsetClamp:
+ if ((f16ShadowCompare && i == 7) || (! f16ShadowCompare && i == 6))
+ lvalue = true;
+ break;
+#else
case glslang::EOpSparseTextureLodOffset:
case glslang::EOpSparseTextureGrad:
case glslang::EOpSparseTextureOffsetClamp:
@@ -3222,6 +3267,7 @@
if (i == 6)
lvalue = true;
break;
+#endif
case glslang::EOpSparseTextureGather:
if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2))
lvalue = true;
@@ -3274,6 +3320,12 @@
// Process a GLSL texturing op (will be SPV image)
const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler()
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler();
+#ifdef AMD_EXTENSIONS
+ bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
+ ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
+ : false;
+#endif
+
std::vector<spv::Id> arguments;
if (node->getAsAggregate())
translateArguments(*node->getAsAggregate(), arguments);
@@ -3517,6 +3569,9 @@
#ifdef AMD_EXTENSIONS
if (cracked.gather)
++nonBiasArgCount; // comp argument should be present when bias argument is present
+
+ if (f16ShadowCompare)
+ ++nonBiasArgCount;
#endif
if (cracked.offset)
++nonBiasArgCount;
@@ -3560,7 +3615,11 @@
bool noImplicitLod = false;
// sort out where Dref is coming from
+#ifdef AMD_EXTENSIONS
+ if (cubeCompare || f16ShadowCompare) {
+#else
if (cubeCompare) {
+#endif
params.Dref = arguments[2];
++extraArgs;
} else if (sampler.shadow && cracked.gather) {
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 8d1bfb9..c303c65 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1751,7 +1751,11 @@
break;
}
case OpImageQueryLod:
+#ifdef AMD_EXTENSIONS
+ resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2);
+#else
resultType = makeVectorType(makeFloatType(32), 2);
+#endif
break;
case OpImageQueryLevels:
case OpImageQuerySamples:
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index cbdaf79..3629396 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -849,6 +849,7 @@
case 5013: return "StencilExportEXT";
#ifdef AMD_EXTENSIONS
+ case 5008: return "Float16ImageAMD";
case 5009: return "ImageGatherBiasLodAMD";
case 5010: return "FragmentMaskAMD";
case 5015: return "ImageReadWriteLodAMD";