mirror of
https://github.com/KhronosGroup/glslang
synced 2024-09-19 20:29:54 +00:00
Add support for SPV_NV_geometry_shader_passthrough
This commit is contained in:
parent
0ad6a4e60d
commit
6e5acae144
@ -32,11 +32,18 @@ enum Decoration;
|
|||||||
enum Op;
|
enum Op;
|
||||||
|
|
||||||
static const int GLSLextNVVersion = 100;
|
static const int GLSLextNVVersion = 100;
|
||||||
static const int GLSLextNVRevision = 1;
|
static const int GLSLextNVRevision = 2;
|
||||||
|
|
||||||
//SPV_NV_sample_mask_override_coverage
|
//SPV_NV_sample_mask_override_coverage
|
||||||
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||||
|
|
||||||
static const Decoration OverrideCoverageNV = static_cast<Decoration>(5248);
|
static const Decoration OverrideCoverageNV = static_cast<Decoration>(5248);
|
||||||
|
|
||||||
|
|
||||||
|
//SPV_NV_geometry_shader_passthrough
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
|
||||||
|
|
||||||
|
static const Decoration PassthroughNV = static_cast<Decoration>(5250);
|
||||||
|
|
||||||
|
static const Capability GeometryShaderPassthroughNV = static_cast<Capability>(5251);
|
||||||
#endif // #ifndef GLSLextNV_H
|
#endif // #ifndef GLSLextNV_H
|
@ -4738,6 +4738,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
|
builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (symbol->getQualifier().layoutPassthrough) {
|
||||||
|
addDecoration(id, spv::PassthroughNV);
|
||||||
|
builder.addCapability(spv::GeometryShaderPassthroughNV);
|
||||||
|
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
@ -481,7 +481,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||||||
extInstSet = GLSLextAMDInst;
|
extInstSet = GLSLextAMDInst;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
} else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0) {
|
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0) {
|
||||||
extInstSet = GLSLextNVInst;
|
extInstSet = GLSLextNVInst;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -654,9 +655,12 @@ static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
{
|
{
|
||||||
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0) {
|
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0) {
|
||||||
switch (entrypoint) {
|
switch (entrypoint) {
|
||||||
case OverrideCoverageNV: return "OverrideCoverageNV";
|
case OverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
case PassthroughNV: return "PassthroughNV";
|
||||||
|
case GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,6 +261,7 @@ const char* DecorationString(int decoration)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case 5248: return "OverrideCoverageNV";
|
case 5248: return "OverrideCoverageNV";
|
||||||
|
case 5250: return "PassthroughNV";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -818,6 +819,11 @@ const char* CapabilityString(int info)
|
|||||||
|
|
||||||
case 4423: return "SubgroupBallotKHR";
|
case 4423: return "SubgroupBallotKHR";
|
||||||
case 4427: return "DrawParameters";
|
case 4427: return "DrawParameters";
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case 5251: return "GeometryShaderPassthroughNV";
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
Test/baseResults/spv.GeometryShaderPassthrough.geom.out
Normal file
46
Test/baseResults/spv.GeometryShaderPassthrough.geom.out
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
spv.GeometryShaderPassthrough.geom
|
||||||
|
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80001
|
||||||
|
// Id's are bound by 15
|
||||||
|
|
||||||
|
Capability Geometry
|
||||||
|
Capability GeometryShaderPassthroughNV
|
||||||
|
Extension "SPV_NV_geometry_shader_passthrough"
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Geometry 4 "main" 10 14
|
||||||
|
ExecutionMode 4 Triangles
|
||||||
|
ExecutionMode 4 Invocations 1
|
||||||
|
ExecutionMode 4 OutputVertices
|
||||||
|
Source GLSL 450
|
||||||
|
SourceExtension "GL_NV_geometry_shader_passthrough"
|
||||||
|
Name 4 "main"
|
||||||
|
Name 8 "gl_PerVertex"
|
||||||
|
MemberName 8(gl_PerVertex) 0 "gl_Position"
|
||||||
|
Name 10 ""
|
||||||
|
Name 12 "Inputs"
|
||||||
|
MemberName 12(Inputs) 0 "texcoord"
|
||||||
|
MemberName 12(Inputs) 1 "baseColor"
|
||||||
|
Name 14 ""
|
||||||
|
MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position
|
||||||
|
Decorate 8(gl_PerVertex) Block
|
||||||
|
Decorate 10 PassthroughNV
|
||||||
|
Decorate 12(Inputs) Block
|
||||||
|
Decorate 14 PassthroughNV
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypeVector 6(float) 4
|
||||||
|
8(gl_PerVertex): TypeStruct 7(fvec4)
|
||||||
|
9: TypePointer Input 8(gl_PerVertex)
|
||||||
|
10: 9(ptr) Variable Input
|
||||||
|
11: TypeVector 6(float) 2
|
||||||
|
12(Inputs): TypeStruct 11(fvec2) 7(fvec4)
|
||||||
|
13: TypePointer Input 12(Inputs)
|
||||||
|
14: 13(ptr) Variable Input
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
17
Test/spv.GeometryShaderPassthrough.geom
Normal file
17
Test/spv.GeometryShaderPassthrough.geom
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_NV_geometry_shader_passthrough : require
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
|
||||||
|
layout(passthrough) in gl_PerVertex {
|
||||||
|
vec4 gl_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(passthrough) in Inputs {
|
||||||
|
vec2 texcoord;
|
||||||
|
vec4 baseColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
}
|
@ -599,6 +599,9 @@ public:
|
|||||||
layoutFormat = ElfNone;
|
layoutFormat = ElfNone;
|
||||||
|
|
||||||
layoutPushConstant = false;
|
layoutPushConstant = false;
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
layoutPassthrough = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
bool hasLayout() const
|
bool hasLayout() const
|
||||||
{
|
{
|
||||||
@ -652,6 +655,10 @@ public:
|
|||||||
|
|
||||||
bool layoutPushConstant;
|
bool layoutPushConstant;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
bool layoutPassthrough;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool hasUniformLayout() const
|
bool hasUniformLayout() const
|
||||||
{
|
{
|
||||||
return hasMatrix() ||
|
return hasMatrix() ||
|
||||||
@ -1537,6 +1544,12 @@ public:
|
|||||||
if (qualifier.layoutPushConstant)
|
if (qualifier.layoutPushConstant)
|
||||||
p += snprintf(p, end - p, "push_constant ");
|
p += snprintf(p, end - p, "push_constant ");
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (qualifier.layoutPassthrough)
|
||||||
|
p += snprintf(p, end - p, "passthrough ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
p += snprintf(p, end - p, ") ");
|
p += snprintf(p, end - p, ") ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,11 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
|
|||||||
void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
|
void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
|
||||||
{
|
{
|
||||||
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
|
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
|
||||||
if (type.getQualifier().isArrayedIo(language))
|
if (type.getQualifier().isArrayedIo(language)
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !type.getQualifier().layoutPassthrough
|
||||||
|
#endif
|
||||||
|
)
|
||||||
error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
|
error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3459,6 +3463,20 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
|
|||||||
// - remove unused members
|
// - remove unused members
|
||||||
// - ensure remaining qualifiers/types match
|
// - ensure remaining qualifiers/types match
|
||||||
TType& type = block->getWritableType();
|
TType& type = block->getWritableType();
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
// if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
|
||||||
|
// for passthrough purpose, the redclared block should have the same qualifers as
|
||||||
|
// the current one
|
||||||
|
if (currentBlockQualifier.layoutPassthrough)
|
||||||
|
{
|
||||||
|
type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
|
||||||
|
type.getQualifier().storage = currentBlockQualifier.storage;
|
||||||
|
type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
|
||||||
|
type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TTypeList::iterator member = type.getWritableStruct()->begin();
|
TTypeList::iterator member = type.getWritableStruct()->begin();
|
||||||
size_t numOriginalMembersFound = 0;
|
size_t numOriginalMembersFound = 0;
|
||||||
while (member != type.getStruct()->end()) {
|
while (member != type.getStruct()->end()) {
|
||||||
@ -3928,6 +3946,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (id == "passthrough") {
|
||||||
|
requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
|
||||||
|
publicType.qualifier.layoutPassthrough = true;
|
||||||
|
intermediate.setGeoPassthroughEXT();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
assert(language == EShLangTessEvaluation);
|
assert(language == EShLangTessEvaluation);
|
||||||
|
|
||||||
@ -4328,6 +4354,11 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
|||||||
|
|
||||||
if (src.layoutPushConstant)
|
if (src.layoutPushConstant)
|
||||||
dst.layoutPushConstant = true;
|
dst.layoutPushConstant = true;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (src.layoutPassthrough)
|
||||||
|
dst.layoutPassthrough = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +197,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
||||||
|
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
@ -309,6 +310,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
"#define GL_NV_sample_mask_override_coverage 1\n"
|
"#define GL_NV_sample_mask_override_coverage 1\n"
|
||||||
|
"#define GL_NV_geometry_shader_passthrough 1\n"
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,7 @@ const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_sh
|
|||||||
#endif
|
#endif
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
|
@ -469,9 +469,17 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (outputPrimitive == ElgNone)
|
if (outputPrimitive == ElgNone
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !getGeoPassthroughEXT()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
error(infoSink, "At least one shader must specify an output layout primitive");
|
error(infoSink, "At least one shader must specify an output layout primitive");
|
||||||
if (vertices == TQualifier::layoutNotSet)
|
if (vertices == TQualifier::layoutNotSet
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !getGeoPassthroughEXT()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
||||||
break;
|
break;
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
|
@ -153,6 +153,7 @@ public:
|
|||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
|
geoPassthroughEXT(false),
|
||||||
#endif
|
#endif
|
||||||
useUnknownFormat(false)
|
useUnknownFormat(false)
|
||||||
{
|
{
|
||||||
@ -393,6 +394,8 @@ public:
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
||||||
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
||||||
|
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
||||||
|
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -457,6 +460,7 @@ protected:
|
|||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
bool layoutOverrideCoverage;
|
bool layoutOverrideCoverage;
|
||||||
|
bool geoPassthroughEXT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
|
@ -216,6 +216,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.forwardFun.frag",
|
"spv.forwardFun.frag",
|
||||||
"spv.functionCall.frag",
|
"spv.functionCall.frag",
|
||||||
"spv.functionSemantics.frag",
|
"spv.functionSemantics.frag",
|
||||||
|
"spv.GeometryShaderPassthrough.geom",
|
||||||
"spv.interpOps.frag",
|
"spv.interpOps.frag",
|
||||||
"spv.int64.frag",
|
"spv.int64.frag",
|
||||||
"spv.layoutNested.vert",
|
"spv.layoutNested.vert",
|
||||||
|
Loading…
Reference in New Issue
Block a user