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

This commit is contained in:
John Kessenich
2017-03-09 14:37:32 -07:00
parent 229a6f7f7b
commit 6e1d50a7a2
13 changed files with 754 additions and 114 deletions

View File

@@ -4194,118 +4194,23 @@ TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const
// Handle seeing a "COLON semantic" at the end of a type declaration,
// 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
// The following sketches what needs to be done, but can't be right
// without taking into account stage and input/output.
// adjust for stage in/out
TString semanticUpperCase = semantic;
std::transform(semanticUpperCase.begin(), semanticUpperCase.end(), semanticUpperCase.begin(), ::toupper);
// 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) {
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;
switch(builtIn) {
case EbvPosition:
if (language == EShLangFragment)
builtIn = EbvFragCoord;
break;
case EbvStencilRef:
error(loc, "unimplemented; need ARB_shader_stencil_export", "SV_STENCILREF", "");
break;
default:
break;
}
// 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", "");
qualifier.builtIn = builtIn;
}
//