diff --git a/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h index c4a24308..e29c055b 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 2e2a2fe5..5c00024c 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -833,6 +833,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI 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 4f7c1989..b0b01fba 100644 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -388,12 +388,15 @@ const char* BuiltInString(int builtIn) 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 @@ const char* CapabilityString(int info) 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 00000000..01ac3833 --- /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 00000000..6b5078bd --- /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 00000000..8bbc37cc --- /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 00000000..ff77a3ec --- /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 2b6bd31d..11477769 100644 --- a/Test/baseResults/spv.shadingRate.frag.out +++ b/Test/baseResults/spv.shadingRate.frag.out @@ -4,7 +4,7 @@ spv.shadingRate.frag // 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 @@ spv.shadingRate.frag 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 00000000..35fb96e7 --- /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 00000000..68e736cd --- /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 00000000..9b37ba4c --- /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 00000000..eaef72d7 --- /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 4a7c0568..fabd6135 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -232,6 +232,9 @@ enum TBuiltInVariable { EbvViewIndex, EbvDeviceIndex, + EbvFragSizeEXT, + EbvFragInvocationCountEXT, + #ifdef NV_EXTENSIONS EbvViewportMaskNV, EbvSecondaryPositionNV, @@ -404,6 +407,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) 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 a17ea1ae..7118d065 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -5939,6 +5939,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "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 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ); 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 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV 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 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } #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 89c03337..16265a30 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -205,6 +205,7 @@ void TParseVersions::initializeExtensionBehavior() 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 @@ void TParseVersions::getPreamble(std::string& preamble) "#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 df10f0f4..6b513b43 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -167,6 +167,7 @@ const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_fl 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 f686afdf..efb89672 100755 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -271,6 +271,10 @@ INSTANTIATE_TEST_CASE_P( "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",