From 5154db5183d4ef88b2a6422207c3c730a2c7dc04 Mon Sep 17 00:00:00 2001 From: Daniel Koch Date: Mon, 26 Nov 2018 10:01:58 -0500 Subject: [PATCH] Implement GL_EXT_fragment_invocation_density including SPV generation using SPV_EXT_fragment_invocation_density. This is an alias of the functionality in SPV_NV_shading_rate, and thus in some cases we can only have one set of the tokens present (switch statements), so we have picked the EXT version. This required updating the expected test results for SPV_NV_shading_rate. Also updated the known-good for spirv-headers so that the validator in spirv-tools knows about the new extension. --- SPIRV/GLSL.ext.EXT.h | 3 +- SPIRV/GlslangToSpv.cpp | 10 ++++ SPIRV/doc.cpp | 10 ++-- .../spv.fragmentDensity-es.frag.out | 45 +++++++++++++++++ .../spv.fragmentDensity-neg.frag.out | 7 +++ Test/baseResults/spv.fragmentDensity.frag.out | 48 +++++++++++++++++++ Test/baseResults/spv.fragmentDensity.vert.out | 9 ++++ Test/baseResults/spv.shadingRate.frag.out | 6 +-- Test/spv.fragmentDensity-es.frag | 11 +++++ Test/spv.fragmentDensity-neg.frag | 12 +++++ Test/spv.fragmentDensity.frag | 11 +++++ Test/spv.fragmentDensity.vert | 12 +++++ glslang/Include/BaseTypes.h | 6 +++ glslang/MachineIndependent/Initialize.cpp | 28 +++++++++-- glslang/MachineIndependent/Versions.cpp | 2 + glslang/MachineIndependent/Versions.h | 1 + gtests/Spv.FromFile.cpp | 4 ++ known_good.json | 2 +- 18 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 Test/baseResults/spv.fragmentDensity-es.frag.out create mode 100644 Test/baseResults/spv.fragmentDensity-neg.frag.out create mode 100644 Test/baseResults/spv.fragmentDensity.frag.out create mode 100644 Test/baseResults/spv.fragmentDensity.vert.out create mode 100644 Test/spv.fragmentDensity-es.frag create mode 100644 Test/spv.fragmentDensity-neg.frag create mode 100644 Test/spv.fragmentDensity.frag create mode 100644 Test/spv.fragmentDensity.vert 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", diff --git a/known_good.json b/known_good.json index d9855079..dac84721 100755 --- a/known_good.json +++ b/known_good.json @@ -12,7 +12,7 @@ "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Headers", "subdir" : "External/spirv-tools/external/spirv-headers", - "commit" : "a2c529b5dda18838ab4b52f816acfebd774eaab3" + "commit" : "282879ca34563020dbe73fd8f7d45bed6755626a" } ] }