GLSL: Promote HLSL entry-point renaming code to be used by GLSL as well.

Fixes #1045.
This commit is contained in:
John Kessenich 2017-09-11 21:48:19 -06:00
Родитель 4f4683d251
Коммит 9855bdad00
16 изменённых файлов: 1066 добавлений и 957 удалений

Просмотреть файл

@ -0,0 +1,45 @@
glsl.entryPointRename.vert
ERROR: Source entry point must be "main"
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 20
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "foo" 13
Source GLSL 460
Name 4 "foo"
Name 11 "gl_PerVertex"
MemberName 11(gl_PerVertex) 0 "gl_Position"
MemberName 11(gl_PerVertex) 1 "gl_PointSize"
MemberName 11(gl_PerVertex) 2 "gl_ClipDistance"
MemberName 11(gl_PerVertex) 3 "gl_CullDistance"
Name 13 ""
MemberDecorate 11(gl_PerVertex) 0 BuiltIn Position
MemberDecorate 11(gl_PerVertex) 1 BuiltIn PointSize
MemberDecorate 11(gl_PerVertex) 2 BuiltIn ClipDistance
MemberDecorate 11(gl_PerVertex) 3 BuiltIn CullDistance
Decorate 11(gl_PerVertex) Block
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeInt 32 0
9: 8(int) Constant 1
10: TypeArray 6(float) 9
11(gl_PerVertex): TypeStruct 7(fvec4) 6(float) 10 10
12: TypePointer Output 11(gl_PerVertex)
13: 12(ptr) Variable Output
14: TypeInt 32 1
15: 14(int) Constant 0
16: 6(float) Constant 1065353216
17: 7(fvec4) ConstantComposite 16 16 16 16
18: TypePointer Output 7(fvec4)
4(foo): 2 Function None 3
5: Label
19: 18(ptr) AccessChain 13 15
Store 19 17
Return
FunctionEnd

Просмотреть файл

@ -0,0 +1,43 @@
glsl.entryPointRename.vert
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 20
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "foo" 13
Source GLSL 460
Name 4 "foo"
Name 11 "gl_PerVertex"
MemberName 11(gl_PerVertex) 0 "gl_Position"
MemberName 11(gl_PerVertex) 1 "gl_PointSize"
MemberName 11(gl_PerVertex) 2 "gl_ClipDistance"
MemberName 11(gl_PerVertex) 3 "gl_CullDistance"
Name 13 ""
MemberDecorate 11(gl_PerVertex) 0 BuiltIn Position
MemberDecorate 11(gl_PerVertex) 1 BuiltIn PointSize
MemberDecorate 11(gl_PerVertex) 2 BuiltIn ClipDistance
MemberDecorate 11(gl_PerVertex) 3 BuiltIn CullDistance
Decorate 11(gl_PerVertex) Block
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeInt 32 0
9: 8(int) Constant 1
10: TypeArray 6(float) 9
11(gl_PerVertex): TypeStruct 7(fvec4) 6(float) 10 10
12: TypePointer Output 11(gl_PerVertex)
13: 12(ptr) Variable Output
14: TypeInt 32 1
15: 14(int) Constant 0
16: 6(float) Constant 1065353216
17: 7(fvec4) ConstantComposite 16 16 16 16
18: TypePointer Output 7(fvec4)
4(foo): 2 Function None 3
5: Label
19: 18(ptr) AccessChain 13 15
Store 19 17
Return
FunctionEnd

Просмотреть файл

@ -0,0 +1,4 @@
glsl.entryPointRename2.vert
ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
SPIR-V is not generated for failed compile or link

Просмотреть файл

@ -0,0 +1,11 @@
#version 460
void bar()
{
gl_Position = vec4(1);
}
void main()
{
gl_Position = vec4(1);
}

Просмотреть файл

@ -0,0 +1,6 @@
#version 460
void bar()
{
gl_Position = vec4(1);
}

Просмотреть файл

@ -156,6 +156,16 @@ $EXE --target-env opengl spv.targetOpenGL.vert || HASERROR=1
$EXE -V100 spv.targetVulkan.vert || HASERROR=1 $EXE -V100 spv.targetVulkan.vert || HASERROR=1
$EXE -G100 spv.targetOpenGL.vert || HASERROR=1 $EXE -G100 spv.targetOpenGL.vert || HASERROR=1
#
# Testing GLSL entry point rename
#
$EXE -H -e foo --source-entrypoint main glsl.entryPointRename.vert > $TARGETDIR/glsl.entryPointRename.vert.out
diff -b $BASEDIR/glsl.entryPointRename.vert.out $TARGETDIR/glsl.entryPointRename.vert.out || HASERROR=1
$EXE -H -e foo --source-entrypoint bar glsl.entryPointRename.vert > $TARGETDIR/glsl.entryPointRename.vert.bad.out
diff -b $BASEDIR/glsl.entryPointRename.vert.bad.out $TARGETDIR/glsl.entryPointRename.vert.bad.out || HASERROR=1
$EXE -H -e foo --source-entrypoint main glsl.entryPointRename2.vert > $TARGETDIR/glsl.entryPointRename2.vert.out
diff -b $BASEDIR/glsl.entryPointRename2.vert.out $TARGETDIR/glsl.entryPointRename2.vert.out || HASERROR=1
# #
# Final checking # Final checking
# #

Просмотреть файл

@ -49,9 +49,10 @@ namespace glslang {
TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins,
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) : TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
const TString* entryPoint) :
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language,
infoSink, forwardCompatible, messages), infoSink, forwardCompatible, messages, entryPoint),
inMain(false), inMain(false),
blockName(nullptr), blockName(nullptr),
limits(resources.limits), limits(resources.limits),
@ -88,6 +89,9 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
if (language == EShLangGeometry) if (language == EShLangGeometry)
globalOutputDefaults.layoutStream = 0; globalOutputDefaults.layoutStream = 0;
if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
} }
TParseContext::~TParseContext() TParseContext::~TParseContext()

Просмотреть файл

@ -74,7 +74,8 @@ class TParseContextBase : public TParseVersions {
public: public:
TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version, TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version,
EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
const TString* entryPoint = nullptr)
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages), : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
scopeMangler("::"), scopeMangler("::"),
symbolTable(symbolTable), symbolTable(symbolTable),
@ -84,7 +85,10 @@ public:
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
limits(resources.limits), limits(resources.limits),
globalUniformBlock(nullptr) globalUniformBlock(nullptr)
{ } {
if (entryPoint != nullptr)
sourceEntryPointName = *entryPoint;
}
virtual ~TParseContextBase() { } virtual ~TParseContextBase() { }
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
@ -141,6 +145,15 @@ public:
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
// Potentially rename shader entry point function
void renameShaderFunction(TString*& name) const
{
// Replace the entry point name given in the shader with the real entry point name,
// if there is a substitution.
if (name != nullptr && *name == sourceEntryPointName)
name = NewPoolTString(intermediate.getEntryPointName().c_str());
}
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
@ -173,6 +186,7 @@ protected:
TPpContext* ppContext; TPpContext* ppContext;
TBuiltInResource resources; TBuiltInResource resources;
TLimits& limits; TLimits& limits;
TString sourceEntryPointName;
// These, if set, will be called when a line, pragma ... is preprocessed. // These, if set, will be called when a line, pragma ... is preprocessed.
// They will be called with any parameters to the original directive. // They will be called with any parameters to the original directive.
@ -249,7 +263,8 @@ protected:
class TParseContext : public TParseContextBase { class TParseContext : public TParseContextBase {
public: public:
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&, TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault); bool forwardCompatible = false, EShMessages messages = EShMsgDefault,
const TString* entryPoint = nullptr);
virtual ~TParseContext(); virtual ~TParseContext();
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }; bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };

Просмотреть файл

@ -91,18 +91,16 @@ TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate&
int version, EProfile profile, EShSource source, int version, EProfile profile, EShSource source,
EShLanguage language, TInfoSink& infoSink, EShLanguage language, TInfoSink& infoSink,
SpvVersion spvVersion, bool forwardCompatible, EShMessages messages, SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
bool parsingBuiltIns, const std::string sourceEntryPointName = "") bool parsingBuiltIns, std::string sourceEntryPointName = "")
{ {
#ifndef ENABLE_HLSL
(void)sourceEntryPointName; // Unused argument.
#endif
switch (source) { switch (source) {
case EShSourceGlsl: case EShSourceGlsl: {
intermediate.setEntryPointName("main"); if (sourceEntryPointName.size() == 0)
intermediate.setEntryPointName("main");
TString entryPoint = sourceEntryPointName.c_str();
return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
language, infoSink, forwardCompatible, messages); language, infoSink, forwardCompatible, messages, &entryPoint);
}
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
case EShSourceHlsl: case EShSourceHlsl:
return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,

Просмотреть файл

@ -860,6 +860,11 @@ function_header
// Add the function as a prototype after parsing it (we do not support recursion) // Add the function as a prototype after parsing it (we do not support recursion)
TFunction *function; TFunction *function;
TType type($1); TType type($1);
// Potentially rename shader entry point function. No-op most of the time.
parseContext.renameShaderFunction($2.string);
// Make the function
function = new TFunction($2.string, type); function = new TFunction($2.string, type);
$$ = function; $$ = function;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.0.4. */ /* A Bison parser, made by GNU Bison 3.0. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -345,7 +345,7 @@ extern int yydebug;
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE union YYSTYPE
{ {
#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */ #line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */
@ -384,8 +384,6 @@ union YYSTYPE
#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ #line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
}; };
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
#endif #endif

Просмотреть файл

@ -387,7 +387,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
HlslToken idToken; HlslToken idToken;
TIntermAggregate* initializers = nullptr; TIntermAggregate* initializers = nullptr;
while (acceptIdentifier(idToken)) { while (acceptIdentifier(idToken)) {
const TString *fullName = idToken.string; TString *fullName = idToken.string;
if (parseContext.symbolTable.atGlobalLevel()) if (parseContext.symbolTable.atGlobalLevel())
parseContext.getFullNamespaceName(fullName); parseContext.getFullNamespaceName(fullName);
if (peekTokenClass(EHTokLeftParen)) { if (peekTokenClass(EHTokLeftParen)) {
@ -2263,12 +2263,12 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
// //
// Expects type to have EvqGlobal for a static member and // Expects type to have EvqGlobal for a static member and
// EvqTemporary for non-static member. // EvqTemporary for non-static member.
bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType& type, const TString& memberName, bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType& type, TString& memberName,
TFunctionDeclarator& declarator) TFunctionDeclarator& declarator)
{ {
bool accepted = false; bool accepted = false;
const TString* functionName = &memberName; TString* functionName = &memberName;
parseContext.getFullNamespaceName(functionName); parseContext.getFullNamespaceName(functionName);
declarator.function = new TFunction(functionName, type); declarator.function = new TFunction(functionName, type);
if (type.getQualifier().storage == EvqTemporary) if (type.getQualifier().storage == EvqTemporary)

Просмотреть файл

@ -91,7 +91,7 @@ namespace glslang {
bool acceptConstantBufferType(TType&); bool acceptConstantBufferType(TType&);
bool acceptStruct(TType&, TIntermNode*& nodeList); bool acceptStruct(TType&, TIntermNode*& nodeList);
bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, TVector<TFunctionDeclarator>&); bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, TVector<TFunctionDeclarator>&);
bool acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType&, const TString& memberName, bool acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType&, TString& memberName,
TFunctionDeclarator&); TFunctionDeclarator&);
bool acceptFunctionParameters(TFunction&); bool acceptFunctionParameters(TFunction&);
bool acceptParameterDeclaration(TFunction&); bool acceptParameterDeclaration(TFunction&);

Просмотреть файл

@ -58,11 +58,10 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
const TString sourceEntryPointName, const TString sourceEntryPointName,
bool forwardCompatible, EShMessages messages) : bool forwardCompatible, EShMessages messages) :
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink,
forwardCompatible, messages), forwardCompatible, messages, &sourceEntryPointName),
annotationNestingLevel(0), annotationNestingLevel(0),
inputPatch(nullptr), inputPatch(nullptr),
nextInLocation(0), nextOutLocation(0), nextInLocation(0), nextOutLocation(0),
sourceEntryPointName(sourceEntryPointName),
entryPointFunction(nullptr), entryPointFunction(nullptr),
entryPointFunctionBody(nullptr), entryPointFunctionBody(nullptr),
gsStreamOutput(nullptr), gsStreamOutput(nullptr),
@ -8710,7 +8709,7 @@ void HlslParseContext::popNamespace()
// Use the class/struct nesting string to create a global name for // Use the class/struct nesting string to create a global name for
// a member of a class/struct. // a member of a class/struct.
void HlslParseContext::getFullNamespaceName(const TString*& name) const void HlslParseContext::getFullNamespaceName(TString*& name) const
{ {
if (currentTypePrefix.size() == 0) if (currentTypePrefix.size() == 0)
return; return;
@ -8726,15 +8725,6 @@ void HlslParseContext::addScopeMangler(TString& name)
name.append(scopeMangler); name.append(scopeMangler);
} }
// Potentially rename shader entry point function
void HlslParseContext::renameShaderFunction(const TString*& name) const
{
// Replace the entry point name given in the shader with the real entry point name,
// if there is a substitution.
if (name != nullptr && *name == sourceEntryPointName)
name = NewPoolTString(intermediate.getEntryPointName().c_str());
}
// Return true if this has uniform-interface like decorations. // Return true if this has uniform-interface like decorations.
bool HlslParseContext::hasUniform(const TQualifier& qualifier) const bool HlslParseContext::hasUniform(const TQualifier& qualifier) const
{ {

Просмотреть файл

@ -182,7 +182,7 @@ public:
void pushNamespace(const TString& name); void pushNamespace(const TString& name);
void popNamespace(); void popNamespace();
void getFullNamespaceName(const TString*&) const; void getFullNamespaceName(TString*&) const;
void addScopeMangler(TString&); void addScopeMangler(TString&);
void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); } void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); }
@ -207,9 +207,6 @@ public:
// Determine loop control from attributes // Determine loop control from attributes
TLoopControl handleLoopControl(const TAttributeMap& attributes) const; TLoopControl handleLoopControl(const TAttributeMap& attributes) const;
// Potentially rename shader entry point function
void renameShaderFunction(const TString*& name) const;
// Share struct buffer deep types // Share struct buffer deep types
void shareStructBufferType(TType&); void shareStructBufferType(TType&);
@ -423,7 +420,6 @@ protected:
unsigned int nextInLocation; unsigned int nextInLocation;
unsigned int nextOutLocation; unsigned int nextOutLocation;
TString sourceEntryPointName;
TFunction* entryPointFunction; TFunction* entryPointFunction;
TIntermNode* entryPointFunctionBody; TIntermNode* entryPointFunctionBody;