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.
This commit is contained in:
Daniel Koch 2018-11-26 10:01:58 -05:00
parent 83fe01e274
commit 5154db5183
18 changed files with 215 additions and 12 deletions

View File

@ -28,10 +28,11 @@
#define GLSLextEXT_H #define GLSLextEXT_H
static const int GLSLextEXTVersion = 100; 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_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_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_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 #endif // #ifndef GLSLextEXT_H

View File

@ -833,6 +833,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
builder.addCapability(spv::CapabilityMultiView); builder.addCapability(spv::CapabilityMultiView);
return spv::BuiltInViewIndex; 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 #ifdef NV_EXTENSIONS
case glslang::EbvViewportMaskNV: case glslang::EbvViewportMaskNV:
if (!memberDeclaration) { if (!memberDeclaration) {

View File

@ -388,12 +388,15 @@ const char* BuiltInString(int builtIn)
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case BuiltInPositionPerViewNV: return "PositionPerViewNV"; case BuiltInPositionPerViewNV: return "PositionPerViewNV";
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT
case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT
case BuiltInBaryCoordNV: return "BaryCoordNV"; case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
#endif #endif
case BuiltInFragSizeEXT: return "FragSizeEXT";
case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
case 5264: return "FullyCoveredEXT"; case 5264: return "FullyCoveredEXT";
@ -897,8 +900,9 @@ const char* CapabilityString(int info)
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV"; case CapabilityMeshShadingNV: return "MeshShadingNV";
case CapabilityShadingRateNV: return "ShadingRateNV"; // case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT
#endif #endif
case CapabilityFragmentDensityEXT: return "FragmentDensityEXT";
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@ spv.shadingRate.frag
// Id's are bound by 21 // Id's are bound by 21
Capability Shader Capability Shader
Capability ShadingRateNV Capability FragmentDensityEXT
Extension "SPV_NV_shading_rate" Extension "SPV_NV_shading_rate"
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
@ -19,10 +19,10 @@ spv.shadingRate.frag
Name 19 "gl_InvocationsPerPixelNV" Name 19 "gl_InvocationsPerPixelNV"
Decorate 9(FragmentSize) Location 0 Decorate 9(FragmentSize) Location 0
Decorate 13(gl_FragmentSizeNV) Flat Decorate 13(gl_FragmentSizeNV) Flat
Decorate 13(gl_FragmentSizeNV) BuiltIn FragmentSizeNV Decorate 13(gl_FragmentSizeNV) BuiltIn FragSizeEXT
Decorate 17(InvocationsPerPixel) Location 2 Decorate 17(InvocationsPerPixel) Location 2
Decorate 19(gl_InvocationsPerPixelNV) Flat Decorate 19(gl_InvocationsPerPixelNV) Flat
Decorate 19(gl_InvocationsPerPixelNV) BuiltIn InvocationsPerPixelNV Decorate 19(gl_InvocationsPerPixelNV) BuiltIn FragInvocationCountEXT
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -232,6 +232,9 @@ enum TBuiltInVariable {
EbvViewIndex, EbvViewIndex,
EbvDeviceIndex, EbvDeviceIndex,
EbvFragSizeEXT,
EbvFragInvocationCountEXT,
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
EbvViewportMaskNV, EbvViewportMaskNV,
EbvSecondaryPositionNV, EbvSecondaryPositionNV,
@ -404,6 +407,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvViewIndex: return "ViewIndex"; case EbvViewIndex: return "ViewIndex";
case EbvDeviceIndex: return "DeviceIndex"; case EbvDeviceIndex: return "DeviceIndex";
case EbvFragSizeEXT: return "FragSizeEXT";
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvViewportMaskNV: return "ViewportMaskNV";
case EbvSecondaryPositionNV: return "SecondaryPositionNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV";

View File

@ -5939,6 +5939,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"bool gl_HelperInvocation;" // needs qualifier fixed later "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 #ifdef AMD_EXTENSIONS
if (version >= 450) if (version >= 450)
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
@ -5959,9 +5965,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
); );
if (version >= 450) if (version >= 450)
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
"flat in ivec2 gl_FragmentSizeNV;" "flat in ivec2 gl_FragmentSizeNV;" // GL_NV_shading_rate_image
"flat in int gl_InvocationsPerPixelNV;" "flat in int gl_InvocationsPerPixelNV;"
"in vec3 gl_BaryCoordNV;" "in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric
"in vec3 gl_BaryCoordNoPerspNV;" "in vec3 gl_BaryCoordNoPerspNV;"
); );
@ -6006,13 +6012,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
"highp float gl_FragDepthEXT;" // GL_EXT_frag_depth "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 #ifdef NV_EXTENSIONS
if (version >= 320) if (version >= 320)
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append( // GL_NV_shading_rate_image
"flat in ivec2 gl_FragmentSizeNV;" "flat in ivec2 gl_FragmentSizeNV;"
"flat in int gl_InvocationsPerPixelNV;" "flat in int gl_InvocationsPerPixelNV;"
); );
if (version >= 320) if (version >= 320)
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
"in vec3 gl_BaryCoordNV;" "in vec3 gl_BaryCoordNV;"
"in vec3 gl_BaryCoordNoPerspNV;" "in vec3 gl_BaryCoordNoPerspNV;"
@ -8342,6 +8354,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
} }
#endif #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); symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
if (profile == EEsProfile && version < 320) { if (profile == EEsProfile && version < 320) {

View File

@ -205,6 +205,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable; extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable; extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
extensionBehavior[E_GL_EXT_scalar_block_layout] = 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_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_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_shader_8bit_storage 1\n"
"#define GL_EXT_samplerless_texture_functions 1\n" "#define GL_EXT_samplerless_texture_functions 1\n"
"#define GL_EXT_scalar_block_layout 1\n" "#define GL_EXT_scalar_block_layout 1\n"
"#define GL_EXT_fragment_invocation_density 1\n"
// GL_KHR_shader_subgroup // GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n" "#define GL_KHR_shader_subgroup_basic 1\n"

View File

@ -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_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_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_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 // Arrays of extensions for the above viewportEXTs duplications

View File

@ -271,6 +271,10 @@ INSTANTIATE_TEST_CASE_P(
"spv.flowControl.frag", "spv.flowControl.frag",
"spv.forLoop.frag", "spv.forLoop.frag",
"spv.forwardFun.frag", "spv.forwardFun.frag",
"spv.fragmentDensity.frag",
"spv.fragmentDensity.vert",
"spv.fragmentDensity-es.frag",
"spv.fragmentDensity-neg.frag",
"spv.fullyCovered.frag", "spv.fullyCovered.frag",
"spv.functionCall.frag", "spv.functionCall.frag",
"spv.functionNestedOpaque.vert", "spv.functionNestedOpaque.vert",

View File

@ -12,7 +12,7 @@
"site" : "github", "site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers", "subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers", "subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "a2c529b5dda18838ab4b52f816acfebd774eaab3" "commit" : "282879ca34563020dbe73fd8f7d45bed6755626a"
} }
] ]
} }