Implement GL_OES_shader_multisample_interpolation, as well as core desktop versions of it.
This commit is contained in:
parent
ba01ebd5ba
commit
0fc4338f3e
17 changed files with 829 additions and 9 deletions
|
|
@ -226,6 +226,10 @@ enum TOperator {
|
|||
EOpDPdyCoarse, // Fragment only
|
||||
EOpFwidthCoarse, // Fragment only
|
||||
|
||||
EOpInterpolateAtCentroid, // Fragment only
|
||||
EOpInterpolateAtSample, // Fragment only
|
||||
EOpInterpolateAtOffset, // Fragment only
|
||||
|
||||
EOpMatrixTimesMatrix,
|
||||
EOpOuterProduct,
|
||||
EOpDeterminant,
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
// 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).
|
||||
|
||||
#define GLSLANG_REVISION "3.0.730"
|
||||
#define GLSLANG_DATE "21-Aug-2015"
|
||||
#define GLSLANG_REVISION "3.0.732"
|
||||
#define GLSLANG_DATE "22-Aug-2015"
|
||||
|
|
|
|||
|
|
@ -1185,6 +1185,28 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
"\n");
|
||||
}
|
||||
|
||||
// GL_OES_shader_multisample_interpolation
|
||||
if ((profile == EEsProfile && version >= 310) ||
|
||||
(profile != EEsProfile && version >= 400)) {
|
||||
stageBuiltins[EShLangFragment].append(
|
||||
"float interpolateAtCentroid(float);"
|
||||
"vec2 interpolateAtCentroid(vec2);"
|
||||
"vec3 interpolateAtCentroid(vec3);"
|
||||
"vec4 interpolateAtCentroid(vec4);"
|
||||
|
||||
"float interpolateAtSample(float, int);"
|
||||
"vec2 interpolateAtSample(vec2, int);"
|
||||
"vec3 interpolateAtSample(vec3, int);"
|
||||
"vec4 interpolateAtSample(vec4, int);"
|
||||
|
||||
"float interpolateAtOffset(float, vec2);"
|
||||
"vec2 interpolateAtOffset(vec2, vec2);"
|
||||
"vec3 interpolateAtOffset(vec3, vec2);"
|
||||
"vec4 interpolateAtOffset(vec4, vec2);"
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Standard Uniforms
|
||||
|
|
@ -3009,8 +3031,12 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||
symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_OES_standard_derivatives);
|
||||
symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_OES_standard_derivatives);
|
||||
}
|
||||
if (version >= 310)
|
||||
if (version >= 310) {
|
||||
symbolTable.setFunctionExtensions("fma", Num_AEP_gpu_shader5, AEP_gpu_shader5);
|
||||
symbolTable.setFunctionExtensions("interpolateAtCentroid", 1, &E_GL_OES_shader_multisample_interpolation);
|
||||
symbolTable.setFunctionExtensions("interpolateAtSample", 1, &E_GL_OES_shader_multisample_interpolation);
|
||||
symbolTable.setFunctionExtensions("interpolateAtOffset", 1, &E_GL_OES_shader_multisample_interpolation);
|
||||
}
|
||||
} else if (version < 130) {
|
||||
symbolTable.setFunctionExtensions("texture1DLod", 1, &E_GL_ARB_shader_texture_lod);
|
||||
symbolTable.setFunctionExtensions("texture2DLod", 1, &E_GL_ARB_shader_texture_lod);
|
||||
|
|
@ -3351,6 +3377,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||
symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse);
|
||||
symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse);
|
||||
}
|
||||
symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid);
|
||||
symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample);
|
||||
symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset);
|
||||
break;
|
||||
|
||||
case EShLangCompute:
|
||||
|
|
|
|||
|
|
@ -860,6 +860,35 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc&
|
|||
return node;
|
||||
}
|
||||
|
||||
//
|
||||
// Follow the left branches down to the root of an l-value
|
||||
// expression (just "." and []).
|
||||
//
|
||||
// Return the base of the l-value (where following indexing quits working).
|
||||
// Return nullptr if a chain following dereferences cannot be followed.
|
||||
//
|
||||
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
|
||||
// a valid part of the dereference chain.
|
||||
//
|
||||
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
|
||||
{
|
||||
do {
|
||||
const TIntermBinary* binary = node->getAsBinaryNode();
|
||||
if (binary == nullptr)
|
||||
return node;
|
||||
TOperator op = binary->getOp();
|
||||
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle)
|
||||
return nullptr;
|
||||
if (! swizzleOkay) {
|
||||
if (op == EOpVectorSwizzle)
|
||||
return nullptr;
|
||||
if ((op == EOpIndexDirect || op == EOpIndexIndirect) && binary->getLeft()->getType().isVector() && ! binary->getLeft()->getType().isArray())
|
||||
return nullptr;
|
||||
}
|
||||
node = node->getAsBinaryNode()->getLeft();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
//
|
||||
// Create loop nodes.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1485,6 +1485,30 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
break;
|
||||
}
|
||||
|
||||
case EOpInterpolateAtCentroid:
|
||||
case EOpInterpolateAtSample:
|
||||
case EOpInterpolateAtOffset:
|
||||
// "For the interpolateAt* functions, the call will return a precision
|
||||
// qualification matching the precision of the 'interpolant' argument to
|
||||
// the function call."
|
||||
callNode.getQualifier().precision = arg0->getQualifier().precision;
|
||||
|
||||
// Make sure the first argument is an interpolant, or an array element of an interpolant
|
||||
if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
|
||||
// It might still be an array element.
|
||||
//
|
||||
// We could check more, but the semantics of the first argument are already met; the
|
||||
// only way to turn an array into a float/vec* is array dereference and swizzle.
|
||||
//
|
||||
// ES and desktop 4.3 and earlier: swizzles may not be used
|
||||
// desktop 4.4 and later: swizzles may be used
|
||||
bool swizzleOkay = (profile != EEsProfile) && (version >= 440);
|
||||
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
|
||||
if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
|
||||
error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2456,6 +2480,10 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||
error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), "");
|
||||
return;
|
||||
}
|
||||
if (qualifier.isAuxiliary())
|
||||
error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", "");
|
||||
if (qualifier.isInterpolation())
|
||||
error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", "");
|
||||
break;
|
||||
|
||||
case EShLangCompute:
|
||||
|
|
|
|||
|
|
@ -738,6 +738,10 @@ int TScanContext::tokenizeIdentifier()
|
|||
return es30ReservedFromGLSL(400);
|
||||
|
||||
case SAMPLE:
|
||||
if (parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation))
|
||||
return keyword;
|
||||
return es30ReservedFromGLSL(400);
|
||||
|
||||
case SUBROUTINE:
|
||||
return es30ReservedFromGLSL(400);
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ void TParseContext::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisablePartial;
|
||||
extensionBehavior[E_GL_OES_sample_variables] = EBhDisable;
|
||||
extensionBehavior[E_GL_OES_shader_image_atomic] = EBhDisable;
|
||||
extensionBehavior[E_GL_OES_shader_multisample_interpolation] = EBhDisablePartial;
|
||||
extensionBehavior[E_GL_OES_shader_multisample_interpolation] = EBhDisable;
|
||||
extensionBehavior[E_GL_OES_texture_storage_multisample_2d_array] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_geometry_shader] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_geometry_point_size] = EBhDisable;
|
||||
|
|
|
|||
|
|
@ -286,6 +286,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||
case EOpDPdxCoarse: out.debug << "dPdxCoarse"; break;
|
||||
case EOpDPdyCoarse: out.debug << "dPdyCoarse"; break;
|
||||
case EOpFwidthCoarse: out.debug << "fwidthCoarse"; break;
|
||||
|
||||
case EOpInterpolateAtCentroid: out.debug << "interpolateAtCentroid"; break;
|
||||
|
||||
case EOpDeterminant: out.debug << "determinant"; break;
|
||||
case EOpMatrixInverse: out.debug << "inverse"; break;
|
||||
case EOpTranspose: out.debug << "transpose"; break;
|
||||
|
|
@ -473,8 +476,11 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||
case EOpBitfieldInsert: out.debug << "bitfieldInsert"; break;
|
||||
|
||||
case EOpFma: out.debug << "fma"; break;
|
||||
case EOpFrexp: out.debug << "frexp"; break;
|
||||
case EOpLdexp: out.debug << "ldexp"; break;
|
||||
case EOpFrexp: out.debug << "frexp"; break;
|
||||
case EOpLdexp: out.debug << "ldexp"; break;
|
||||
|
||||
case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
||||
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
||||
|
||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@ public:
|
|||
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
|
||||
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc&);
|
||||
|
||||
// Tree ops
|
||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
|
||||
|
||||
// Linkage related
|
||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue