HLSL: fix GS implementation for EP wrapping
The prior implementation of GS did not work with the new EP wrapping architecture. This fixes it: the Append() method now looks up the actual output rather than the internal sanitized temporary type, and writes to that.
This commit is contained in:
@@ -611,12 +611,15 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList)
|
||||
qualifier.layoutFormat = type.getQualifier().layoutFormat;
|
||||
qualifier.precision = type.getQualifier().precision;
|
||||
|
||||
if (type.getQualifier().storage == EvqVaryingOut ||
|
||||
if (type.getQualifier().storage == EvqOut ||
|
||||
type.getQualifier().storage == EvqBuffer) {
|
||||
qualifier.storage = type.getQualifier().storage;
|
||||
qualifier.readonly = type.getQualifier().readonly;
|
||||
}
|
||||
|
||||
if (type.getQualifier().builtIn != EbvNone)
|
||||
qualifier.builtIn = type.getQualifier().builtIn;
|
||||
|
||||
type.getQualifier() = qualifier;
|
||||
}
|
||||
|
||||
@@ -1035,7 +1038,8 @@ bool HlslGrammar::acceptStreamOutTemplateType(TType& type, TLayoutGeometry& geom
|
||||
return false;
|
||||
}
|
||||
|
||||
type.getQualifier().storage = EvqVaryingOut;
|
||||
type.getQualifier().storage = EvqOut;
|
||||
type.getQualifier().builtIn = EbvGsOutputStream;
|
||||
|
||||
if (! acceptTokenClass(EHTokRightAngle)) {
|
||||
expected("right angle bracket");
|
||||
|
||||
@@ -66,7 +66,8 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
|
||||
nextInLocation(0), nextOutLocation(0),
|
||||
sourceEntryPointName(sourceEntryPointName),
|
||||
entryPointFunction(nullptr),
|
||||
entryPointFunctionBody(nullptr)
|
||||
entryPointFunctionBody(nullptr),
|
||||
gsStreamOutput(nullptr)
|
||||
{
|
||||
globalUniformDefaults.clear();
|
||||
globalUniformDefaults.layoutMatrix = ElmRowMajor;
|
||||
@@ -1852,11 +1853,15 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
|
||||
TIntermAggregate* synthBody = new TIntermAggregate();
|
||||
auto inputIt = inputs.begin();
|
||||
TIntermTyped* callingArgs = nullptr;
|
||||
|
||||
for (int i = 0; i < userFunction.getParamCount(); i++) {
|
||||
TParameter& param = userFunction[i];
|
||||
argVars.push_back(makeInternalVariable(*param.name, *param.type));
|
||||
|
||||
argVars.back()->getWritableType().getQualifier().makeTemporary();
|
||||
|
||||
TIntermSymbol* arg = intermediate.addSymbol(*argVars.back());
|
||||
|
||||
handleFunctionArgument(&callee, callingArgs, arg);
|
||||
if (param.type->getQualifier().isParamInput()) {
|
||||
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
|
||||
@@ -1911,10 +1916,20 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
|
||||
auto outputIt = outputs.begin();
|
||||
for (int i = 0; i < userFunction.getParamCount(); i++) {
|
||||
TParameter& param = userFunction[i];
|
||||
|
||||
// GS outputs are via emit, so we do not copy them here.
|
||||
if (param.type->getQualifier().isParamOutput()) {
|
||||
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign,
|
||||
intermediate.addSymbol(**outputIt),
|
||||
intermediate.addSymbol(*argVars[i])));
|
||||
if (param.declaredBuiltIn == EbvGsOutputStream) {
|
||||
// GS output stream does not assign outputs here: it's the Append() method
|
||||
// which writes to the output, probably multiple times separated by Emit.
|
||||
// We merely remember the output to use, here.
|
||||
gsStreamOutput = *outputIt;
|
||||
} else {
|
||||
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign,
|
||||
intermediate.addSymbol(**outputIt),
|
||||
intermediate.addSymbol(*argVars[i])));
|
||||
}
|
||||
|
||||
outputIt++;
|
||||
}
|
||||
}
|
||||
@@ -3301,9 +3316,15 @@ void HlslParseContext::decomposeGeometryMethods(const TSourceLoc& loc, TIntermTy
|
||||
emit->setLoc(loc);
|
||||
emit->setType(TType(EbtVoid));
|
||||
|
||||
// find the matching output
|
||||
if (gsStreamOutput == nullptr) {
|
||||
error(loc, "unable to find output symbol for Append()", "", "");
|
||||
return;
|
||||
}
|
||||
|
||||
sequence = intermediate.growAggregate(sequence,
|
||||
handleAssign(loc, EOpAssign,
|
||||
argAggregate->getSequence()[0]->getAsTyped(),
|
||||
intermediate.addSymbol(*gsStreamOutput, loc),
|
||||
argAggregate->getSequence()[1]->getAsTyped()),
|
||||
loc);
|
||||
|
||||
|
||||
@@ -405,6 +405,8 @@ protected:
|
||||
|
||||
TVector<TString> currentTypePrefix; // current scoping prefix for nested structures
|
||||
TVector<TVariable*> implicitThisStack; // currently active 'this' variables for nested structures
|
||||
|
||||
TVariable* gsStreamOutput; // geometry shader stream outputs, for emit (Append method)
|
||||
};
|
||||
|
||||
// This is the prefix we use for builtin methods to avoid namespace collisions with
|
||||
|
||||
Reference in New Issue
Block a user