Commit 6e1d50a7 by John Kessenich

HLSL: Accept SV_Cull/ClipDistanceN, by refactoring the way semantics are mapped.

parent 229a6f7f
struct S {
float clip0 : SV_ClipDistance0;
float cull0 : SV_CullDistance0;
uint vpai : SV_ViewportArrayIndex;
uint rtai : SV_RenderTargetArrayIndex;
int ii : SV_InstanceID;
};
[maxvertexcount(4)]
S main(triangle in uint VertexID[3] : VertexID,
inout LineStream<S> OutputStream)
{
S s;
return s;
}
struct S {
float clip : SV_ClipDistance;
float clip0 : SV_ClipDistance0;
float clip7 : SV_ClipDistance7;
float cull : SV_CullDistance;
float cull2 : SV_CullDistance2;
float cull5 : SV_CullDistance5;
int ii : SV_InstanceID;
};
S main(S ins)
{
S s;
return s;
}
...@@ -218,6 +218,7 @@ enum TBuiltInVariable { ...@@ -218,6 +218,7 @@ enum TBuiltInVariable {
// to one of the above. // to one of the above.
EbvFragDepthGreater, EbvFragDepthGreater,
EbvFragDepthLesser, EbvFragDepthLesser,
EbvStencilRef,
EbvLast EbvLast
}; };
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1887" #define GLSLANG_REVISION "Overload400-PrecQual.1892"
#define GLSLANG_DATE "08-Mar-2017" #define GLSLANG_DATE "09-Mar-2017"
...@@ -240,6 +240,8 @@ INSTANTIATE_TEST_CASE_P( ...@@ -240,6 +240,8 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.max.frag", "PixelShaderFunction"}, {"hlsl.max.frag", "PixelShaderFunction"},
{"hlsl.precedence.frag", "PixelShaderFunction"}, {"hlsl.precedence.frag", "PixelShaderFunction"},
{"hlsl.precedence2.frag", "PixelShaderFunction"}, {"hlsl.precedence2.frag", "PixelShaderFunction"},
{"hlsl.semantic.geom", "main"},
{"hlsl.semantic.vert", "main"},
{"hlsl.scope.frag", "PixelShaderFunction"}, {"hlsl.scope.frag", "PixelShaderFunction"},
{"hlsl.sin.frag", "PixelShaderFunction"}, {"hlsl.sin.frag", "PixelShaderFunction"},
{"hlsl.struct.frag", "PixelShaderFunction"}, {"hlsl.struct.frag", "PixelShaderFunction"},
......
...@@ -3401,7 +3401,7 @@ bool HlslGrammar::acceptPostDecls(TQualifier& qualifier) ...@@ -3401,7 +3401,7 @@ bool HlslGrammar::acceptPostDecls(TQualifier& qualifier)
parseContext.handleRegister(registerDesc.loc, qualifier, profile.string, *registerDesc.string, subComponent, spaceDesc.string); parseContext.handleRegister(registerDesc.loc, qualifier, profile.string, *registerDesc.string, subComponent, spaceDesc.string);
} else { } else {
// semantic, in idToken.string // semantic, in idToken.string
parseContext.handleSemantic(idToken.loc, qualifier, *idToken.string); parseContext.handleSemantic(idToken.loc, qualifier, mapSemantic(*idToken.string));
} }
} else if (peekTokenClass(EHTokLeftAngle)) { } else if (peekTokenClass(EHTokLeftAngle)) {
found = true; found = true;
......
...@@ -4194,118 +4194,23 @@ TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const ...@@ -4194,118 +4194,23 @@ TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const
// Handle seeing a "COLON semantic" at the end of a type declaration, // Handle seeing a "COLON semantic" at the end of a type declaration,
// by updating the type according to the semantic. // by updating the type according to the semantic.
// //
void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, const TString& semantic) void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBuiltInVariable builtIn)
{ {
// TODO: need to know if it's an input or an output // adjust for stage in/out
// The following sketches what needs to be done, but can't be right
// without taking into account stage and input/output. switch(builtIn) {
case EbvPosition:
TString semanticUpperCase = semantic; if (language == EShLangFragment)
std::transform(semanticUpperCase.begin(), semanticUpperCase.end(), semanticUpperCase.begin(), ::toupper); builtIn = EbvFragCoord;
// in DX9, all outputs had to have a semantic associated with them, that was either consumed break;
// by the system or was a specific register assignment case EbvStencilRef:
// in DX10+, only semantics with the SV_ prefix have any meaning beyond decoration
// Fxc will only accept DX9 style semantics in compat mode
// Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
// stage, it would just be ignored as it is likely there as part of an output struct from one stage
// to the next
bool bParseDX9 = false;
if (bParseDX9) {
if (semanticUpperCase == "PSIZE")
qualifier.builtIn = EbvPointSize;
else if (semantic == "FOG")
qualifier.builtIn = EbvFogFragCoord;
else if (semanticUpperCase == "DEPTH")
qualifier.builtIn = EbvFragDepth;
else if (semanticUpperCase == "VFACE")
qualifier.builtIn = EbvFace;
else if (semanticUpperCase == "VPOS")
qualifier.builtIn = EbvFragCoord;
}
// SV Position has a different meaning in vertex vs fragment
if (semanticUpperCase == "SV_POSITION" && language != EShLangFragment)
qualifier.builtIn = EbvPosition;
else if (semanticUpperCase == "SV_POSITION" && language == EShLangFragment)
qualifier.builtIn = EbvFragCoord;
else if (semanticUpperCase == "SV_CLIPDISTANCE")
qualifier.builtIn = EbvClipDistance;
else if (semanticUpperCase == "SV_CULLDISTANCE")
qualifier.builtIn = EbvCullDistance;
else if (semanticUpperCase == "SV_VERTEXID")
qualifier.builtIn = EbvVertexIndex;
else if (semanticUpperCase == "SV_VIEWPORTARRAYINDEX")
qualifier.builtIn = EbvViewportIndex;
else if (semanticUpperCase == "SV_TESSFACTOR")
qualifier.builtIn = EbvTessLevelOuter;
// Targets are defined 0-7
else if (semanticUpperCase == "SV_TARGET") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 0;
} else if (semanticUpperCase == "SV_TARGET0") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 0;
} else if (semanticUpperCase == "SV_TARGET1") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 1;
} else if (semanticUpperCase == "SV_TARGET2") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 2;
} else if (semanticUpperCase == "SV_TARGET3") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 3;
} else if (semanticUpperCase == "SV_TARGET4") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 4;
} else if (semanticUpperCase == "SV_TARGET5") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 5;
} else if (semanticUpperCase == "SV_TARGET6") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 6;
} else if (semanticUpperCase == "SV_TARGET7") {
qualifier.builtIn = EbvNone;
// qualifier.layoutLocation = 7;
} else if (semanticUpperCase == "SV_SAMPLEINDEX")
qualifier.builtIn = EbvSampleId;
else if (semanticUpperCase == "SV_RENDERTARGETARRAYINDEX")
qualifier.builtIn = EbvLayer;
else if (semanticUpperCase == "SV_PRIMITIVEID")
qualifier.builtIn = EbvPrimitiveId;
else if (semanticUpperCase == "SV_OUTPUTCONTROLPOINTID")
qualifier.builtIn = EbvInvocationId;
else if (semanticUpperCase == "SV_ISFRONTFACE")
qualifier.builtIn = EbvFace;
else if (semanticUpperCase == "SV_INSTANCEID")
qualifier.builtIn = EbvInstanceIndex;
else if (semanticUpperCase == "SV_INSIDETESSFACTOR")
qualifier.builtIn = EbvTessLevelInner;
else if (semanticUpperCase == "SV_GSINSTANCEID")
qualifier.builtIn = EbvInvocationId;
else if (semanticUpperCase == "SV_DISPATCHTHREADID")
qualifier.builtIn = EbvGlobalInvocationId;
else if (semanticUpperCase == "SV_GROUPTHREADID")
qualifier.builtIn = EbvLocalInvocationId;
else if (semanticUpperCase == "SV_GROUPINDEX")
qualifier.builtIn = EbvLocalInvocationIndex;
else if (semanticUpperCase == "SV_GROUPID")
qualifier.builtIn = EbvWorkGroupId;
else if (semanticUpperCase == "SV_DOMAINLOCATION")
qualifier.builtIn = EbvTessCoord;
else if (semanticUpperCase == "SV_DEPTH")
qualifier.builtIn = EbvFragDepth;
else if( semanticUpperCase == "SV_COVERAGE")
qualifier.builtIn = EbvSampleMask;
// TODO, these need to get refined to be more specific
else if( semanticUpperCase == "SV_DEPTHGREATEREQUAL")
qualifier.builtIn = EbvFragDepthGreater;
else if( semanticUpperCase == "SV_DEPTHLESSEQUAL")
qualifier.builtIn = EbvFragDepthLesser;
else if( semanticUpperCase == "SV_STENCILREF")
error(loc, "unimplemented; need ARB_shader_stencil_export", "SV_STENCILREF", ""); error(loc, "unimplemented; need ARB_shader_stencil_export", "SV_STENCILREF", "");
break;
default:
break;
}
qualifier.builtIn = builtIn;
} }
// //
......
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&); TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
TFunction* handleConstructorCall(const TSourceLoc&, const TType&); TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
void handleSemantic(TSourceLoc, TQualifier&, const TString& semantic); void handleSemantic(TSourceLoc, TQualifier&, TBuiltInVariable);
void handlePackOffset(const TSourceLoc&, TQualifier&, const glslang::TString& location, void handlePackOffset(const TSourceLoc&, TQualifier&, const glslang::TString& location,
const glslang::TString* component); const glslang::TString* component);
void handleRegister(const TSourceLoc&, TQualifier&, const glslang::TString* profile, const glslang::TString& desc, void handleRegister(const TSourceLoc&, TQualifier&, const glslang::TString* profile, const glslang::TString& desc,
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "../glslang/MachineIndependent/ParseHelper.h" #include "../glslang/MachineIndependent/ParseHelper.h"
#include "hlslScanContext.h" #include "hlslScanContext.h"
#include "hlslTokens.h" #include "hlslTokens.h"
//#include "Scan.h"
// preprocessor includes // preprocessor includes
#include "../glslang/MachineIndependent/preprocessor/PpContext.h" #include "../glslang/MachineIndependent/preprocessor/PpContext.h"
...@@ -82,6 +81,7 @@ struct str_hash ...@@ -82,6 +81,7 @@ struct str_hash
// After a single process-level initialization, this is read only and thread safe // After a single process-level initialization, this is read only and thread safe
std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr; std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr; std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>* SemanticMap = nullptr;
}; };
...@@ -381,6 +381,73 @@ void HlslScanContext::fillInKeywordMap() ...@@ -381,6 +381,73 @@ void HlslScanContext::fillInKeywordMap()
ReservedSet->insert("unsigned"); ReservedSet->insert("unsigned");
ReservedSet->insert("using"); ReservedSet->insert("using");
ReservedSet->insert("virtual"); ReservedSet->insert("virtual");
SemanticMap = new std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>;
// in DX9, all outputs had to have a semantic associated with them, that was either consumed
// by the system or was a specific register assignment
// in DX10+, only semantics with the SV_ prefix have any meaning beyond decoration
// Fxc will only accept DX9 style semantics in compat mode
// Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
// stage, it would just be ignored as it is likely there as part of an output struct from one stage
// to the next
bool bParseDX9 = false;
if (bParseDX9) {
(*SemanticMap)["PSIZE"] = EbvPointSize;
(*SemanticMap)["FOG"] = EbvFogFragCoord;
(*SemanticMap)["DEPTH"] = EbvFragDepth;
(*SemanticMap)["VFACE"] = EbvFace;
(*SemanticMap)["VPOS"] = EbvFragCoord;
}
(*SemanticMap)["SV_POSITION"] = EbvPosition;
(*SemanticMap)["SV_CLIPDISTANCE"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE0"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE1"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE2"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE3"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE4"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE5"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE6"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE7"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE8"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE9"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE10"] = EbvClipDistance;
(*SemanticMap)["SV_CLIPDISTANCE11"] = EbvClipDistance;
(*SemanticMap)["SV_CULLDISTANCE"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE0"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE1"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE2"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE3"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE4"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE5"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE6"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE7"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE8"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE9"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE10"] = EbvCullDistance;
(*SemanticMap)["SV_CULLDISTANCE11"] = EbvCullDistance;
(*SemanticMap)["SV_VERTEXID"] = EbvVertexIndex;
(*SemanticMap)["SV_VIEWPORTARRAYINDEX"] = EbvViewportIndex;
(*SemanticMap)["SV_TESSFACTOR"] = EbvTessLevelOuter;
(*SemanticMap)["SV_SAMPLEINDEX"] = EbvSampleId;
(*SemanticMap)["SV_RENDERTARGETARRAYINDEX"] = EbvLayer;
(*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
(*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
(*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
(*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
(*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
(*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
(*SemanticMap)["SV_DISPATCHTHREADID"] = EbvGlobalInvocationId;
(*SemanticMap)["SV_GROUPTHREADID"] = EbvLocalInvocationId;
(*SemanticMap)["SV_GROUPINDEX"] = EbvLocalInvocationIndex;
(*SemanticMap)["SV_GROUPID"] = EbvWorkGroupId;
(*SemanticMap)["SV_DOMAINLOCATION"] = EbvTessCoord;
(*SemanticMap)["SV_DEPTH"] = EbvFragDepth;
(*SemanticMap)["SV_COVERAGE"] = EbvSampleMask;
(*SemanticMap)["SV_DEPTHGREATEREQUAL"] = EbvFragDepthGreater;
(*SemanticMap)["SV_DEPTHLESSEQUAL"] = EbvFragDepthLesser;
(*SemanticMap)["SV_STENCILREF"] = EbvStencilRef;
} }
void HlslScanContext::deleteKeywordMap() void HlslScanContext::deleteKeywordMap()
...@@ -389,15 +456,29 @@ void HlslScanContext::deleteKeywordMap() ...@@ -389,15 +456,29 @@ void HlslScanContext::deleteKeywordMap()
KeywordMap = nullptr; KeywordMap = nullptr;
delete ReservedSet; delete ReservedSet;
ReservedSet = nullptr; ReservedSet = nullptr;
delete SemanticMap;
SemanticMap = nullptr;
} }
// Wrapper for tokenizeClass()"] = to get everything inside the token. // Wrapper for tokenizeClass() to get everything inside the token.
void HlslScanContext::tokenize(HlslToken& token) void HlslScanContext::tokenize(HlslToken& token)
{ {
EHlslTokenClass tokenClass = tokenizeClass(token); EHlslTokenClass tokenClass = tokenizeClass(token);
token.tokenClass = tokenClass; token.tokenClass = tokenClass;
} }
glslang::TBuiltInVariable HlslScanContext::mapSemantic(const TString& semantic)
{
TString semanticUpperCase = semantic;
std::transform(semanticUpperCase.begin(), semanticUpperCase.end(), semanticUpperCase.begin(), ::toupper);
auto it = SemanticMap->find(semanticUpperCase.c_str());
if (it != SemanticMap->end())
return it->second;
else
return glslang::EbvNone;
}
// //
// Fill in token information for the next token, except for the token class. // Fill in token information for the next token, except for the token class.
// Returns the enum value of the token class of the next token found. // Returns the enum value of the token class of the next token found.
......
...@@ -82,6 +82,7 @@ public: ...@@ -82,6 +82,7 @@ public:
static void deleteKeywordMap(); static void deleteKeywordMap();
void tokenize(HlslToken&); void tokenize(HlslToken&);
glslang::TBuiltInVariable mapSemantic(const TString& semantic);
protected: protected:
HlslScanContext(HlslScanContext&); HlslScanContext(HlslScanContext&);
......
...@@ -52,6 +52,7 @@ namespace glslang { ...@@ -52,6 +52,7 @@ namespace glslang {
bool acceptTokenClass(EHlslTokenClass); bool acceptTokenClass(EHlslTokenClass);
EHlslTokenClass peek() const; EHlslTokenClass peek() const;
bool peekTokenClass(EHlslTokenClass) const; bool peekTokenClass(EHlslTokenClass) const;
glslang::TBuiltInVariable mapSemantic(const TString& semantic) { return scanner.mapSemantic(semantic); }
protected: protected:
HlslToken token; // the token we are currently looking at, but have not yet accepted HlslToken token; // the token we are currently looking at, but have not yet accepted
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment