Merge pull request #1595 from dgkoch/EXT_fragment_invocation_density
Implement GL_EXT_fragment_invocation_density
diff --git a/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h
index c4a2430..e29c055 100644
--- a/SPIRV/GLSL.ext.EXT.h
+++ b/SPIRV/GLSL.ext.EXT.h
@@ -28,10 +28,11 @@
#define GLSLextEXT_H
static const int GLSLextEXTVersion = 100;
-static const int GLSLextEXTRevision = 1;
+static const int GLSLextEXTRevision = 2;
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
+static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
#endif // #ifndef GLSLextEXT_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 2e2a2fe..5c00024 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -833,6 +833,16 @@
builder.addCapability(spv::CapabilityMultiView);
return spv::BuiltInViewIndex;
+ case glslang::EbvFragSizeEXT:
+ builder.addExtension(spv::E_SPV_EXT_fragment_invocation_density);
+ builder.addCapability(spv::CapabilityFragmentDensityEXT);
+ return spv::BuiltInFragSizeEXT;
+
+ case glslang::EbvFragInvocationCountEXT:
+ builder.addExtension(spv::E_SPV_EXT_fragment_invocation_density);
+ builder.addCapability(spv::CapabilityFragmentDensityEXT);
+ return spv::BuiltInFragInvocationCountEXT;
+
#ifdef NV_EXTENSIONS
case glslang::EbvViewportMaskNV:
if (!memberDeclaration) {
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 4f7c198..b0b01fb 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -388,12 +388,15 @@
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
- case BuiltInFragmentSizeNV: return "FragmentSizeNV";
- case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV";
+// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
+// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
#endif
+ case BuiltInFragSizeEXT: return "FragSizeEXT";
+ case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
+
case 5264: return "FullyCoveredEXT";
@@ -897,8 +900,9 @@
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV";
- case CapabilityShadingRateNV: return "ShadingRateNV";
+// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT
#endif
+ case CapabilityFragmentDensityEXT: return "FragmentDensityEXT";
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
diff --git a/Test/baseResults/spv.fragmentDensity-es.frag.out b/Test/baseResults/spv.fragmentDensity-es.frag.out
new file mode 100644
index 0000000..01ac383
--- /dev/null
+++ b/Test/baseResults/spv.fragmentDensity-es.frag.out
@@ -0,0 +1,45 @@
+spv.fragmentDensity-es.frag
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 18
+
+ Capability Shader
+ Capability FragmentDensityEXT
+ Extension "SPV_EXT_fragment_invocation_density"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 9 11 14 16
+ ExecutionMode 4 OriginUpperLeft
+ Source ESSL 310
+ SourceExtension "GL_EXT_fragment_invocation_density"
+ Name 4 "main"
+ Name 9 "FragSize"
+ Name 11 "gl_FragSizeEXT"
+ Name 14 "FragInvocationCount"
+ Name 16 "gl_FragInvocationCountEXT"
+ Decorate 9(FragSize) Location 0
+ Decorate 11(gl_FragSizeEXT) Flat
+ Decorate 11(gl_FragSizeEXT) BuiltIn FragSizeEXT
+ Decorate 14(FragInvocationCount) Location 2
+ Decorate 16(gl_FragInvocationCountEXT) Flat
+ Decorate 16(gl_FragInvocationCountEXT) BuiltIn FragInvocationCountEXT
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypeVector 6(int) 2
+ 8: TypePointer Output 7(ivec2)
+ 9(FragSize): 8(ptr) Variable Output
+ 10: TypePointer Input 7(ivec2)
+11(gl_FragSizeEXT): 10(ptr) Variable Input
+ 13: TypePointer Output 6(int)
+14(FragInvocationCount): 13(ptr) Variable Output
+ 15: TypePointer Input 6(int)
+16(gl_FragInvocationCountEXT): 15(ptr) Variable Input
+ 4(main): 2 Function None 3
+ 5: Label
+ 12: 7(ivec2) Load 11(gl_FragSizeEXT)
+ Store 9(FragSize) 12
+ 17: 6(int) Load 16(gl_FragInvocationCountEXT)
+ Store 14(FragInvocationCount) 17
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/spv.fragmentDensity-neg.frag.out b/Test/baseResults/spv.fragmentDensity-neg.frag.out
new file mode 100644
index 0000000..6b5078b
--- /dev/null
+++ b/Test/baseResults/spv.fragmentDensity-neg.frag.out
@@ -0,0 +1,7 @@
+spv.fragmentDensity-neg.frag
+ERROR: 0:10: 'gl_FragSizeEXT' : required extension not requested: GL_EXT_fragment_invocation_density
+ERROR: 0:11: 'gl_FragInvocationCountEXT' : required extension not requested: GL_EXT_fragment_invocation_density
+ERROR: 2 compilation errors. No code generated.
+
+
+SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/spv.fragmentDensity.frag.out b/Test/baseResults/spv.fragmentDensity.frag.out
new file mode 100644
index 0000000..8bbc37c
--- /dev/null
+++ b/Test/baseResults/spv.fragmentDensity.frag.out
@@ -0,0 +1,48 @@
+spv.fragmentDensity.frag
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 21
+
+ Capability Shader
+ Capability FragmentDensityEXT
+ Extension "SPV_EXT_fragment_invocation_density"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 9 13 17 19
+ ExecutionMode 4 OriginUpperLeft
+ Source GLSL 450
+ SourceExtension "GL_EXT_fragment_invocation_density"
+ Name 4 "main"
+ Name 9 "FragSize"
+ Name 13 "gl_FragSizeEXT"
+ Name 17 "FragInvocationCount"
+ Name 19 "gl_FragInvocationCountEXT"
+ Decorate 9(FragSize) Location 0
+ Decorate 13(gl_FragSizeEXT) Flat
+ Decorate 13(gl_FragSizeEXT) BuiltIn FragSizeEXT
+ Decorate 17(FragInvocationCount) Location 2
+ Decorate 19(gl_FragInvocationCountEXT) Flat
+ Decorate 19(gl_FragInvocationCountEXT) BuiltIn FragInvocationCountEXT
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 2
+ 8: TypePointer Output 7(fvec2)
+ 9(FragSize): 8(ptr) Variable Output
+ 10: TypeInt 32 1
+ 11: TypeVector 10(int) 2
+ 12: TypePointer Input 11(ivec2)
+13(gl_FragSizeEXT): 12(ptr) Variable Input
+ 16: TypePointer Output 10(int)
+17(FragInvocationCount): 16(ptr) Variable Output
+ 18: TypePointer Input 10(int)
+19(gl_FragInvocationCountEXT): 18(ptr) Variable Input
+ 4(main): 2 Function None 3
+ 5: Label
+ 14: 11(ivec2) Load 13(gl_FragSizeEXT)
+ 15: 7(fvec2) ConvertSToF 14
+ Store 9(FragSize) 15
+ 20: 10(int) Load 19(gl_FragInvocationCountEXT)
+ Store 17(FragInvocationCount) 20
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/spv.fragmentDensity.vert.out b/Test/baseResults/spv.fragmentDensity.vert.out
new file mode 100644
index 0000000..ff77a3e
--- /dev/null
+++ b/Test/baseResults/spv.fragmentDensity.vert.out
@@ -0,0 +1,9 @@
+spv.fragmentDensity.vert
+ERROR: 0:10: 'gl_FragSizeEXT' : undeclared identifier
+ERROR: 0:10: 'assign' : cannot convert from ' temp float' to 'layout( location=0) smooth out highp 2-component vector of uint'
+ERROR: 0:11: 'gl_FragInvocationCountEXT' : undeclared identifier
+ERROR: 0:11: 'assign' : cannot convert from ' temp float' to 'layout( location=2) smooth out highp int'
+ERROR: 4 compilation errors. No code generated.
+
+
+SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/spv.shadingRate.frag.out b/Test/baseResults/spv.shadingRate.frag.out
index 2b6bd31..1147776 100644
--- a/Test/baseResults/spv.shadingRate.frag.out
+++ b/Test/baseResults/spv.shadingRate.frag.out
@@ -4,7 +4,7 @@
// Id's are bound by 21
Capability Shader
- Capability ShadingRateNV
+ Capability FragmentDensityEXT
Extension "SPV_NV_shading_rate"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
@@ -19,10 +19,10 @@
Name 19 "gl_InvocationsPerPixelNV"
Decorate 9(FragmentSize) Location 0
Decorate 13(gl_FragmentSizeNV) Flat
- Decorate 13(gl_FragmentSizeNV) BuiltIn FragmentSizeNV
+ Decorate 13(gl_FragmentSizeNV) BuiltIn FragSizeEXT
Decorate 17(InvocationsPerPixel) Location 2
Decorate 19(gl_InvocationsPerPixelNV) Flat
- Decorate 19(gl_InvocationsPerPixelNV) BuiltIn InvocationsPerPixelNV
+ Decorate 19(gl_InvocationsPerPixelNV) BuiltIn FragInvocationCountEXT
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
diff --git a/Test/spv.fragmentDensity-es.frag b/Test/spv.fragmentDensity-es.frag
new file mode 100644
index 0000000..35fb96e
--- /dev/null
+++ b/Test/spv.fragmentDensity-es.frag
@@ -0,0 +1,11 @@
+#version 310 es
+
+#extension GL_EXT_fragment_invocation_density : require
+
+layout (location = 0) out highp ivec2 FragSize;
+layout (location = 2) out highp int FragInvocationCount;
+
+void main () {
+ FragSize = gl_FragSizeEXT;
+ FragInvocationCount = gl_FragInvocationCountEXT;
+}
diff --git a/Test/spv.fragmentDensity-neg.frag b/Test/spv.fragmentDensity-neg.frag
new file mode 100644
index 0000000..68e736c
--- /dev/null
+++ b/Test/spv.fragmentDensity-neg.frag
@@ -0,0 +1,12 @@
+#version 450
+
+//make sure the builtins don't exist if the extension isn't enabled.
+//#extension GL_EXT_fragment_invocation_density : require
+
+layout (location = 0) out vec2 FragSize;
+layout (location = 2) out int FragInvocationCount;
+
+void main () {
+ FragSize = gl_FragSizeEXT;
+ FragInvocationCount = gl_FragInvocationCountEXT;
+}
diff --git a/Test/spv.fragmentDensity.frag b/Test/spv.fragmentDensity.frag
new file mode 100644
index 0000000..9b37ba4
--- /dev/null
+++ b/Test/spv.fragmentDensity.frag
@@ -0,0 +1,11 @@
+#version 450
+
+#extension GL_EXT_fragment_invocation_density : require
+
+layout (location = 0) out vec2 FragSize;
+layout (location = 2) out int FragInvocationCount;
+
+void main () {
+ FragSize = gl_FragSizeEXT;
+ FragInvocationCount = gl_FragInvocationCountEXT;
+}
diff --git a/Test/spv.fragmentDensity.vert b/Test/spv.fragmentDensity.vert
new file mode 100644
index 0000000..eaef72d
--- /dev/null
+++ b/Test/spv.fragmentDensity.vert
@@ -0,0 +1,12 @@
+#version 450
+
+// try using a fragment-only extension in a vertex shader
+#extension GL_EXT_fragment_invocation_density : require
+
+layout (location = 0) out uvec2 FragSize;
+layout (location = 2) out int FragInvocationCount;
+
+void main () {
+ FragSize = gl_FragSizeEXT;
+ FragInvocationCount = gl_FragInvocationCountEXT;
+}
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index 4a7c056..fabd613 100644
--- a/glslang/Include/BaseTypes.h
+++ b/glslang/Include/BaseTypes.h
@@ -232,6 +232,9 @@
EbvViewIndex,
EbvDeviceIndex,
+ EbvFragSizeEXT,
+ EbvFragInvocationCountEXT,
+
#ifdef NV_EXTENSIONS
EbvViewportMaskNV,
EbvSecondaryPositionNV,
@@ -404,6 +407,9 @@
case EbvViewIndex: return "ViewIndex";
case EbvDeviceIndex: return "DeviceIndex";
+ case EbvFragSizeEXT: return "FragSizeEXT";
+ case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
+
#ifdef NV_EXTENSIONS
case EbvViewportMaskNV: return "ViewportMaskNV";
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index a17ea1a..7118d06 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -5939,6 +5939,12 @@
"bool gl_HelperInvocation;" // needs qualifier fixed later
);
+ if (version >= 450)
+ stageBuiltins[EShLangFragment].append( // GL_EXT_fragment_invocation_density
+ "flat in ivec2 gl_FragSizeEXT;"
+ "flat in int gl_FragInvocationCountEXT;"
+ );
+
#ifdef AMD_EXTENSIONS
if (version >= 450)
stageBuiltins[EShLangFragment].append(
@@ -5959,9 +5965,9 @@
);
if (version >= 450)
stageBuiltins[EShLangFragment].append(
- "flat in ivec2 gl_FragmentSizeNV;"
+ "flat in ivec2 gl_FragmentSizeNV;" // GL_NV_shading_rate_image
"flat in int gl_InvocationsPerPixelNV;"
- "in vec3 gl_BaryCoordNV;"
+ "in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric
"in vec3 gl_BaryCoordNoPerspNV;"
);
@@ -6006,13 +6012,19 @@
stageBuiltins[EShLangFragment].append(
"highp float gl_FragDepthEXT;" // GL_EXT_frag_depth
);
+
+ if (version >= 310)
+ stageBuiltins[EShLangFragment].append( // GL_EXT_fragment_invocation_density
+ "flat in ivec2 gl_FragSizeEXT;"
+ "flat in int gl_FragInvocationCountEXT;"
+ );
#ifdef NV_EXTENSIONS
if (version >= 320)
- stageBuiltins[EShLangFragment].append(
+ stageBuiltins[EShLangFragment].append( // GL_NV_shading_rate_image
"flat in ivec2 gl_FragmentSizeNV;"
"flat in int gl_InvocationsPerPixelNV;"
);
- if (version >= 320)
+ if (version >= 320)
stageBuiltins[EShLangFragment].append(
"in vec3 gl_BaryCoordNV;"
"in vec3 gl_BaryCoordNoPerspNV;"
@@ -8342,6 +8354,14 @@
}
#endif
+ if ((profile != EEsProfile && version >= 450) ||
+ (profile == EEsProfile && version >= 310)) {
+ symbolTable.setVariableExtensions("gl_FragSizeEXT", 1, &E_GL_EXT_fragment_invocation_density);
+ symbolTable.setVariableExtensions("gl_FragInvocationCountEXT", 1, &E_GL_EXT_fragment_invocation_density);
+ BuiltInVariable("gl_FragSizeEXT", EbvFragSizeEXT, symbolTable);
+ BuiltInVariable("gl_FragInvocationCountEXT", EbvFragInvocationCountEXT, symbolTable);
+ }
+
symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
if (profile == EEsProfile && version < 320) {
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 89c0333..16265a3 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -205,6 +205,7 @@
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
+ extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
@@ -380,6 +381,7 @@
"#define GL_EXT_shader_8bit_storage 1\n"
"#define GL_EXT_samplerless_texture_functions 1\n"
"#define GL_EXT_scalar_block_layout 1\n"
+ "#define GL_EXT_fragment_invocation_density 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index df10f0f..6b513b4 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -167,6 +167,7 @@
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
+const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
// Arrays of extensions for the above viewportEXTs duplications
diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp
index f686afd..efb8967 100755
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -271,6 +271,10 @@
"spv.flowControl.frag",
"spv.forLoop.frag",
"spv.forwardFun.frag",
+ "spv.fragmentDensity.frag",
+ "spv.fragmentDensity.vert",
+ "spv.fragmentDensity-es.frag",
+ "spv.fragmentDensity-neg.frag",
"spv.fullyCovered.frag",
"spv.functionCall.frag",
"spv.functionNestedOpaque.vert",