mirror of
https://github.com/RPCS3/glslang.git
synced 2024-11-24 03:39:51 +00:00
Non-Functional: Whitespace, comments, replace accidentally deleted comment.
- fixed ParseHelper.cpp newlines (crlf -> lf) - removed trailing white space in most source files - fix some spelling issues - extra blank lines - tabs to spaces - replace #include comment about no location
This commit is contained in:
parent
3dd32293f4
commit
ecba76fe73
@ -439,7 +439,6 @@ spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qual
|
||||
return spv::DecorationMax;
|
||||
}
|
||||
|
||||
|
||||
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
|
||||
// associated capabilities when required. For some built-in variables, a capability
|
||||
// is generated only when using the variable in an executable instruction, but not when
|
||||
@ -1633,7 +1632,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
|
||||
// Does it need a swizzle inversion? If so, evaluation is inverted;
|
||||
// operate first on the swizzle base, then apply the swizzle.
|
||||
if (glslangOperands[0]->getAsOperator() &&
|
||||
if (glslangOperands[0]->getAsOperator() &&
|
||||
glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
|
||||
invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
|
||||
}
|
||||
@ -1960,7 +1959,7 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
|
||||
// is applied.
|
||||
spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyped& node)
|
||||
{
|
||||
if (node.getAsOperator() &&
|
||||
if (node.getAsOperator() &&
|
||||
node.getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
|
||||
return convertGlslangToSpvType(node.getAsBinaryNode()->getLeft()->getType());
|
||||
else
|
||||
@ -2139,7 +2138,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
||||
return spvType;
|
||||
}
|
||||
|
||||
|
||||
// Do full recursive conversion of a glslang structure (or block) type to a SPIR-V Id.
|
||||
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
|
||||
// Mutually recursive with convertGlslangToSpvType().
|
||||
@ -3012,7 +3010,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
}
|
||||
// copy the projective coordinate if we have to
|
||||
if (projTargetComp != projSourceComp) {
|
||||
spv::Id projComp = builder.createCompositeExtract(params.coords,
|
||||
spv::Id projComp = builder.createCompositeExtract(params.coords,
|
||||
builder.getScalarTypeId(builder.getTypeId(params.coords)),
|
||||
projSourceComp);
|
||||
params.coords = builder.createCompositeInsert(projComp, params.coords,
|
||||
@ -4731,7 +4729,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||
if (builtIn != spv::BuiltInMax)
|
||||
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (builtIn == spv::BuiltInSampleMask) {
|
||||
spv::Decoration decoration;
|
||||
// GL_NV_sample_mask_override_coverage extension
|
||||
|
@ -103,10 +103,10 @@ namespace spv {
|
||||
|
||||
switch (opCode) {
|
||||
case spv::OpTypeVector: // fall through
|
||||
case spv::OpTypeMatrix: // ...
|
||||
case spv::OpTypeSampler: // ...
|
||||
case spv::OpTypeArray: // ...
|
||||
case spv::OpTypeRuntimeArray: // ...
|
||||
case spv::OpTypeMatrix: // ...
|
||||
case spv::OpTypeSampler: // ...
|
||||
case spv::OpTypeArray: // ...
|
||||
case spv::OpTypeRuntimeArray: // ...
|
||||
case spv::OpTypePipe: return range_t(2, 3);
|
||||
case spv::OpTypeStruct: // fall through
|
||||
case spv::OpTypeFunction: return range_t(2, maxCount);
|
||||
@ -286,7 +286,6 @@ namespace spv {
|
||||
return literal;
|
||||
}
|
||||
|
||||
|
||||
void spirvbin_t::applyMap()
|
||||
{
|
||||
msg(3, 2, std::string("Applying map: "));
|
||||
@ -300,7 +299,6 @@ namespace spv {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Find free IDs for anything we haven't mapped
|
||||
void spirvbin_t::mapRemainder()
|
||||
{
|
||||
@ -355,7 +353,7 @@ namespace spv {
|
||||
if (idPosR.find(asId(start+1)) == idPosR.end())
|
||||
stripInst(start);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break; // leave it alone
|
||||
}
|
||||
|
||||
@ -399,7 +397,7 @@ namespace spv {
|
||||
if (spv::InstructionDesc[opCode].hasResult()) {
|
||||
const spv::Id resultId = asId(word++);
|
||||
idPosR[resultId] = start;
|
||||
|
||||
|
||||
if (typeId != spv::NoResult) {
|
||||
const unsigned idTypeSize = typeSizeInWords(typeId);
|
||||
|
||||
@ -462,7 +460,6 @@ namespace spv {
|
||||
error("bad schema, must be 0");
|
||||
}
|
||||
|
||||
|
||||
int spirvbin_t::processInstruction(unsigned word, instfn_t instFn, idfn_t idFn)
|
||||
{
|
||||
const auto instructionStart = word;
|
||||
@ -902,7 +899,7 @@ namespace spv {
|
||||
},
|
||||
|
||||
// If local var id used anywhere else, don't eliminate
|
||||
[&](spv::Id& id) {
|
||||
[&](spv::Id& id) {
|
||||
if (fnLocalVars.count(id) > 0) {
|
||||
fnLocalVars.erase(id);
|
||||
idMap.erase(id);
|
||||
@ -1079,7 +1076,6 @@ namespace spv {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOTDEF
|
||||
bool spirvbin_t::matchType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const
|
||||
{
|
||||
@ -1139,7 +1135,6 @@ namespace spv {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Look for an equivalent type in the globalTypes map
|
||||
spv::Id spirvbin_t::findType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt) const
|
||||
{
|
||||
@ -1261,7 +1256,6 @@ namespace spv {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Strip a single binary by removing ranges given in stripRange
|
||||
void spirvbin_t::strip()
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ class spirvbin_t : public spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose) { }
|
||||
|
||||
|
||||
// remap on an existing binary in memory
|
||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
@ -175,7 +175,7 @@ private:
|
||||
range_t constRange(spv::Op opCode) const;
|
||||
unsigned typeSizeInWords(spv::Id id) const;
|
||||
unsigned idTypeSizeInWords(spv::Id id) const;
|
||||
|
||||
|
||||
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
|
||||
@ -242,7 +242,7 @@ private:
|
||||
void stripDebug(); // strip all debug info
|
||||
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||
void strip(); // remove debug symbols
|
||||
|
||||
|
||||
std::vector<spirword_t> spv; // SPIR words
|
||||
|
||||
namemap_t nameMap; // ID names from OpName
|
||||
@ -268,11 +268,11 @@ private:
|
||||
|
||||
// Which functions are called, anywhere in the module, with a call count
|
||||
std::unordered_map<spv::Id, int> fnCalls;
|
||||
|
||||
|
||||
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||
posmap_rev_t idPosR; // reverse map from IDs to positions
|
||||
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
|
||||
|
||||
|
||||
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
||||
|
||||
spv::Id entryPoint; // module entry point
|
||||
|
@ -79,7 +79,7 @@ Id Builder::import(const char* name)
|
||||
{
|
||||
Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);
|
||||
import->addStringOperand(name);
|
||||
|
||||
|
||||
imports.push_back(std::unique_ptr<Instruction>(import));
|
||||
return import->getResultId();
|
||||
}
|
||||
@ -246,7 +246,7 @@ Id Builder::makeStructResultType(Id type0, Id type1)
|
||||
type = groupedTypes[OpTypeStruct][t];
|
||||
if (type->getNumOperands() != 2)
|
||||
continue;
|
||||
if (type->getIdOperand(0) != type0 ||
|
||||
if (type->getIdOperand(0) != type0 ||
|
||||
type->getIdOperand(1) != type1)
|
||||
continue;
|
||||
return type->getResultId();
|
||||
@ -628,7 +628,7 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1,
|
||||
bool Builder::isConstantOpCode(Op opcode) const
|
||||
{
|
||||
switch (opcode) {
|
||||
case OpUndef:
|
||||
case OpUndef:
|
||||
case OpConstantTrue:
|
||||
case OpConstantFalse:
|
||||
case OpConstant:
|
||||
@ -1936,7 +1936,6 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Step 2: Construct a matrix from that array.
|
||||
// First make the column vectors, then make the matrix.
|
||||
|
||||
|
@ -36,9 +36,9 @@
|
||||
//
|
||||
// Simple in-memory representation (IR) of SPIRV. Just for holding
|
||||
// Each function's CFG of blocks. Has this hierarchy:
|
||||
// - Module, which is a list of
|
||||
// - Function, which is a list of
|
||||
// - Block, which is a list of
|
||||
// - Module, which is a list of
|
||||
// - Function, which is a list of
|
||||
// - Block, which is a list of
|
||||
// - Instruction
|
||||
//
|
||||
|
||||
@ -65,7 +65,7 @@ const Id NoResult = 0;
|
||||
const Id NoType = 0;
|
||||
|
||||
const Decoration NoPrecision = DecorationMax;
|
||||
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||
(MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask |
|
||||
MemorySemanticsUniformMemoryMask |
|
||||
MemorySemanticsSubgroupMemoryMask |
|
||||
@ -229,7 +229,7 @@ protected:
|
||||
std::vector<std::unique_ptr<Instruction> > localVariables;
|
||||
Function& parent;
|
||||
|
||||
// track whether this block is known to be uncreachable (not necessarily
|
||||
// track whether this block is known to be uncreachable (not necessarily
|
||||
// true for all unreachable blocks, but should be set at least
|
||||
// for the extraneous ones introduced by the builder).
|
||||
bool unreachable;
|
||||
|
@ -229,7 +229,7 @@ void ProcessBindingBase(int& argc, char**& argv, std::array<unsigned int, EShLan
|
||||
if (!isdigit(argv[1][0])) {
|
||||
if (argc < 3) // this form needs one more argument
|
||||
usage();
|
||||
|
||||
|
||||
// Parse form: --argname stage base
|
||||
const EShLanguage lang = FindLanguage(argv[1], false);
|
||||
base[lang] = atoi(argv[2]);
|
||||
@ -265,7 +265,7 @@ void ProcessArguments(int argc, char* argv[])
|
||||
Work[w] = 0;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
argv++;
|
||||
for (; argc >= 1; argc--, argv++) {
|
||||
if (argv[0][0] == '-') {
|
||||
switch (argv[0][1]) {
|
||||
@ -292,7 +292,7 @@ void ProcessArguments(int argc, char* argv[])
|
||||
lowerword == "sub") {
|
||||
ProcessBindingBase(argc, argv, baseUboBinding);
|
||||
} else if (lowerword == "auto-map-bindings" || // synonyms
|
||||
lowerword == "auto-map-binding" ||
|
||||
lowerword == "auto-map-binding" ||
|
||||
lowerword == "amb") {
|
||||
Options |= EOptionAutoMapBindings;
|
||||
} else if (lowerword == "flatten-uniform-arrays" || // synonyms
|
||||
@ -575,7 +575,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||
|
||||
if (Options & EOptionAutoMapBindings)
|
||||
shader->setAutoMapBindings(true);
|
||||
|
||||
|
||||
shaders.push_back(shader);
|
||||
|
||||
const int defaultVersion = Options & EOptionDefaultDesktop? 110: 100;
|
||||
@ -619,7 +619,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||
if (!program.mapIO())
|
||||
LinkFailed = true;
|
||||
}
|
||||
|
||||
|
||||
// Report
|
||||
if (! (Options & EOptionSuppressInfolog) &&
|
||||
! (Options & EOptionMemoryLeakMode)) {
|
||||
@ -863,7 +863,7 @@ EShLanguage FindLanguage(const std::string& name, bool parseSuffix)
|
||||
}
|
||||
|
||||
//
|
||||
// Read a file's data into a string, and compile it using the old interface ShCompile,
|
||||
// Read a file's data into a string, and compile it using the old interface ShCompile,
|
||||
// for non-linkable results.
|
||||
//
|
||||
void CompileFile(const char* fileName, ShHandle compiler)
|
||||
@ -887,13 +887,13 @@ void CompileFile(const char* fileName, ShHandle compiler)
|
||||
|
||||
EShMessages messages = EShMsgDefault;
|
||||
SetMessageOptions(messages);
|
||||
|
||||
|
||||
for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
|
||||
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
|
||||
//ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
ret = ShCompile(compiler, shaderStrings, NumShaderStrings, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
//const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
|
||||
// "or should be l", "ine 1", "string 5\n", "float glo", "bal",
|
||||
//const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
|
||||
// "or should be l", "ine 1", "string 5\n", "float glo", "bal",
|
||||
// ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
|
||||
//const char* multi[7] = { "/", "/", "\\", "\n", "\n", "#", "version 300 es" };
|
||||
//ret = ShCompile(compiler, multi, 7, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
@ -1024,7 +1024,7 @@ int fopen_s(
|
||||
//
|
||||
// Malloc a string of sufficient size and read a string into it.
|
||||
//
|
||||
char** ReadFileData(const char* fileName)
|
||||
char** ReadFileData(const char* fileName)
|
||||
{
|
||||
FILE *in = nullptr;
|
||||
int errorCode = fopen_s(&in, fileName, "r");
|
||||
@ -1035,7 +1035,7 @@ char** ReadFileData(const char* fileName)
|
||||
|
||||
if (errorCode || in == nullptr)
|
||||
Error("unable to open input file");
|
||||
|
||||
|
||||
while (fgetc(in) != EOF)
|
||||
count++;
|
||||
|
||||
@ -1080,7 +1080,7 @@ char** ReadFileData(const char* fileName)
|
||||
break;
|
||||
}
|
||||
len = count;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
|
@ -59,21 +59,21 @@ namespace glslang {
|
||||
void add(TWorkItem* item)
|
||||
{
|
||||
GetGlobalLock();
|
||||
|
||||
|
||||
worklist.push_back(item);
|
||||
|
||||
|
||||
ReleaseGlobalLock();
|
||||
}
|
||||
|
||||
|
||||
bool remove(TWorkItem*& item)
|
||||
{
|
||||
GetGlobalLock();
|
||||
|
||||
|
||||
if (worklist.empty())
|
||||
return false;
|
||||
item = worklist.front();
|
||||
worklist.pop_front();
|
||||
|
||||
|
||||
ReleaseGlobalLock();
|
||||
|
||||
return true;
|
||||
|
@ -143,8 +143,8 @@ namespace {
|
||||
<< " [--map (all|types|names|funcs)]"
|
||||
<< " [--dce (all|types|funcs)]"
|
||||
<< " [--opt (all|loadstore)]"
|
||||
<< " [--strip-all | --strip all | -s]"
|
||||
<< " [--do-everything]"
|
||||
<< " [--strip-all | --strip all | -s]"
|
||||
<< " [--do-everything]"
|
||||
<< " --input | -i file1 [file2...] --output|-o DESTDIR"
|
||||
<< std::endl;
|
||||
|
||||
@ -311,7 +311,6 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::vector<std::string> inputFile;
|
||||
|
@ -84,7 +84,7 @@ enum TStorageQualifier {
|
||||
EvqUniform, // read only, shared with app
|
||||
EvqBuffer, // read/write, shared with app
|
||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||
|
||||
|
||||
// parameters
|
||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
||||
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
|
||||
@ -212,7 +212,7 @@ enum TBuiltInVariable {
|
||||
};
|
||||
|
||||
// These will show up in error messages
|
||||
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||
{
|
||||
switch (q) {
|
||||
case EvqTemporary: return "temp"; break;
|
||||
|
@ -66,7 +66,7 @@ std::string to_string(const T& val) {
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||
inline long long int strtoll (const char* str, char** endptr, int base)
|
||||
{
|
||||
return _strtoi64(str, endptr, base);
|
||||
return _strtoi64(str, endptr, base);
|
||||
}
|
||||
inline unsigned long long int strtoull (const char* str, char** endptr, int base)
|
||||
{
|
||||
@ -178,7 +178,7 @@ public:
|
||||
template <class T> class TList : public std::list<T, pool_allocator<T> > {
|
||||
};
|
||||
|
||||
template <class K, class D, class CMP = std::less<K> >
|
||||
template <class K, class D, class CMP = std::less<K> >
|
||||
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > {
|
||||
};
|
||||
|
||||
@ -212,14 +212,14 @@ inline const TString String(const int i, const int base = 10)
|
||||
inline const TString String(const int i, const int /*base*/ = 10)
|
||||
{
|
||||
char text[16]; // 32 bit ints are at most 10 digits in base 10
|
||||
|
||||
|
||||
// we assume base 10 for all cases
|
||||
snprintf(text, sizeof(text), "%d", i);
|
||||
|
||||
return text;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct TSourceLoc {
|
||||
void init() { name = nullptr; string = 0; line = 0; column = 0; }
|
||||
// Returns the name if it exists. Otherwise, returns the string number.
|
||||
|
@ -46,14 +46,14 @@ public:
|
||||
TConstUnion() : iConst(0), type(EbtInt) { }
|
||||
|
||||
void setIConst(int i)
|
||||
{
|
||||
iConst = i;
|
||||
{
|
||||
iConst = i;
|
||||
type = EbtInt;
|
||||
}
|
||||
|
||||
void setUConst(unsigned int u)
|
||||
{
|
||||
uConst = u;
|
||||
uConst = u;
|
||||
type = EbtUint;
|
||||
}
|
||||
|
||||
@ -71,13 +71,13 @@ public:
|
||||
|
||||
void setDConst(double d)
|
||||
{
|
||||
dConst = d;
|
||||
dConst = d;
|
||||
type = EbtDouble;
|
||||
}
|
||||
|
||||
void setBConst(bool b)
|
||||
{
|
||||
bConst = b;
|
||||
bConst = b;
|
||||
type = EbtBool;
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ public:
|
||||
}
|
||||
|
||||
bool operator>(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
@ -250,7 +250,7 @@ public:
|
||||
}
|
||||
|
||||
bool operator<(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
@ -285,7 +285,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator+(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -301,7 +301,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator-(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -317,7 +317,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator*(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -325,7 +325,7 @@ public:
|
||||
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
||||
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator%(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -348,7 +348,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator>>(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
@ -394,7 +394,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator<<(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
@ -440,7 +440,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator&(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -455,7 +455,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator|(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -470,7 +470,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator^(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -485,7 +485,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator~() const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(~iConst); break;
|
||||
@ -499,7 +499,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator&&(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -511,7 +511,7 @@ public:
|
||||
}
|
||||
|
||||
TConstUnion operator||(const TConstUnion& constant) const
|
||||
{
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
@ -544,7 +544,7 @@ private:
|
||||
// One convenience is being able to use [] to go inside the array, instead
|
||||
// of C++ assuming it as an array of pointers to vectors.
|
||||
//
|
||||
// General usage is that the size is known up front, and it is
|
||||
// General usage is that the size is known up front, and it is
|
||||
// created once with the proper size.
|
||||
//
|
||||
class TConstUnionArray {
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
|
||||
TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
|
||||
TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; }
|
||||
TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size];
|
||||
TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size];
|
||||
snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n);
|
||||
append(buf);
|
||||
append(buf);
|
||||
return *this; }
|
||||
TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
|
||||
TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
|
||||
@ -113,20 +113,20 @@ public:
|
||||
append(s);
|
||||
append("\n");
|
||||
}
|
||||
|
||||
|
||||
void setOutputStream(int output = 4)
|
||||
{
|
||||
outputStream = output;
|
||||
}
|
||||
|
||||
protected:
|
||||
void append(const char* s);
|
||||
void append(const char* s);
|
||||
|
||||
void append(int count, char c);
|
||||
void append(const TPersistString& t);
|
||||
void append(const TString& t);
|
||||
|
||||
void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
|
||||
void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
|
||||
sink.reserve(sink.capacity() + sink.capacity() / 2); }
|
||||
void appendToStream(const char* s);
|
||||
TPersistString sink;
|
||||
|
@ -43,8 +43,8 @@
|
||||
|
||||
//
|
||||
// This header defines an allocator that can be used to efficiently
|
||||
// allocate a large number of small requests for heap memory, with the
|
||||
// intention that they are not individually deallocated, but rather
|
||||
// allocate a large number of small requests for heap memory, with the
|
||||
// intention that they are not individually deallocated, but rather
|
||||
// collectively deallocated at one time.
|
||||
//
|
||||
// This simultaneously
|
||||
@ -70,7 +70,7 @@ namespace glslang {
|
||||
// If we are using guard blocks, we must track each individual
|
||||
// allocation. If we aren't using guard blocks, these
|
||||
// never get instantiated, so won't have any impact.
|
||||
//
|
||||
//
|
||||
|
||||
class TAllocation {
|
||||
public:
|
||||
@ -87,7 +87,7 @@ public:
|
||||
memset(postGuard(), guardBlockEndVal, guardBlockSize);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void check() const {
|
||||
checkGuardBlock(preGuard(), guardBlockBeginVal, "before");
|
||||
checkGuardBlock(postGuard(), guardBlockEndVal, "after");
|
||||
@ -100,7 +100,7 @@ public:
|
||||
inline static size_t allocationSize(size_t size) {
|
||||
return size + 2 * guardBlockSize + headerSize();
|
||||
}
|
||||
|
||||
|
||||
// Offset from surrounding buffer to get to user data buffer.
|
||||
inline static unsigned char* offsetAllocation(unsigned char* m) {
|
||||
return m + guardBlockSize + headerSize();
|
||||
@ -123,16 +123,16 @@ private:
|
||||
const static unsigned char userDataFill;
|
||||
|
||||
const static size_t guardBlockSize;
|
||||
# ifdef GUARD_BLOCKS
|
||||
# ifdef GUARD_BLOCKS
|
||||
inline static size_t headerSize() { return sizeof(TAllocation); }
|
||||
# else
|
||||
inline static size_t headerSize() { return 0; }
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// There are several stacks. One is to track the pushing and popping
|
||||
// of the user, and not yet implemented. The others are simply a
|
||||
// of the user, and not yet implemented. The others are simply a
|
||||
// repositories of free pages or used pages.
|
||||
//
|
||||
// Page stacks are linked together with a simple header at the beginning
|
||||
@ -141,7 +141,7 @@ private:
|
||||
// re-use.
|
||||
//
|
||||
// The "page size" used is not, nor must it match, the underlying OS
|
||||
// page size. But, having it be about that size or equal to a set of
|
||||
// page size. But, having it be about that size or equal to a set of
|
||||
// pages is likely most optimal.
|
||||
//
|
||||
class TPoolAllocator {
|
||||
@ -185,7 +185,7 @@ public:
|
||||
|
||||
protected:
|
||||
friend struct tHeader;
|
||||
|
||||
|
||||
struct tHeader {
|
||||
tHeader(tHeader* nextPage, size_t pageCount) :
|
||||
#ifdef GUARD_BLOCKS
|
||||
@ -227,7 +227,7 @@ protected:
|
||||
}
|
||||
|
||||
size_t pageSize; // granularity of allocation from the OS
|
||||
size_t alignment; // all returned allocations will be aligned at
|
||||
size_t alignment; // all returned allocations will be aligned at
|
||||
// this granularity, which will be a power of 2
|
||||
size_t alignmentMask;
|
||||
size_t headerSkip; // amount of memory to skip to make room for the
|
||||
@ -245,7 +245,6 @@ private:
|
||||
TPoolAllocator(const TPoolAllocator&); // don't allow default copy constructor
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// There could potentially be many pools with pops happening at
|
||||
// different times. But a simple use is to have a global pop
|
||||
@ -278,7 +277,7 @@ public:
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
template<class Other>
|
||||
template<class Other>
|
||||
struct rebind {
|
||||
typedef pool_allocator<Other> other;
|
||||
};
|
||||
@ -292,9 +291,9 @@ public:
|
||||
template<class Other>
|
||||
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
|
||||
|
||||
pointer allocate(size_type n) {
|
||||
pointer allocate(size_type n) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
|
||||
pointer allocate(size_type n, const void*) {
|
||||
pointer allocate(size_type n, const void*) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
|
||||
|
||||
void deallocate(void*, size_type) { }
|
||||
|
@ -81,7 +81,7 @@ struct TBuiltInResource {
|
||||
int maxComputeImageUniforms;
|
||||
int maxComputeAtomicCounters;
|
||||
int maxComputeAtomicCounterBuffers;
|
||||
int maxVaryingComponents;
|
||||
int maxVaryingComponents;
|
||||
int maxVertexOutputComponents;
|
||||
int maxGeometryInputComponents;
|
||||
int maxGeometryOutputComponents;
|
||||
|
@ -42,8 +42,7 @@
|
||||
// This should not be included by driver code.
|
||||
//
|
||||
|
||||
|
||||
#define SH_EXPORTING
|
||||
#define SH_EXPORTING
|
||||
#include "../Public/ShaderLang.h"
|
||||
#include "../MachineIndependent/Versions.h"
|
||||
#include "InfoSink.h"
|
||||
@ -73,7 +72,7 @@ public:
|
||||
TUniformMap() { }
|
||||
virtual ~TUniformMap() { }
|
||||
virtual TUniformMap* getAsUniformMap() { return this; }
|
||||
virtual int getLocation(const char* name) = 0;
|
||||
virtual int getLocation(const char* name) = 0;
|
||||
virtual TInfoSink& getInfoSink() { return infoSink; }
|
||||
TInfoSink infoSink;
|
||||
};
|
||||
@ -95,7 +94,7 @@ public:
|
||||
|
||||
virtual TCompiler* getAsCompiler() { return this; }
|
||||
virtual bool linkable() { return haveValidObjectCode; }
|
||||
|
||||
|
||||
TInfoSink& infoSink;
|
||||
protected:
|
||||
TCompiler& operator=(TCompiler&);
|
||||
@ -117,9 +116,9 @@ typedef glslang::TVector<TShHandleBase*> THandleList;
|
||||
|
||||
class TLinker : public TShHandleBase {
|
||||
public:
|
||||
TLinker(EShExecutable e, TInfoSink& iSink) :
|
||||
TLinker(EShExecutable e, TInfoSink& iSink) :
|
||||
infoSink(iSink),
|
||||
executable(e),
|
||||
executable(e),
|
||||
haveReturnableObjectCode(false),
|
||||
appAttributeBindings(0),
|
||||
fixedAttributeBindings(0),
|
||||
@ -147,7 +146,7 @@ protected:
|
||||
const ShBindingTable* fixedAttributeBindings;
|
||||
const int* excludedAttributes;
|
||||
int excludedCount;
|
||||
ShBindingTable* uniformBindings; // created by the linker
|
||||
ShBindingTable* uniformBindings; // created by the linker
|
||||
};
|
||||
|
||||
//
|
||||
@ -155,7 +154,7 @@ protected:
|
||||
// and the machine dependent code.
|
||||
//
|
||||
// The machine dependent code should derive from the classes
|
||||
// above. Then Construct*() and Delete*() will create and
|
||||
// above. Then Construct*() and Delete*() will create and
|
||||
// destroy the machine dependent objects, which contain the
|
||||
// above machine independent information.
|
||||
//
|
||||
@ -165,7 +164,7 @@ TShHandleBase* ConstructLinker(EShExecutable, int);
|
||||
TShHandleBase* ConstructBindings();
|
||||
void DeleteLinker(TShHandleBase*);
|
||||
void DeleteBindingList(TShHandleBase* bindingList);
|
||||
|
||||
|
||||
TUniformMap* ConstructUniformMap();
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
|
@ -421,7 +421,7 @@ public:
|
||||
clearLayout();
|
||||
}
|
||||
|
||||
// Drop just the storage qualification, which perhaps should
|
||||
// Drop just the storage qualification, which perhaps should
|
||||
// never be done, as it is fundamentally inconsistent, but need to
|
||||
// explore what downstream consumers need.
|
||||
// E.g., in a deference, it is an inconsistency between:
|
||||
@ -927,9 +927,9 @@ struct TShaderQualifiers {
|
||||
TLayoutDepth layoutDepth;
|
||||
bool blendEquation; // true if any blend equation was specified
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
bool layoutOverrideCoverage; // true if layout override_coverage set
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void init()
|
||||
{
|
||||
@ -950,7 +950,7 @@ struct TShaderQualifiers {
|
||||
earlyFragmentTests = false;
|
||||
layoutDepth = EldNone;
|
||||
blendEquation = false;
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
layoutOverrideCoverage = false;
|
||||
#endif
|
||||
}
|
||||
@ -989,10 +989,10 @@ struct TShaderQualifiers {
|
||||
layoutDepth = src.layoutDepth;
|
||||
if (src.blendEquation)
|
||||
blendEquation = src.blendEquation;
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (src.layoutOverrideCoverage)
|
||||
layoutOverrideCoverage = src.layoutOverrideCoverage;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -1085,7 +1085,7 @@ public:
|
||||
qualifier.storage = q;
|
||||
}
|
||||
// for explicit precision qualifier
|
||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
|
||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
|
||||
bool isVector = false) :
|
||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1),
|
||||
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
|
||||
@ -1332,7 +1332,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Recursively checks if the type contains the given basic type
|
||||
virtual bool containsBasicType(TBasicType checkType) const
|
||||
{
|
||||
@ -1601,7 +1601,6 @@ public:
|
||||
p += snprintf(p, end - p, "passthrough ");
|
||||
#endif
|
||||
|
||||
|
||||
p += snprintf(p, end - p, ") ");
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
// Definition of the in-memory high-level intermediate representation
|
||||
// of shaders. This is a tree that parser creates.
|
||||
//
|
||||
// Nodes in the tree are defined as a hierarchy of classes derived from
|
||||
// Nodes in the tree are defined as a hierarchy of classes derived from
|
||||
// TIntermNode. Each is a node in a tree. There is no preset branching factor;
|
||||
// each node can have it's own type of list of children.
|
||||
//
|
||||
@ -66,14 +66,14 @@ enum TOperator {
|
||||
EOpNull, // if in a node, should only mean a node is still being built
|
||||
EOpSequence, // denotes a list of statements, or parameters, etc.
|
||||
EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST
|
||||
EOpFunctionCall,
|
||||
EOpFunctionCall,
|
||||
EOpFunction, // For function definition
|
||||
EOpParameters, // an aggregate listing the parameters to a function
|
||||
|
||||
//
|
||||
// Unary operators
|
||||
//
|
||||
|
||||
|
||||
EOpNegative,
|
||||
EOpLogicalNot,
|
||||
EOpVectorLogicalNot,
|
||||
@ -445,7 +445,7 @@ enum TOperator {
|
||||
//
|
||||
// moves
|
||||
//
|
||||
|
||||
|
||||
EOpAssign,
|
||||
EOpAddAssign,
|
||||
EOpSubAssign,
|
||||
@ -709,7 +709,7 @@ public:
|
||||
virtual void setType(const TType& t) { type.shallowCopy(t); }
|
||||
virtual const TType& getType() const { return type; }
|
||||
virtual TType& getWritableType() { return type; }
|
||||
|
||||
|
||||
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
||||
virtual TQualifier& getQualifier() { return type.getQualifier(); }
|
||||
virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
|
||||
@ -734,7 +734,7 @@ protected:
|
||||
//
|
||||
class TIntermLoop : public TIntermNode {
|
||||
public:
|
||||
TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
|
||||
TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
|
||||
body(aBody),
|
||||
test(aTest),
|
||||
terminal(aTerminal),
|
||||
@ -1148,7 +1148,7 @@ enum TVisit
|
||||
};
|
||||
|
||||
//
|
||||
// For traversing the tree. User should derive from this,
|
||||
// For traversing the tree. User should derive from this,
|
||||
// put their traversal specific data in it, and then pass
|
||||
// it to a Traverse method.
|
||||
//
|
||||
@ -1160,10 +1160,10 @@ enum TVisit
|
||||
// the subtree). Similarly for inVisit for in-order visiting of nodes with
|
||||
// multiple children.
|
||||
//
|
||||
// If you only want post-visits, explicitly turn off preVisit (and inVisit)
|
||||
// If you only want post-visits, explicitly turn off preVisit (and inVisit)
|
||||
// and turn on postVisit.
|
||||
//
|
||||
// In general, for the visit*() methods, return true from interior nodes
|
||||
// In general, for the visit*() methods, return true from interior nodes
|
||||
// to have the traversal continue on to children.
|
||||
//
|
||||
// If you process children yourself, or don't want them processed, return false.
|
||||
|
@ -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 "Overload400-PrecQual.1744"
|
||||
#define GLSLANG_DATE "05-Jan-2017"
|
||||
#define GLSLANG_REVISION "Overload400-PrecQual.1747"
|
||||
#define GLSLANG_DATE "06-Jan-2017"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// The file revision.h should be updated to the latest version, somehow, on
|
||||
// The file revision.h should be updated to the latest version, somehow, on
|
||||
// check-in, if glslang has changed.
|
||||
//
|
||||
// revision.template is the source for revision.h when using SubWCRev as the
|
||||
|
@ -59,10 +59,10 @@ void TInfoSinkBase::append(const char* s)
|
||||
}
|
||||
|
||||
void TInfoSinkBase::append(int count, char c)
|
||||
{
|
||||
{
|
||||
if (outputStream & EString) {
|
||||
checkMem(count);
|
||||
sink.append(count, c);
|
||||
sink.append(count, c);
|
||||
}
|
||||
|
||||
//#ifdef _WIN32
|
||||
@ -79,10 +79,10 @@ void TInfoSinkBase::append(int count, char c)
|
||||
}
|
||||
|
||||
void TInfoSinkBase::append(const TPersistString& t)
|
||||
{
|
||||
{
|
||||
if (outputStream & EString) {
|
||||
checkMem(t.size());
|
||||
sink.append(t);
|
||||
sink.append(t);
|
||||
}
|
||||
|
||||
//#ifdef _WIN32
|
||||
@ -95,10 +95,10 @@ void TInfoSinkBase::append(const TPersistString& t)
|
||||
}
|
||||
|
||||
void TInfoSinkBase::append(const TString& t)
|
||||
{
|
||||
{
|
||||
if (outputStream & EString) {
|
||||
checkMem(t.size());
|
||||
sink.append(t.c_str());
|
||||
sink.append(t.c_str());
|
||||
}
|
||||
|
||||
//#ifdef _WIN32
|
||||
|
@ -36,7 +36,7 @@
|
||||
//
|
||||
|
||||
//
|
||||
// Create strings that declare built-in definitions, add built-ins programmatically
|
||||
// Create strings that declare built-in definitions, add built-ins programmatically
|
||||
// that cannot be expressed in the strings, and establish mappings between
|
||||
// built-in functions and operators.
|
||||
//
|
||||
@ -103,7 +103,6 @@ TBuiltIns::~TBuiltIns()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Add all context-independent built-in functions and variables that are present
|
||||
// for the given version and profile. Share common ones across stages, otherwise
|
||||
@ -128,47 +127,47 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 radians(vec2 degrees);"
|
||||
"vec3 radians(vec3 degrees);"
|
||||
"vec4 radians(vec4 degrees);"
|
||||
|
||||
|
||||
"float degrees(float radians);"
|
||||
"vec2 degrees(vec2 radians);"
|
||||
"vec3 degrees(vec3 radians);"
|
||||
"vec4 degrees(vec4 radians);"
|
||||
|
||||
|
||||
"float sin(float angle);"
|
||||
"vec2 sin(vec2 angle);"
|
||||
"vec3 sin(vec3 angle);"
|
||||
"vec4 sin(vec4 angle);"
|
||||
|
||||
|
||||
"float cos(float angle);"
|
||||
"vec2 cos(vec2 angle);"
|
||||
"vec3 cos(vec3 angle);"
|
||||
"vec4 cos(vec4 angle);"
|
||||
|
||||
|
||||
"float tan(float angle);"
|
||||
"vec2 tan(vec2 angle);"
|
||||
"vec3 tan(vec3 angle);"
|
||||
"vec4 tan(vec4 angle);"
|
||||
|
||||
|
||||
"float asin(float x);"
|
||||
"vec2 asin(vec2 x);"
|
||||
"vec3 asin(vec3 x);"
|
||||
"vec4 asin(vec4 x);"
|
||||
|
||||
|
||||
"float acos(float x);"
|
||||
"vec2 acos(vec2 x);"
|
||||
"vec3 acos(vec3 x);"
|
||||
"vec4 acos(vec4 x);"
|
||||
|
||||
|
||||
"float atan(float y, float x);"
|
||||
"vec2 atan(vec2 y, vec2 x);"
|
||||
"vec3 atan(vec3 y, vec3 x);"
|
||||
"vec4 atan(vec4 y, vec4 x);"
|
||||
|
||||
|
||||
"float atan(float y_over_x);"
|
||||
"vec2 atan(vec2 y_over_x);"
|
||||
"vec3 atan(vec3 y_over_x);"
|
||||
"vec4 atan(vec4 y_over_x);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
if (version >= 130) {
|
||||
@ -177,32 +176,32 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 sinh(vec2 angle);"
|
||||
"vec3 sinh(vec3 angle);"
|
||||
"vec4 sinh(vec4 angle);"
|
||||
|
||||
|
||||
"float cosh(float angle);"
|
||||
"vec2 cosh(vec2 angle);"
|
||||
"vec3 cosh(vec3 angle);"
|
||||
"vec4 cosh(vec4 angle);"
|
||||
|
||||
|
||||
"float tanh(float angle);"
|
||||
"vec2 tanh(vec2 angle);"
|
||||
"vec3 tanh(vec3 angle);"
|
||||
"vec4 tanh(vec4 angle);"
|
||||
|
||||
|
||||
"float asinh(float x);"
|
||||
"vec2 asinh(vec2 x);"
|
||||
"vec3 asinh(vec3 x);"
|
||||
"vec4 asinh(vec4 x);"
|
||||
|
||||
|
||||
"float acosh(float x);"
|
||||
"vec2 acosh(vec2 x);"
|
||||
"vec3 acosh(vec3 x);"
|
||||
"vec4 acosh(vec4 x);"
|
||||
|
||||
|
||||
"float atanh(float y_over_x);"
|
||||
"vec2 atanh(vec2 y_over_x);"
|
||||
"vec3 atanh(vec3 y_over_x);"
|
||||
"vec4 atanh(vec4 y_over_x);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -214,37 +213,37 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 pow(vec2 x, vec2 y);"
|
||||
"vec3 pow(vec3 x, vec3 y);"
|
||||
"vec4 pow(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"float exp(float x);"
|
||||
"vec2 exp(vec2 x);"
|
||||
"vec3 exp(vec3 x);"
|
||||
"vec4 exp(vec4 x);"
|
||||
|
||||
|
||||
"float log(float x);"
|
||||
"vec2 log(vec2 x);"
|
||||
"vec3 log(vec3 x);"
|
||||
"vec4 log(vec4 x);"
|
||||
|
||||
|
||||
"float exp2(float x);"
|
||||
"vec2 exp2(vec2 x);"
|
||||
"vec3 exp2(vec3 x);"
|
||||
"vec4 exp2(vec4 x);"
|
||||
|
||||
|
||||
"float log2(float x);"
|
||||
"vec2 log2(vec2 x);"
|
||||
"vec3 log2(vec3 x);"
|
||||
"vec4 log2(vec4 x);"
|
||||
|
||||
|
||||
"float sqrt(float x);"
|
||||
"vec2 sqrt(vec2 x);"
|
||||
"vec3 sqrt(vec3 x);"
|
||||
"vec4 sqrt(vec4 x);"
|
||||
|
||||
|
||||
"float inversesqrt(float x);"
|
||||
"vec2 inversesqrt(vec2 x);"
|
||||
"vec3 inversesqrt(vec3 x);"
|
||||
"vec4 inversesqrt(vec4 x);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
//
|
||||
@ -255,27 +254,27 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 abs(vec2 x);"
|
||||
"vec3 abs(vec3 x);"
|
||||
"vec4 abs(vec4 x);"
|
||||
|
||||
|
||||
"float sign(float x);"
|
||||
"vec2 sign(vec2 x);"
|
||||
"vec3 sign(vec3 x);"
|
||||
"vec4 sign(vec4 x);"
|
||||
|
||||
|
||||
"float floor(float x);"
|
||||
"vec2 floor(vec2 x);"
|
||||
"vec3 floor(vec3 x);"
|
||||
"vec4 floor(vec4 x);"
|
||||
|
||||
|
||||
"float ceil(float x);"
|
||||
"vec2 ceil(vec2 x);"
|
||||
"vec3 ceil(vec3 x);"
|
||||
"vec4 ceil(vec4 x);"
|
||||
|
||||
|
||||
"float fract(float x);"
|
||||
"vec2 fract(vec2 x);"
|
||||
"vec3 fract(vec3 x);"
|
||||
"vec4 fract(vec4 x);"
|
||||
|
||||
|
||||
"float mod(float x, float y);"
|
||||
"vec2 mod(vec2 x, float y);"
|
||||
"vec3 mod(vec3 x, float y);"
|
||||
@ -283,7 +282,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 mod(vec2 x, vec2 y);"
|
||||
"vec3 mod(vec3 x, vec3 y);"
|
||||
"vec4 mod(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"float min(float x, float y);"
|
||||
"vec2 min(vec2 x, float y);"
|
||||
"vec3 min(vec3 x, float y);"
|
||||
@ -291,7 +290,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 min(vec2 x, vec2 y);"
|
||||
"vec3 min(vec3 x, vec3 y);"
|
||||
"vec4 min(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"float max(float x, float y);"
|
||||
"vec2 max(vec2 x, float y);"
|
||||
"vec3 max(vec3 x, float y);"
|
||||
@ -299,7 +298,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 max(vec2 x, vec2 y);"
|
||||
"vec3 max(vec3 x, vec3 y);"
|
||||
"vec4 max(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"float clamp(float x, float minVal, float maxVal);"
|
||||
"vec2 clamp(vec2 x, float minVal, float maxVal);"
|
||||
"vec3 clamp(vec3 x, float minVal, float maxVal);"
|
||||
@ -307,7 +306,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);"
|
||||
"vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);"
|
||||
"vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);"
|
||||
|
||||
|
||||
"float mix(float x, float y, float a);"
|
||||
"vec2 mix(vec2 x, vec2 y, float a);"
|
||||
"vec3 mix(vec3 x, vec3 y, float a);"
|
||||
@ -323,7 +322,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 step(float edge, vec2 x);"
|
||||
"vec3 step(float edge, vec3 x);"
|
||||
"vec4 step(float edge, vec4 x);"
|
||||
|
||||
|
||||
"float smoothstep(float edge0, float edge1, float x);"
|
||||
"vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);"
|
||||
"vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);"
|
||||
@ -331,7 +330,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 smoothstep(float edge0, float edge1, vec2 x);"
|
||||
"vec3 smoothstep(float edge0, float edge1, vec3 x);"
|
||||
"vec4 smoothstep(float edge0, float edge1, vec4 x);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
if (version >= 130) {
|
||||
@ -350,22 +349,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 trunc(vec2 x);"
|
||||
"vec3 trunc(vec3 x);"
|
||||
"vec4 trunc(vec4 x);"
|
||||
|
||||
|
||||
"float round(float x);"
|
||||
"vec2 round(vec2 x);"
|
||||
"vec3 round(vec3 x);"
|
||||
"vec4 round(vec4 x);"
|
||||
|
||||
|
||||
"float roundEven(float x);"
|
||||
"vec2 roundEven(vec2 x);"
|
||||
"vec3 roundEven(vec3 x);"
|
||||
"vec4 roundEven(vec4 x);"
|
||||
|
||||
|
||||
"float modf(float, out float);"
|
||||
"vec2 modf(vec2, out vec2 );"
|
||||
"vec3 modf(vec3, out vec3 );"
|
||||
"vec4 modf(vec4, out vec4 );"
|
||||
|
||||
|
||||
" int min(int x, int y);"
|
||||
"ivec2 min(ivec2 x, int y);"
|
||||
"ivec3 min(ivec3 x, int y);"
|
||||
@ -373,7 +372,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"ivec2 min(ivec2 x, ivec2 y);"
|
||||
"ivec3 min(ivec3 x, ivec3 y);"
|
||||
"ivec4 min(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
" uint min(uint x, uint y);"
|
||||
"uvec2 min(uvec2 x, uint y);"
|
||||
"uvec3 min(uvec3 x, uint y);"
|
||||
@ -381,7 +380,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"uvec2 min(uvec2 x, uvec2 y);"
|
||||
"uvec3 min(uvec3 x, uvec3 y);"
|
||||
"uvec4 min(uvec4 x, uvec4 y);"
|
||||
|
||||
|
||||
" int max(int x, int y);"
|
||||
"ivec2 max(ivec2 x, int y);"
|
||||
"ivec3 max(ivec3 x, int y);"
|
||||
@ -589,12 +588,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"dvec2 faceforward(dvec2, dvec2, dvec2);"
|
||||
"dvec3 faceforward(dvec3, dvec3, dvec3);"
|
||||
"dvec4 faceforward(dvec4, dvec4, dvec4);"
|
||||
|
||||
|
||||
"double reflect(double, double);"
|
||||
"dvec2 reflect(dvec2 , dvec2 );"
|
||||
"dvec3 reflect(dvec3 , dvec3 );"
|
||||
"dvec4 reflect(dvec4 , dvec4 );"
|
||||
|
||||
|
||||
"double refract(double, double, double);"
|
||||
"dvec2 refract(dvec2 , dvec2 , double);"
|
||||
"dvec3 refract(dvec3 , dvec3 , double);"
|
||||
@ -1079,38 +1078,38 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"float length(vec2 x);"
|
||||
"float length(vec3 x);"
|
||||
"float length(vec4 x);"
|
||||
|
||||
|
||||
"float distance(float p0, float p1);"
|
||||
"float distance(vec2 p0, vec2 p1);"
|
||||
"float distance(vec3 p0, vec3 p1);"
|
||||
"float distance(vec4 p0, vec4 p1);"
|
||||
|
||||
|
||||
"float dot(float x, float y);"
|
||||
"float dot(vec2 x, vec2 y);"
|
||||
"float dot(vec3 x, vec3 y);"
|
||||
"float dot(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"vec3 cross(vec3 x, vec3 y);"
|
||||
"float normalize(float x);"
|
||||
"vec2 normalize(vec2 x);"
|
||||
"vec3 normalize(vec3 x);"
|
||||
"vec4 normalize(vec4 x);"
|
||||
|
||||
|
||||
"float faceforward(float N, float I, float Nref);"
|
||||
"vec2 faceforward(vec2 N, vec2 I, vec2 Nref);"
|
||||
"vec3 faceforward(vec3 N, vec3 I, vec3 Nref);"
|
||||
"vec4 faceforward(vec4 N, vec4 I, vec4 Nref);"
|
||||
|
||||
|
||||
"float reflect(float I, float N);"
|
||||
"vec2 reflect(vec2 I, vec2 N);"
|
||||
"vec3 reflect(vec3 I, vec3 N);"
|
||||
"vec4 reflect(vec4 I, vec4 N);"
|
||||
|
||||
|
||||
"float refract(float I, float N, float eta);"
|
||||
"vec2 refract(vec2 I, vec2 N, float eta);"
|
||||
"vec3 refract(vec3 I, vec3 N, float eta);"
|
||||
"vec4 refract(vec4 I, vec4 N, float eta);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
//
|
||||
@ -1120,7 +1119,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"mat2 matrixCompMult(mat2 x, mat2 y);"
|
||||
"mat3 matrixCompMult(mat3 x, mat3 y);"
|
||||
"mat4 matrixCompMult(mat4 x, mat4 y);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
// 120 is correct for both ES and desktop
|
||||
@ -1135,7 +1134,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"mat4x2 outerProduct(vec2 c, vec4 r);"
|
||||
"mat3x4 outerProduct(vec4 c, vec3 r);"
|
||||
"mat4x3 outerProduct(vec3 c, vec4 r);"
|
||||
|
||||
|
||||
"mat2 transpose(mat2 m);"
|
||||
"mat3 transpose(mat3 m);"
|
||||
"mat4 transpose(mat4 m);"
|
||||
@ -1151,8 +1150,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"mat3x2 matrixCompMult(mat3x2, mat3x2);"
|
||||
"mat3x4 matrixCompMult(mat3x4, mat3x4);"
|
||||
"mat4x2 matrixCompMult(mat4x2, mat4x2);"
|
||||
"mat4x3 matrixCompMult(mat4x3, mat4x3);"
|
||||
|
||||
"mat4x3 matrixCompMult(mat4x3, mat4x3);"
|
||||
|
||||
"\n");
|
||||
|
||||
// 150 is correct for both ES and desktop
|
||||
@ -1161,11 +1160,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"float determinant(mat2 m);"
|
||||
"float determinant(mat3 m);"
|
||||
"float determinant(mat4 m);"
|
||||
|
||||
|
||||
"mat2 inverse(mat2 m);"
|
||||
"mat3 inverse(mat3 m);"
|
||||
"mat4 inverse(mat4 m);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
@ -1177,71 +1176,71 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"bvec2 lessThan(vec2 x, vec2 y);"
|
||||
"bvec3 lessThan(vec3 x, vec3 y);"
|
||||
"bvec4 lessThan(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 lessThan(ivec2 x, ivec2 y);"
|
||||
"bvec3 lessThan(ivec3 x, ivec3 y);"
|
||||
"bvec4 lessThan(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 lessThanEqual(vec2 x, vec2 y);"
|
||||
"bvec3 lessThanEqual(vec3 x, vec3 y);"
|
||||
"bvec4 lessThanEqual(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 lessThanEqual(ivec2 x, ivec2 y);"
|
||||
"bvec3 lessThanEqual(ivec3 x, ivec3 y);"
|
||||
"bvec4 lessThanEqual(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThan(vec2 x, vec2 y);"
|
||||
"bvec3 greaterThan(vec3 x, vec3 y);"
|
||||
"bvec4 greaterThan(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThan(ivec2 x, ivec2 y);"
|
||||
"bvec3 greaterThan(ivec3 x, ivec3 y);"
|
||||
"bvec4 greaterThan(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThanEqual(vec2 x, vec2 y);"
|
||||
"bvec3 greaterThanEqual(vec3 x, vec3 y);"
|
||||
"bvec4 greaterThanEqual(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThanEqual(ivec2 x, ivec2 y);"
|
||||
"bvec3 greaterThanEqual(ivec3 x, ivec3 y);"
|
||||
"bvec4 greaterThanEqual(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 equal(vec2 x, vec2 y);"
|
||||
"bvec3 equal(vec3 x, vec3 y);"
|
||||
"bvec4 equal(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 equal(ivec2 x, ivec2 y);"
|
||||
"bvec3 equal(ivec3 x, ivec3 y);"
|
||||
"bvec4 equal(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 equal(bvec2 x, bvec2 y);"
|
||||
"bvec3 equal(bvec3 x, bvec3 y);"
|
||||
"bvec4 equal(bvec4 x, bvec4 y);"
|
||||
|
||||
|
||||
"bvec2 notEqual(vec2 x, vec2 y);"
|
||||
"bvec3 notEqual(vec3 x, vec3 y);"
|
||||
"bvec4 notEqual(vec4 x, vec4 y);"
|
||||
|
||||
|
||||
"bvec2 notEqual(ivec2 x, ivec2 y);"
|
||||
"bvec3 notEqual(ivec3 x, ivec3 y);"
|
||||
"bvec4 notEqual(ivec4 x, ivec4 y);"
|
||||
|
||||
|
||||
"bvec2 notEqual(bvec2 x, bvec2 y);"
|
||||
"bvec3 notEqual(bvec3 x, bvec3 y);"
|
||||
"bvec4 notEqual(bvec4 x, bvec4 y);"
|
||||
|
||||
|
||||
"bool any(bvec2 x);"
|
||||
"bool any(bvec3 x);"
|
||||
"bool any(bvec4 x);"
|
||||
|
||||
|
||||
"bool all(bvec2 x);"
|
||||
"bool all(bvec3 x);"
|
||||
"bool all(bvec4 x);"
|
||||
|
||||
|
||||
"bvec2 not(bvec2 x);"
|
||||
"bvec3 not(bvec3 x);"
|
||||
"bvec4 not(bvec4 x);"
|
||||
|
||||
|
||||
"\n");
|
||||
|
||||
if (version >= 130) {
|
||||
@ -1249,27 +1248,27 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"bvec2 lessThan(uvec2 x, uvec2 y);"
|
||||
"bvec3 lessThan(uvec3 x, uvec3 y);"
|
||||
"bvec4 lessThan(uvec4 x, uvec4 y);"
|
||||
|
||||
|
||||
"bvec2 lessThanEqual(uvec2 x, uvec2 y);"
|
||||
"bvec3 lessThanEqual(uvec3 x, uvec3 y);"
|
||||
"bvec4 lessThanEqual(uvec4 x, uvec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThan(uvec2 x, uvec2 y);"
|
||||
"bvec3 greaterThan(uvec3 x, uvec3 y);"
|
||||
"bvec4 greaterThan(uvec4 x, uvec4 y);"
|
||||
|
||||
|
||||
"bvec2 greaterThanEqual(uvec2 x, uvec2 y);"
|
||||
"bvec3 greaterThanEqual(uvec3 x, uvec3 y);"
|
||||
"bvec4 greaterThanEqual(uvec4 x, uvec4 y);"
|
||||
|
||||
|
||||
"bvec2 equal(uvec2 x, uvec2 y);"
|
||||
"bvec3 equal(uvec3 x, uvec3 y);"
|
||||
"bvec4 equal(uvec4 x, uvec4 y);"
|
||||
|
||||
"bvec2 notEqual(uvec2 x, uvec2 y);"
|
||||
"bvec3 notEqual(uvec3 x, uvec3 y);"
|
||||
"bvec4 notEqual(uvec4 x, uvec4 y);"
|
||||
|
||||
"bvec4 notEqual(uvec4 x, uvec4 y);"
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -1292,7 +1291,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec4 texture3DProj(sampler3D, vec4);" // OES_texture_3D, but caught by keyword check
|
||||
|
||||
"vec4 textureCube(samplerCube, vec3);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
@ -1306,7 +1305,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
|
||||
"vec4 texture1DProj(sampler1D, vec2);"
|
||||
"vec4 texture1DProj(sampler1D, vec4);"
|
||||
|
||||
|
||||
"vec4 shadow1D(sampler1DShadow, vec3);"
|
||||
"vec4 shadow2D(sampler2DShadow, vec3);"
|
||||
"vec4 shadow1DProj(sampler1DShadow, vec4);"
|
||||
@ -1346,22 +1345,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"float noise1(vec2 x);"
|
||||
"float noise1(vec3 x);"
|
||||
"float noise1(vec4 x);"
|
||||
|
||||
|
||||
"vec2 noise2(float x);"
|
||||
"vec2 noise2(vec2 x);"
|
||||
"vec2 noise2(vec3 x);"
|
||||
"vec2 noise2(vec4 x);"
|
||||
|
||||
|
||||
"vec3 noise3(float x);"
|
||||
"vec3 noise3(vec2 x);"
|
||||
"vec3 noise3(vec3 x);"
|
||||
"vec3 noise3(vec4 x);"
|
||||
|
||||
|
||||
"vec4 noise4(float x);"
|
||||
"vec4 noise4(vec2 x);"
|
||||
"vec4 noise4(vec3 x);"
|
||||
"vec4 noise4(vec4 x);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -1517,7 +1516,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"lowp ivec2 findMSB(highp uvec2);"
|
||||
"lowp ivec3 findMSB(highp uvec3);"
|
||||
"lowp ivec4 findMSB(highp uvec4);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -2243,7 +2242,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 dFdx(vec2 p);"
|
||||
"vec3 dFdx(vec3 p);"
|
||||
"vec4 dFdx(vec4 p);"
|
||||
|
||||
|
||||
"float dFdy(float p);"
|
||||
"vec2 dFdy(vec2 p);"
|
||||
"vec3 dFdy(vec3 p);"
|
||||
@ -2286,12 +2285,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec2 dFdyCoarse(vec2 p);"
|
||||
"vec3 dFdyCoarse(vec3 p);"
|
||||
"vec4 dFdyCoarse(vec4 p);"
|
||||
|
||||
|
||||
"float fwidthCoarse(float p);"
|
||||
"vec2 fwidthCoarse(vec2 p);"
|
||||
"vec3 fwidthCoarse(vec3 p);"
|
||||
"vec4 fwidthCoarse(vec4 p);"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -2462,11 +2461,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"uniform mat4 gl_ModelViewMatrixInverse;"
|
||||
"uniform mat4 gl_ProjectionMatrixInverse;"
|
||||
"uniform mat4 gl_ModelViewProjectionMatrixInverse;"
|
||||
|
||||
|
||||
"uniform mat4 gl_ModelViewMatrixTranspose;"
|
||||
"uniform mat4 gl_ProjectionMatrixTranspose;"
|
||||
"uniform mat4 gl_ModelViewProjectionMatrixTranspose;"
|
||||
|
||||
|
||||
"uniform mat4 gl_ModelViewMatrixInverseTranspose;"
|
||||
"uniform mat4 gl_ProjectionMatrixInverseTranspose;"
|
||||
"uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;"
|
||||
@ -2524,7 +2523,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"float quadraticAttenuation;"// K2
|
||||
"};"
|
||||
|
||||
|
||||
"struct gl_LightModelParameters {"
|
||||
"vec4 ambient;" // Acs
|
||||
"};"
|
||||
@ -2559,7 +2557,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"};"
|
||||
|
||||
"uniform gl_FogParameters gl_Fog;"
|
||||
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -2589,7 +2587,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
// Define the interface to the vertex shader.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
||||
if (profile != EEsProfile) {
|
||||
if (version < 130) {
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
@ -2621,7 +2619,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"in vec4 gl_MultiTexCoord5;"
|
||||
"in vec4 gl_MultiTexCoord6;"
|
||||
"in vec4 gl_MultiTexCoord7;"
|
||||
"in float gl_FogCoord;"
|
||||
"in float gl_FogCoord;"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -2663,7 +2661,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
"vec4 gl_Position;" // needs qualifier fixed later
|
||||
"float gl_PointSize;" // needs qualifier fixed later
|
||||
"float gl_ClipDistance[];"
|
||||
);
|
||||
);
|
||||
if (IncludeLegacy(version, profile, spvVersion))
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
"vec4 gl_ClipVertex;" // needs qualifier fixed later
|
||||
@ -2827,7 +2825,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Define the interface to the tessellation control shader.
|
||||
@ -2907,7 +2904,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
|
||||
"patch in float gl_TessLevelOuter[4];"
|
||||
"patch in float gl_TessLevelInner[2];"
|
||||
|
||||
|
||||
"out gl_PerVertex {"
|
||||
"vec4 gl_Position;"
|
||||
"float gl_PointSize;"
|
||||
@ -2941,7 +2938,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
|
||||
"patch in highp float gl_TessLevelOuter[4];"
|
||||
"patch in highp float gl_TessLevelInner[2];"
|
||||
|
||||
|
||||
"out gl_PerVertex {"
|
||||
"highp vec4 gl_Position;"
|
||||
"highp float gl_PointSize;"
|
||||
@ -3113,7 +3110,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function for initialize(), to add the second set of names for texturing,
|
||||
// Helper function for initialize(), to add the second set of names for texturing,
|
||||
// when adding context-independent built-in functions.
|
||||
//
|
||||
void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion)
|
||||
@ -3221,7 +3218,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// when adding context-independent built-in functions.
|
||||
//
|
||||
// Add all the query functions for the given type.
|
||||
@ -3298,7 +3295,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// when adding context-independent built-in functions.
|
||||
//
|
||||
// Add all the image access functions for the given type.
|
||||
@ -3357,7 +3354,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
|
||||
" imageAtomicOr(volatile coherent ",
|
||||
" imageAtomicXor(volatile coherent ",
|
||||
" imageAtomicExchange(volatile coherent "
|
||||
};
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < numBuiltins; ++i) {
|
||||
commonBuiltins.append(dataType);
|
||||
@ -3408,7 +3405,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, TString& typeName, int /*ve
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// when adding context-independent built-in functions.
|
||||
//
|
||||
// Add all the texture lookup functions for the given type.
|
||||
@ -3637,9 +3634,8 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int ve
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// Helper function for add2ndGenerationSamplingImaging(),
|
||||
// when adding context-independent built-in functions.
|
||||
//
|
||||
// Add all the texture gather functions for the given type.
|
||||
@ -3840,7 +3836,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents);
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents);
|
||||
@ -3849,7 +3845,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
@ -4012,7 +4008,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents);
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents);
|
||||
@ -4021,7 +4017,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents);
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel);
|
||||
@ -4086,7 +4082,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
}
|
||||
|
||||
// images (some in compute below)
|
||||
if ((profile == EEsProfile && version >= 310) ||
|
||||
if ((profile == EEsProfile && version >= 310) ||
|
||||
(profile != EEsProfile && version >= 130)) {
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
|
||||
s.append(builtInConstant);
|
||||
@ -4101,7 +4097,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
}
|
||||
|
||||
// atomic counters (some in compute below)
|
||||
if ((profile == EEsProfile && version >= 310) ||
|
||||
if ((profile == EEsProfile && version >= 310) ||
|
||||
(profile != EEsProfile && version >= 420)) {
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources. maxVertexAtomicCounters);
|
||||
s.append(builtInConstant);
|
||||
@ -4137,12 +4133,11 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
||||
s.append("\n");
|
||||
}
|
||||
|
||||
|
||||
// compute
|
||||
if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) {
|
||||
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX,
|
||||
resources.maxComputeWorkGroupCountY,
|
||||
resources.maxComputeWorkGroupCountZ);
|
||||
resources.maxComputeWorkGroupCountZ);
|
||||
s.append(builtInConstant);
|
||||
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX,
|
||||
resources.maxComputeWorkGroupSizeY,
|
||||
@ -4272,7 +4267,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
// N.B.: a symbol should only be tagged once, and this function is called multiple times, once
|
||||
// per stage that's used for this profile. So
|
||||
// - generally, stick common ones in the fragment stage to ensure they are tagged exactly once
|
||||
// - for ES, which has different precisions for different stages, the coarsest-grained tagging
|
||||
// - for ES, which has different precisions for different stages, the coarsest-grained tagging
|
||||
// for a built-in used in many stages needs to be once for the fragment stage and once for
|
||||
// the vertex stage
|
||||
|
||||
@ -4501,7 +4496,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BuiltInVariable("gl_Layer", EbvLayer, symbolTable);
|
||||
BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable);
|
||||
|
||||
@ -5062,7 +5057,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
|
||||
//
|
||||
// Add context-dependent (resource-specific) built-ins not handled by the above. These
|
||||
// would be ones that need to be programmatically added because they cannot
|
||||
// would be ones that need to be programmatically added because they cannot
|
||||
// be added by simple text strings. For these, also
|
||||
// 1) Map built-in functions to operators, for those that will turn into an operation node
|
||||
// instead of remaining a function call.
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; }
|
||||
|
||||
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0;
|
||||
|
||||
|
||||
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0;
|
||||
|
||||
protected:
|
||||
@ -89,7 +89,7 @@ public:
|
||||
void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage);
|
||||
|
||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
|
||||
|
||||
|
||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
||||
|
||||
protected:
|
||||
@ -107,7 +107,6 @@ protected:
|
||||
int dimMap[EsdNumDims];
|
||||
};
|
||||
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _INITIALIZE_INCLUDED_
|
||||
|
@ -155,7 +155,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
||||
return folded;
|
||||
}
|
||||
|
||||
// If either is a specialization constant, while the other is
|
||||
// If either is a specialization constant, while the other is
|
||||
// a constant (or specialization constant), the result is still
|
||||
// a specialization constant, if the operation is an allowed
|
||||
// specialization-constant operation.
|
||||
@ -192,7 +192,7 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI
|
||||
node->setType(type);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Low level: add unary node (no promotions or other argument modifications)
|
||||
//
|
||||
@ -286,7 +286,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
|
||||
if (source == EShSourceHlsl) {
|
||||
break; // HLSL can promote logical not
|
||||
}
|
||||
|
||||
|
||||
if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -474,7 +474,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||
|
||||
// samplers can get assigned via a sampler constructor
|
||||
// (well, not yet, but code in the rest of this function is ready for it)
|
||||
if (node->getBasicType() == EbtSampler && op == EOpAssign &&
|
||||
if (node->getBasicType() == EbtSampler && op == EOpAssign &&
|
||||
node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
|
||||
break;
|
||||
|
||||
@ -867,16 +867,16 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||
if (fromConvertable && toConvertable) {
|
||||
switch (op) {
|
||||
case EOpAndAssign: // assignments can perform arbitrary conversions
|
||||
case EOpInclusiveOrAssign: // ...
|
||||
case EOpExclusiveOrAssign: // ...
|
||||
case EOpAssign: // ...
|
||||
case EOpAddAssign: // ...
|
||||
case EOpSubAssign: // ...
|
||||
case EOpMulAssign: // ...
|
||||
case EOpVectorTimesScalarAssign: // ...
|
||||
case EOpMatrixTimesScalarAssign: // ...
|
||||
case EOpDivAssign: // ...
|
||||
case EOpModAssign: // ...
|
||||
case EOpInclusiveOrAssign: // ...
|
||||
case EOpExclusiveOrAssign: // ...
|
||||
case EOpAssign: // ...
|
||||
case EOpAddAssign: // ...
|
||||
case EOpSubAssign: // ...
|
||||
case EOpMulAssign: // ...
|
||||
case EOpVectorTimesScalarAssign: // ...
|
||||
case EOpMatrixTimesScalarAssign: // ...
|
||||
case EOpDivAssign: // ...
|
||||
case EOpModAssign: // ...
|
||||
case EOpReturn: // function returns can also perform arbitrary conversions
|
||||
case EOpFunctionCall: // conversion of a calling parameter
|
||||
case EOpLogicalNot:
|
||||
@ -1245,7 +1245,6 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
|
||||
{
|
||||
// However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
|
||||
@ -2304,7 +2303,6 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TIntermBinary::updatePrecision()
|
||||
{
|
||||
#ifdef AMD_EXTENSIONS
|
||||
|
@ -240,7 +240,7 @@ void TParseContextBase::trackLinkageDeferred(TSymbol& symbol)
|
||||
linkageSymbols.push_back(&symbol);
|
||||
}
|
||||
|
||||
// Make a shared symbol have a non-shared version that can be edited by the current
|
||||
// Make a shared symbol have a non-shared version that can be edited by the current
|
||||
// compile, such that editing its type will not change the shared version and will
|
||||
// effect all nodes already sharing it (non-shallow type),
|
||||
// or adopting its full type after being edited (shallow type).
|
||||
@ -308,20 +308,20 @@ const TFunction* TParseContextBase::selectFunction(
|
||||
std::function<bool(const TType& from, const TType& to1, const TType& to2)> better,
|
||||
/* output */ bool& tie)
|
||||
{
|
||||
//
|
||||
//
|
||||
// Operation
|
||||
//
|
||||
//
|
||||
// 1. Prune the input list of candidates down to a list of viable candidates,
|
||||
// where each viable candidate has
|
||||
//
|
||||
//
|
||||
// * at least as many parameters as there are calling arguments, with any
|
||||
// remaining parameters being optional or having default values
|
||||
// * each parameter is true under convertible(A, B), where A is the calling
|
||||
// type for in and B is the formal type, and in addition, for out B is the
|
||||
// calling type and A is the formal type
|
||||
//
|
||||
//
|
||||
// 2. If there are no viable candidates, return with no match.
|
||||
//
|
||||
//
|
||||
// 3. If there is only one viable candidate, it is the best match.
|
||||
//
|
||||
// 4. If there are multiple viable candidates, select the first viable candidate
|
||||
@ -329,7 +329,7 @@ const TFunction* TParseContextBase::selectFunction(
|
||||
// that candidate is better (bullets below), make it the incumbent. Repeat, with
|
||||
// a linear walk through the viable candidate list. The final incumbent will be
|
||||
// returned as the best match. A viable candidate is better than the incumbent if
|
||||
//
|
||||
//
|
||||
// * it has a function argument with a better(...) conversion than the incumbent,
|
||||
// for all directions needed by in and out
|
||||
// * the incumbent has no argument with a better(...) conversion then the
|
||||
@ -408,7 +408,7 @@ const TFunction* TParseContextBase::selectFunction(
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
const TFunction* incumbent = viableCandidates.front();
|
||||
for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
|
||||
const TFunction& candidate = *(*it);
|
||||
@ -421,7 +421,7 @@ const TFunction* TParseContextBase::selectFunction(
|
||||
if (incumbent == *it)
|
||||
continue;
|
||||
const TFunction& candidate = *(*it);
|
||||
|
||||
|
||||
// In the case of default parameters, it may have an identical initial set, which is
|
||||
// also ambiguous
|
||||
if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
|
||||
|
@ -50,7 +50,7 @@ namespace glslang {
|
||||
TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins,
|
||||
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
|
||||
inMain(false), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
|
||||
limits(resources.limits),
|
||||
@ -76,7 +76,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
|
||||
globalInputDefaults.clear();
|
||||
globalOutputDefaults.clear();
|
||||
|
||||
// "Shaders in the transform
|
||||
// "Shaders in the transform
|
||||
// feedback capturing mode have an initial global default of
|
||||
// layout(xfb_buffer = 0) out;"
|
||||
if (language == EShLangVertex ||
|
||||
@ -370,12 +370,12 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
|
||||
requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
|
||||
|
||||
if (symbol && symbol->isReadOnly()) {
|
||||
// All shared things containing an implicitly sized array must be copied up
|
||||
// All shared things containing an implicitly sized array must be copied up
|
||||
// on first use, so that all future references will share its array structure,
|
||||
// so that editing the implicit size will effect all nodes consuming it,
|
||||
// and so that editing the implicit size won't change the shared one.
|
||||
//
|
||||
// If this is a variable or a block, check it and all it contains, but if this
|
||||
// If this is a variable or a block, check it and all it contains, but if this
|
||||
// is a member of an anonymous block, check the whole block, as the whole block
|
||||
// will need to be copied up if it contains an implicitly-sized array.
|
||||
if (symbol->getType().containsImplicitlySizedArray() ||
|
||||
@ -537,7 +537,7 @@ void TParseContext::checkIndex(const TSourceLoc& loc, const TType& type, int& in
|
||||
error(loc, "", "[", "matrix index out of range '%d'", index);
|
||||
index = type.getMatrixCols() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
|
||||
@ -558,7 +558,7 @@ void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* b
|
||||
}
|
||||
}
|
||||
|
||||
// Make a shared symbol have a non-shared version that can be edited by the current
|
||||
// Make a shared symbol have a non-shared version that can be edited by the current
|
||||
// compile, such that editing its type will not change the shared version and will
|
||||
// effect all nodes sharing it.
|
||||
void TParseContext::makeEditable(TSymbol*& symbol)
|
||||
@ -600,7 +600,7 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
|
||||
|
||||
// Issue any errors if the non-array object is missing arrayness WRT
|
||||
// shader I/O that has array requirements.
|
||||
// All arrayness checking is handled in array paths, this is for
|
||||
// All arrayness checking is handled in array paths, this is for
|
||||
void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
|
||||
{
|
||||
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
|
||||
@ -633,7 +633,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
|
||||
|
||||
// If there has been an input primitive declaration (geometry shader) or an output
|
||||
// number of vertices declaration(tessellation shader), make sure all input array types
|
||||
// match it in size. Types come either from nodes in the AST or symbols in the
|
||||
// match it in size. Types come either from nodes in the AST or symbols in the
|
||||
// symbol table.
|
||||
//
|
||||
// Types without an array size will be given one.
|
||||
@ -729,7 +729,7 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
|
||||
return result;
|
||||
else
|
||||
unaryOpError(loc, str, childNode->getCompleteString());
|
||||
|
||||
|
||||
return childNode;
|
||||
}
|
||||
|
||||
@ -742,7 +742,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
||||
|
||||
//
|
||||
// .length() can't be resolved until we later see the function-calling syntax.
|
||||
// Save away the name in the AST for now. Processing is completed in
|
||||
// Save away the name in the AST for now. Processing is completed in
|
||||
// handleLengthMethod().
|
||||
//
|
||||
if (field == "length") {
|
||||
@ -906,7 +906,7 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct
|
||||
if (symbolTable.atBuiltInLevel())
|
||||
function.setDefined();
|
||||
else {
|
||||
if (prevDec && ! builtIn)
|
||||
if (prevDec && ! builtIn)
|
||||
symbol->getAsFunction()->setPrototyped(); // need a writable one, but like having prevDec as a const
|
||||
function.setPrototyped();
|
||||
}
|
||||
@ -926,7 +926,7 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing the function prototype in front of a function definition in the grammar.
|
||||
// Handle seeing the function prototype in front of a function definition in the grammar.
|
||||
// The body is handled after this function returns.
|
||||
//
|
||||
TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function)
|
||||
@ -1087,10 +1087,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
||||
if (argQualifier.writeonly && ! formalQualifier.writeonly)
|
||||
error(arguments->getLoc(), message, "writeonly", "");
|
||||
}
|
||||
// TODO 4.5 functionality: A shader will fail to compile
|
||||
// TODO 4.5 functionality: A shader will fail to compile
|
||||
// if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
|
||||
// shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
|
||||
// memargument of an atomic memory function, as long as the underlying array or vector is a buffer or
|
||||
// shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
|
||||
// memargument of an atomic memory function, as long as the underlying array or vector is a buffer or
|
||||
// shared variable.
|
||||
}
|
||||
|
||||
@ -1213,7 +1213,7 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction
|
||||
operationPrecision = std::max(function[0].type->getQualifier().precision,
|
||||
unaryNode->getOperand()->getType().getQualifier().precision);
|
||||
if (function.getType().getBasicType() != EbtBool)
|
||||
resultPrecision = function.getType().getQualifier().precision == EpqNone ?
|
||||
resultPrecision = function.getType().getQualifier().precision == EpqNone ?
|
||||
operationPrecision :
|
||||
function.getType().getQualifier().precision;
|
||||
} else if (TIntermAggregate* agg = node.getAsAggregate()) {
|
||||
@ -1243,7 +1243,7 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction
|
||||
if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore)
|
||||
resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision;
|
||||
else if (function.getType().getBasicType() != EbtBool)
|
||||
resultPrecision = function.getType().getQualifier().precision == EpqNone ?
|
||||
resultPrecision = function.getType().getQualifier().precision == EpqNone ?
|
||||
operationPrecision :
|
||||
function.getType().getQualifier().precision;
|
||||
}
|
||||
@ -1301,7 +1301,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
|
||||
}
|
||||
|
||||
// Finish processing object.length(). This started earlier in handleDotDereference(), where
|
||||
// the ".length" part was recognized and semantically checked, and finished here where the
|
||||
// the ".length" part was recognized and semantically checked, and finished here where the
|
||||
// function syntax "()" is recognized.
|
||||
//
|
||||
// Return resulting tree node.
|
||||
@ -1319,8 +1319,8 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
|
||||
return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
|
||||
} else if (type.isImplicitlySizedArray()) {
|
||||
if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
|
||||
// We could be between a layout declaration that gives a built-in io array implicit size and
|
||||
// a user redeclaration of that array, meaning we have to substitute its implicit size here
|
||||
// We could be between a layout declaration that gives a built-in io array implicit size and
|
||||
// a user redeclaration of that array, meaning we have to substitute its implicit size here
|
||||
// without actually redeclaring the array. (It is an error to use a member before the
|
||||
// redeclaration, but not an error to use the array name itself.)
|
||||
const TString& name = intermNode->getAsSymbolNode()->getName();
|
||||
@ -1604,7 +1604,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
||||
if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui)
|
||||
error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
|
||||
} else {
|
||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
|
||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
|
||||
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
|
||||
else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile)
|
||||
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
||||
@ -1654,7 +1654,7 @@ extern bool PureOperatorBuiltins;
|
||||
//
|
||||
void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
|
||||
{
|
||||
// Further maintenance of this function is deprecated, because the "correct"
|
||||
// Further maintenance of this function is deprecated, because the "correct"
|
||||
// future-oriented design is to not have to do string compares on function names.
|
||||
|
||||
// If PureOperatorBuiltins == true, then all built-ins should be mapped
|
||||
@ -1759,7 +1759,7 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn
|
||||
if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui)
|
||||
error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
|
||||
} else {
|
||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
|
||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
|
||||
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
|
||||
else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile)
|
||||
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
||||
@ -2412,8 +2412,8 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const
|
||||
// of the texture type must match that of the constructed sampler type
|
||||
// (that is, the suffixes of the type of the first argument and the
|
||||
// type of the constructor will be spelled the same way)
|
||||
if (function[0].type->getBasicType() != EbtSampler ||
|
||||
! function[0].type->getSampler().isTexture() ||
|
||||
if (function[0].type->getBasicType() != EbtSampler ||
|
||||
! function[0].type->getSampler().isTexture() ||
|
||||
function[0].type->isArray()) {
|
||||
error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, "");
|
||||
return true;
|
||||
@ -2720,7 +2720,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
||||
#endif
|
||||
|
||||
// Ordering
|
||||
if (! force && ((profile != EEsProfile && version < 420) ||
|
||||
if (! force && ((profile != EEsProfile && version < 420) ||
|
||||
(profile == EEsProfile && version < 310))
|
||||
&& ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) {
|
||||
// non-function parameters
|
||||
@ -3330,7 +3330,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||
// Now, modify the type of the copy, as per the type of the current redeclaration.
|
||||
|
||||
TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
|
||||
if (ssoPre150) {
|
||||
if (ssoPre150) {
|
||||
if (intermediate.inIoAccessed(identifier))
|
||||
error(loc, "cannot redeclare after use", identifier.c_str(), "");
|
||||
if (qualifier.hasLayout())
|
||||
@ -3368,7 +3368,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
||||
if (qualifier.storage != EvqVaryingIn)
|
||||
error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
|
||||
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
|
||||
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
|
||||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
|
||||
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
|
||||
if (publicType.pixelCenterInteger)
|
||||
@ -3388,7 +3388,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
|
||||
}
|
||||
}
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
else if (identifier == "gl_SampleMask") {
|
||||
if (!publicType.layoutOverrideCoverage) {
|
||||
error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
|
||||
@ -3526,7 +3526,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
|
||||
|
||||
// go to next member
|
||||
++member;
|
||||
} else {
|
||||
} else {
|
||||
// For missing members of anonymous blocks that have been redeclared,
|
||||
// hide the original (shared) declaration.
|
||||
// Instance-named blocks can just have the member removed.
|
||||
@ -3659,7 +3659,7 @@ void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publ
|
||||
|
||||
// fix and check for member storage qualifiers and types that don't belong within a structure
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||
const TSourceLoc& memberLoc = typeList[member].loc;
|
||||
if (memberQualifier.isAuxiliary() ||
|
||||
memberQualifier.isInterpolation() ||
|
||||
@ -3833,7 +3833,7 @@ void TParseContext::finish()
|
||||
// Check for stages that are enabled by extension.
|
||||
// Can't do this at the beginning, it is chicken and egg to add a stage by
|
||||
// extension.
|
||||
// Stage-specific features were correctly tested for already, this is just
|
||||
// Stage-specific features were correctly tested for already, this is just
|
||||
// about the stage itself.
|
||||
switch (language) {
|
||||
case EShLangGeometry:
|
||||
@ -4041,7 +4041,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
error(loc, "unknown blend equation", "blend_support", "");
|
||||
return;
|
||||
}
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (id == "override_coverage") {
|
||||
requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
|
||||
publicType.shaderQualifiers.layoutOverrideCoverage = true;
|
||||
@ -4079,7 +4079,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
}
|
||||
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
|
||||
|
||||
if (id == "offset") {
|
||||
// "offset" can be for either
|
||||
// - uniform offsets
|
||||
@ -4135,9 +4135,9 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
publicType.qualifier.layoutComponent = value;
|
||||
return;
|
||||
} else if (id.compare(0, 4, "xfb_") == 0) {
|
||||
// "Any shader making any static use (after preprocessing) of any of these
|
||||
// *xfb_* qualifiers will cause the shader to be in a transform feedback
|
||||
// capturing mode and hence responsible for describing the transform feedback
|
||||
// "Any shader making any static use (after preprocessing) of any of these
|
||||
// *xfb_* qualifiers will cause the shader to be in a transform feedback
|
||||
// capturing mode and hence responsible for describing the transform feedback
|
||||
// setup."
|
||||
intermediate.setXfbMode();
|
||||
const char* feature = "transform feedback qualifier";
|
||||
@ -4148,7 +4148,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
// "It is a compile-time error to specify an *xfb_buffer* that is greater than
|
||||
// the implementation-dependent constant gl_MaxTransformFeedbackBuffers."
|
||||
if (value >= resources.maxTransformFeedbackBuffers)
|
||||
error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);
|
||||
error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);
|
||||
if (value >= (int)TQualifier::layoutXfbBufferEnd)
|
||||
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
|
||||
else
|
||||
@ -4161,7 +4161,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
publicType.qualifier.layoutXfbOffset = value;
|
||||
return;
|
||||
} else if (id == "xfb_stride") {
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
||||
if (value > 4 * resources.maxTransformFeedbackInterleavedComponents)
|
||||
error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents);
|
||||
@ -4295,17 +4295,17 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone
|
||||
//
|
||||
// "More than one layout qualifier may appear in a single declaration.
|
||||
// Additionally, the same layout-qualifier-name can occur multiple times
|
||||
// within a layout qualifier or across multiple layout qualifiers in the
|
||||
// same declaration. When the same layout-qualifier-name occurs
|
||||
// multiple times, in a single declaration, the last occurrence overrides
|
||||
// the former occurrence(s). Further, if such a layout-qualifier-name
|
||||
// will effect subsequent declarations or other observable behavior, it
|
||||
// is only the last occurrence that will have any effect, behaving as if
|
||||
// the earlier occurrence(s) within the declaration are not present.
|
||||
// This is also true for overriding layout-qualifier-names, where one
|
||||
// overrides the other (e.g., row_major vs. column_major); only the last
|
||||
// occurrence has any effect."
|
||||
// Additionally, the same layout-qualifier-name can occur multiple times
|
||||
// within a layout qualifier or across multiple layout qualifiers in the
|
||||
// same declaration. When the same layout-qualifier-name occurs
|
||||
// multiple times, in a single declaration, the last occurrence overrides
|
||||
// the former occurrence(s). Further, if such a layout-qualifier-name
|
||||
// will effect subsequent declarations or other observable behavior, it
|
||||
// is only the last occurrence that will have any effect, behaving as if
|
||||
// the earlier occurrence(s) within the declaration are not present.
|
||||
// This is also true for overriding layout-qualifier-names, where one
|
||||
// overrides the other (e.g., row_major vs. column_major); only the last
|
||||
// occurrence has any effect."
|
||||
//
|
||||
void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
|
||||
{
|
||||
@ -4384,7 +4384,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
||||
}
|
||||
}
|
||||
|
||||
// Check packing and matrix
|
||||
// Check packing and matrix
|
||||
if (qualifier.hasUniformLayout()) {
|
||||
switch (qualifier.storage) {
|
||||
case EvqUniform:
|
||||
@ -4472,8 +4472,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
if (repeated >= 0)
|
||||
error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
|
||||
|
||||
// "The offset must be a multiple of the size of the first component of the first
|
||||
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
|
||||
// "The offset must be a multiple of the size of the first component of the first
|
||||
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
|
||||
// containing a double, the offset must also be a multiple of 8..."
|
||||
if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
|
||||
error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", "");
|
||||
@ -4547,7 +4547,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
|
||||
|
||||
if (profile == EEsProfile) {
|
||||
// "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
|
||||
// "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
|
||||
// specify either memory qualifier readonly or the memory qualifier writeonly."
|
||||
if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) {
|
||||
if (! qualifier.readonly && ! qualifier.writeonly)
|
||||
@ -4609,8 +4609,8 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
|
||||
|
||||
if (qualifier.hasAnyLocation()) {
|
||||
|
||||
// "As with input layout qualifiers, all shaders except compute shaders
|
||||
// allow *location* layout qualifiers on output variable declarations,
|
||||
// "As with input layout qualifiers, all shaders except compute shaders
|
||||
// allow *location* layout qualifiers on output variable declarations,
|
||||
// output block declarations, and output block member declarations."
|
||||
|
||||
switch (qualifier.storage) {
|
||||
@ -4921,7 +4921,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
|
||||
// create list of candidates to send
|
||||
TVector<const TFunction*> candidateList;
|
||||
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
||||
|
||||
|
||||
// can 'from' convert to 'to'?
|
||||
const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool {
|
||||
if (from == to)
|
||||
@ -4953,7 +4953,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
|
||||
|
||||
// for ambiguity reporting
|
||||
bool tie = false;
|
||||
|
||||
|
||||
// send to the generic selector
|
||||
const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
|
||||
|
||||
@ -4965,7 +4965,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
// When a declaration includes a type, but not a variable name, it can be
|
||||
// When a declaration includes a type, but not a variable name, it can be
|
||||
// to establish defaults.
|
||||
void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
|
||||
{
|
||||
@ -5029,7 +5029,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
||||
|
||||
// Declare the variable
|
||||
if (arraySizes || type.isArray()) {
|
||||
// Arrayness is potentially coming both from the type and from the
|
||||
// Arrayness is potentially coming both from the type and from the
|
||||
// variable: "int[] a[];" or just one or the other.
|
||||
// Merge it all to the type, so all arrayness is part of the type.
|
||||
arrayDimCheck(loc, &type, arraySizes);
|
||||
@ -5667,9 +5667,9 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
||||
error(memberLoc, "member cannot contradict block", "stream", "");
|
||||
}
|
||||
|
||||
// "This includes a block's inheritance of the
|
||||
// current global default buffer, a block member's inheritance of the block's
|
||||
// buffer, and the requirement that any *xfb_buffer* declared on a block
|
||||
// "This includes a block's inheritance of the
|
||||
// current global default buffer, a block member's inheritance of the block's
|
||||
// buffer, and the requirement that any *xfb_buffer* declared on a block
|
||||
// member must match the buffer inherited from the block."
|
||||
if (memberQualifier.hasXfbBuffer()) {
|
||||
if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
|
||||
@ -5854,15 +5854,15 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
|
||||
}
|
||||
|
||||
//
|
||||
// "For a block, this process applies to the entire block, or until the first member
|
||||
// is reached that has a location layout qualifier. When a block member is declared with a location
|
||||
// "For a block, this process applies to the entire block, or until the first member
|
||||
// is reached that has a location layout qualifier. When a block member is declared with a location
|
||||
// qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
|
||||
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
|
||||
// until the next member declared with a location qualifier. The values used for locations do not have to be
|
||||
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
|
||||
// until the next member declared with a location qualifier. The values used for locations do not have to be
|
||||
// declared in increasing order."
|
||||
void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
|
||||
{
|
||||
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members
|
||||
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members
|
||||
// have a location layout qualifier, or a compile-time error results."
|
||||
if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
|
||||
error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
|
||||
@ -5898,9 +5898,9 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi
|
||||
|
||||
void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
{
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
// members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
// members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
|
||||
// offsets."
|
||||
|
||||
if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
|
||||
@ -5927,10 +5927,10 @@ void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeLis
|
||||
qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
|
||||
}
|
||||
|
||||
// Calculate and save the offset of each block member, using the recursively
|
||||
// Calculate and save the offset of each block member, using the recursively
|
||||
// defined block offset rules and the user-provided offset and align.
|
||||
//
|
||||
// Also, compute and save the total size of the block. For the block's size, arrayness
|
||||
// Also, compute and save the total size of the block. For the block's size, arrayness
|
||||
// is not taken into account, as each element is backed by a separate buffer.
|
||||
//
|
||||
void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
@ -5954,20 +5954,20 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140,
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (memberQualifier.hasOffset()) {
|
||||
// "The specified offset must be a multiple
|
||||
// "The specified offset must be a multiple
|
||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
|
||||
|
||||
// GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
|
||||
// GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
|
||||
// member in the block or that lies within the previous member of the block"
|
||||
if (spvVersion.spv == 0) {
|
||||
if (memberQualifier.layoutOffset < offset)
|
||||
error(memberLoc, "cannot lie in previous members", "offset", "");
|
||||
|
||||
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||
// "The actual offset of a member is computed as
|
||||
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||
// "The actual offset of a member is computed as
|
||||
// follows: If offset was declared, start with that offset, otherwise start with the next available offset."
|
||||
offset = std::max(offset, memberQualifier.layoutOffset);
|
||||
} else {
|
||||
@ -5978,13 +5978,13 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
||||
}
|
||||
}
|
||||
|
||||
// "The actual alignment of a member will be the greater of the specified align alignment and the standard
|
||||
// "The actual alignment of a member will be the greater of the specified align alignment and the standard
|
||||
// (e.g., std140) base alignment for the member's type."
|
||||
if (memberQualifier.hasAlign())
|
||||
memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
|
||||
|
||||
// "If the resulting offset is not a multiple of the actual alignment,
|
||||
// increase it to the first offset that is a multiple of
|
||||
// increase it to the first offset that is a multiple of
|
||||
// the actual alignment."
|
||||
RoundToPow2(offset, memberAlignment);
|
||||
typeList[member].type->getQualifier().layoutOffset = offset;
|
||||
@ -6074,7 +6074,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
||||
error(loc, "can only apply to 'out'", id, "");
|
||||
if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
|
||||
error(loc, "cannot change previously set layout value", id, "");
|
||||
|
||||
|
||||
if (language == EShLangTessControl)
|
||||
checkIoArraysConsistency(loc);
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ protected:
|
||||
// * note, that appropriately gives an error if redeclaring a block that
|
||||
// was already used and hence already copied-up
|
||||
//
|
||||
// - on seeing a layout declaration that sizes the array, fix everything in the
|
||||
// - on seeing a layout declaration that sizes the array, fix everything in the
|
||||
// resize-list, giving errors for mismatch
|
||||
//
|
||||
// - on seeing an array size declaration, give errors on mismatch between it and previous
|
||||
|
@ -44,14 +44,14 @@ OS_TLSIndex PoolIndex;
|
||||
|
||||
void InitializeMemoryPools()
|
||||
{
|
||||
TThreadMemoryPools* pools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
TThreadMemoryPools* pools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (pools)
|
||||
return;
|
||||
|
||||
TPoolAllocator *threadPoolAllocator = new TPoolAllocator();
|
||||
|
||||
TThreadMemoryPools* threadData = new TThreadMemoryPools();
|
||||
|
||||
|
||||
threadData->threadPoolAllocator = threadPoolAllocator;
|
||||
|
||||
OS_SetTLSValue(PoolIndex, threadData);
|
||||
@ -60,12 +60,12 @@ void InitializeMemoryPools()
|
||||
void FreeGlobalPools()
|
||||
{
|
||||
// Release the allocated memory for this thread.
|
||||
TThreadMemoryPools* globalPools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
TThreadMemoryPools* globalPools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (! globalPools)
|
||||
return;
|
||||
|
||||
GetThreadPoolAllocator().popAll();
|
||||
delete &GetThreadPoolAllocator();
|
||||
delete &GetThreadPoolAllocator();
|
||||
delete globalPools;
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ void SetThreadPoolAllocator(TPoolAllocator& poolAllocator)
|
||||
// Implement the functionality of the TPoolAllocator class, which
|
||||
// is documented in PoolAlloc.h.
|
||||
//
|
||||
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
|
||||
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
|
||||
pageSize(growthIncrement),
|
||||
alignment(allocationAlignment),
|
||||
freeList(0),
|
||||
@ -206,13 +206,12 @@ void TAllocation::checkGuardBlock(unsigned char*, unsigned char, const char*) co
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void TPoolAllocator::push()
|
||||
{
|
||||
tAllocState state = { currentPageOffset, inUseList };
|
||||
|
||||
stack.push_back(state);
|
||||
|
||||
|
||||
//
|
||||
// Indicate there is no current page to allocate from.
|
||||
//
|
||||
@ -237,7 +236,7 @@ void TPoolAllocator::pop()
|
||||
while (inUseList != page) {
|
||||
// invoke destructor to free allocation list
|
||||
inUseList->~tHeader();
|
||||
|
||||
|
||||
tHeader* nextInUse = inUseList->nextPage;
|
||||
if (inUseList->pageCount > 1)
|
||||
delete [] reinterpret_cast<char*>(inUseList);
|
||||
@ -269,7 +268,7 @@ void* TPoolAllocator::allocate(size_t numBytes)
|
||||
// size including guard blocks. In release build,
|
||||
// guardBlockSize=0 and this all gets optimized away.
|
||||
size_t allocationSize = TAllocation::allocationSize(numBytes);
|
||||
|
||||
|
||||
//
|
||||
// Just keep some interesting statistics.
|
||||
//
|
||||
@ -327,14 +326,13 @@ void* TPoolAllocator::allocate(size_t numBytes)
|
||||
// Use placement-new to initialize header
|
||||
new(memory) tHeader(inUseList, 1);
|
||||
inUseList = memory;
|
||||
|
||||
|
||||
unsigned char* ret = reinterpret_cast<unsigned char*>(inUseList) + headerSkip;
|
||||
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
|
||||
|
||||
return initializeAllocation(inUseList, ret, numBytes);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check all allocations in a list for damage by calling check on each.
|
||||
//
|
||||
|
@ -142,13 +142,13 @@ void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab)
|
||||
{
|
||||
do {
|
||||
consumeWhiteSpace(foundNonSpaceTab);
|
||||
|
||||
|
||||
// if not starting a comment now, then done
|
||||
int c = peek();
|
||||
if (c != '/' || c == EndOfInput)
|
||||
return;
|
||||
|
||||
// skip potential comment
|
||||
// skip potential comment
|
||||
foundNonSpaceTab = true;
|
||||
if (! consumeComment())
|
||||
return;
|
||||
@ -199,10 +199,10 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
|
||||
}
|
||||
lookingInMiddle = true;
|
||||
|
||||
// Nominal start, skipping the desktop allowed comments and white space, but tracking if
|
||||
// Nominal start, skipping the desktop allowed comments and white space, but tracking if
|
||||
// something else was found for ES:
|
||||
consumeWhitespaceComment(foundNonSpaceTab);
|
||||
if (foundNonSpaceTab)
|
||||
if (foundNonSpaceTab)
|
||||
versionNotFirst = true;
|
||||
|
||||
// "#"
|
||||
@ -802,7 +802,7 @@ int TScanContext::tokenizeIdentifier()
|
||||
return keyword;
|
||||
|
||||
case BUFFER:
|
||||
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
||||
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
||||
(parseContext.profile != EEsProfile && parseContext.version < 430))
|
||||
return identifierOrType();
|
||||
return keyword;
|
||||
@ -962,7 +962,7 @@ int TScanContext::tokenizeIdentifier()
|
||||
case U64VEC3:
|
||||
case U64VEC4:
|
||||
afterType = true;
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
(parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) &&
|
||||
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||
return keyword;
|
||||
@ -1194,7 +1194,7 @@ int TScanContext::tokenizeIdentifier()
|
||||
return keyword;
|
||||
|
||||
case PRECISE:
|
||||
if ((parseContext.profile == EEsProfile && parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5)) ||
|
||||
if ((parseContext.profile == EEsProfile && parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5)) ||
|
||||
(parseContext.profile != EEsProfile && parseContext.version >= 400))
|
||||
return keyword;
|
||||
if (parseContext.profile == EEsProfile && parseContext.version == 310) {
|
||||
@ -1356,7 +1356,7 @@ int TScanContext::dMat()
|
||||
|
||||
int TScanContext::firstGenerationImage(bool inEs310)
|
||||
{
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
(parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) ||
|
||||
(inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
|
||||
return keyword;
|
||||
@ -1381,8 +1381,8 @@ int TScanContext::secondGenerationImage()
|
||||
return keyword;
|
||||
}
|
||||
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
(parseContext.profile != EEsProfile &&
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
(parseContext.profile != EEsProfile &&
|
||||
(parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
|
||||
return keyword;
|
||||
|
||||
|
@ -254,7 +254,7 @@ protected:
|
||||
size_t currentChar;
|
||||
|
||||
// This is for reporting what string/line an error occurred on, and can be overridden by #line.
|
||||
// It remembers the last state of each source string as it is left for the next one, so unget()
|
||||
// It remembers the last state of each source string as it is left for the next one, so unget()
|
||||
// can restore that state.
|
||||
TSourceLoc* loc; // an array
|
||||
|
||||
|
@ -194,11 +194,11 @@ enum EPrecisionClass {
|
||||
EPcCount
|
||||
};
|
||||
|
||||
// A process-global symbol table per version per profile for built-ins common
|
||||
// to multiple stages (languages), and a process-global symbol table per version
|
||||
// A process-global symbol table per version per profile for built-ins common
|
||||
// to multiple stages (languages), and a process-global symbol table per version
|
||||
// per profile per stage for built-ins unique to each stage. They will be sparsely
|
||||
// populated, so they will only be generated as needed.
|
||||
//
|
||||
//
|
||||
// Each has a different set of built-ins, and we want to preserve that from
|
||||
// compile to compile.
|
||||
//
|
||||
@ -214,10 +214,10 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
|
||||
EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable)
|
||||
{
|
||||
TIntermediate intermediate(language, version, profile);
|
||||
|
||||
|
||||
intermediate.setSource(source);
|
||||
|
||||
std::unique_ptr<TParseContextBase> parseContext(CreateParseContext(symbolTable, intermediate, version, profile, source,
|
||||
std::unique_ptr<TParseContextBase> parseContext(CreateParseContext(symbolTable, intermediate, version, profile, source,
|
||||
language, infoSink, spvVersion, true, EShMsgDefault,
|
||||
true));
|
||||
|
||||
@ -226,7 +226,7 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
|
||||
TScanContext scanContext(*parseContext);
|
||||
parseContext->setScanContext(&scanContext);
|
||||
parseContext->setPpContext(&ppContext);
|
||||
|
||||
|
||||
//
|
||||
// Push the symbol table to give it an initial scope. This
|
||||
// push should not have a corresponding pop, so that built-ins
|
||||
@ -242,7 +242,7 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
|
||||
|
||||
if (builtInLengths[0] == 0)
|
||||
return true;
|
||||
|
||||
|
||||
TInputScanner input(1, builtInShaders, builtInLengths);
|
||||
if (! parseContext->parseShaderStrings(ppContext, input) != 0) {
|
||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||
@ -330,7 +330,7 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
|
||||
EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source)
|
||||
{
|
||||
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
||||
|
||||
|
||||
builtInParseables->initialize(*resources, version, profile, spvVersion, language);
|
||||
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable);
|
||||
builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources);
|
||||
@ -339,7 +339,7 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
|
||||
}
|
||||
|
||||
//
|
||||
// To do this on the fly, we want to leave the current state of our thread's
|
||||
// To do this on the fly, we want to leave the current state of our thread's
|
||||
// pool allocator intact, so:
|
||||
// - Switch to a new pool for parsing the built-ins
|
||||
// - Do the parsing, which builds the symbol table, using the new pool
|
||||
@ -402,7 +402,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
||||
[versionIndex][spvVersionIndex][profileIndex][sourceIndex][CommonIndex(profile, (EShLanguage)stage)]);
|
||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable(*stageTables[stage]);
|
||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the local tables before deleting the pool they used.
|
||||
@ -471,7 +471,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
||||
profile = ECoreProfile;
|
||||
else
|
||||
profile = ENoProfile;
|
||||
}
|
||||
}
|
||||
// else: typical desktop case... e.g., "#version 410 core"
|
||||
}
|
||||
}
|
||||
@ -628,7 +628,7 @@ bool ProcessDeferred(
|
||||
|
||||
if (numStrings == 0)
|
||||
return true;
|
||||
|
||||
|
||||
// Move to length-based strings, rather than null-terminated strings.
|
||||
// Also, add strings to include the preamble and to ensure the shader is not null,
|
||||
// which lets the grammar accept what was a null (post preprocessing) shader.
|
||||
@ -710,24 +710,24 @@ bool ProcessDeferred(
|
||||
if (spvVersion.vulkan >= 100)
|
||||
intermediate.setOriginUpperLeft();
|
||||
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
||||
|
||||
|
||||
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
||||
[MapSpvVersionToIndex(spvVersion)]
|
||||
[MapProfileToIndex(profile)]
|
||||
[MapSourceToIndex(source)]
|
||||
[compiler->getLanguage()];
|
||||
|
||||
|
||||
// Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
|
||||
TSymbolTable* symbolTableMemory = new TSymbolTable;
|
||||
TSymbolTable& symbolTable = *symbolTableMemory;
|
||||
if (cachedTable)
|
||||
symbolTable.adoptLevels(*cachedTable);
|
||||
|
||||
|
||||
// Add built-in symbols that are potentially context dependent;
|
||||
// they get popped again further down.
|
||||
AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, spvVersion,
|
||||
compiler->getLanguage(), source);
|
||||
|
||||
|
||||
//
|
||||
// Now we can process the full shader under proper symbols and rules.
|
||||
//
|
||||
@ -754,7 +754,7 @@ bool ProcessDeferred(
|
||||
}
|
||||
|
||||
parseContext->initializeExtensionBehavior();
|
||||
|
||||
|
||||
// Fill in the strings as outlined above.
|
||||
std::string preamble;
|
||||
parseContext->getPreamble(preamble);
|
||||
@ -978,7 +978,7 @@ struct DoFullParse{
|
||||
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
|
||||
TInputScanner& fullInput, bool versionWillBeError,
|
||||
TSymbolTable&, TIntermediate& intermediate,
|
||||
EShOptimizationLevel optLevel, EShMessages messages)
|
||||
EShOptimizationLevel optLevel, EShMessages messages)
|
||||
{
|
||||
bool success = true;
|
||||
// Parse the full shader.
|
||||
@ -1032,7 +1032,6 @@ bool PreprocessDeferred(
|
||||
false, includer);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// do a partial compile on the given strings for a single compilation unit
|
||||
// for a potential deferred link into a single stage (and deferred full compile of that
|
||||
@ -1041,7 +1040,7 @@ bool PreprocessDeferred(
|
||||
// all preprocessing, parsing, semantic checks, etc. for a single compilation unit
|
||||
// are done here.
|
||||
//
|
||||
// return: the tree and other information is filled into the intermediate argument,
|
||||
// return: the tree and other information is filled into the intermediate argument,
|
||||
// and true is returned by the function for success.
|
||||
//
|
||||
bool CompileDeferred(
|
||||
@ -1072,7 +1071,6 @@ bool CompileDeferred(
|
||||
|
||||
} // end anonymous namespace for local functions
|
||||
|
||||
|
||||
//
|
||||
// ShInitialize() should be called exactly once per process, not per thread.
|
||||
//
|
||||
@ -1103,7 +1101,7 @@ ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));
|
||||
|
||||
|
||||
return reinterpret_cast<void*>(base);
|
||||
}
|
||||
|
||||
@ -1264,8 +1262,7 @@ int ShLinkExt(
|
||||
}
|
||||
if (base->getAsCompiler())
|
||||
cObjects.push_back(base->getAsCompiler());
|
||||
|
||||
|
||||
|
||||
if (cObjects[i] == 0)
|
||||
return 0;
|
||||
}
|
||||
@ -1281,7 +1278,7 @@ int ShLinkExt(
|
||||
for (int i = 0; i < numHandles; ++i) {
|
||||
if (cObjects[i]->getAsCompiler()) {
|
||||
if (! cObjects[i]->getAsCompiler()->linkable()) {
|
||||
linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");
|
||||
linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1340,7 +1337,7 @@ const void* ShGetExecutable(const ShHandle handle)
|
||||
return 0;
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
|
||||
|
||||
TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
|
||||
if (linker == 0)
|
||||
return 0;
|
||||
@ -1357,7 +1354,7 @@ const void* ShGetExecutable(const ShHandle handle)
|
||||
// success or failure.
|
||||
//
|
||||
int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
|
||||
{
|
||||
{
|
||||
if (!InitThread())
|
||||
return 0;
|
||||
|
||||
@ -1369,7 +1366,7 @@ int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* t
|
||||
|
||||
if (linker == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
linker->setAppAttributeBindings(table);
|
||||
|
||||
return 1;
|
||||
@ -1446,7 +1443,7 @@ int ShGetUniformLocation(const ShHandle handle, const char* name)
|
||||
//
|
||||
// Below is a new alternate C++ interface that might potentially replace the above
|
||||
// opaque handle-based interface.
|
||||
//
|
||||
//
|
||||
// See more detailed comment in ShaderLang.h
|
||||
//
|
||||
|
||||
@ -1552,7 +1549,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
||||
{
|
||||
if (! InitThread())
|
||||
return false;
|
||||
|
||||
|
||||
pool = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*pool);
|
||||
if (! preamble)
|
||||
@ -1636,7 +1633,7 @@ bool TProgram::link(EShMessages messages)
|
||||
linked = true;
|
||||
|
||||
bool error = false;
|
||||
|
||||
|
||||
pool = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*pool);
|
||||
|
||||
@ -1723,7 +1720,7 @@ const char* TProgram::getInfoDebugLog()
|
||||
//
|
||||
|
||||
bool TProgram::buildReflection()
|
||||
{
|
||||
{
|
||||
if (! linked || reflection)
|
||||
return false;
|
||||
|
||||
|
@ -120,7 +120,7 @@ protected:
|
||||
const TString *name;
|
||||
unsigned int uniqueId; // For cross-scope comparing during code generation
|
||||
|
||||
// For tracking what extensions must be present
|
||||
// For tracking what extensions must be present
|
||||
// (don't use if correct version/profile is present).
|
||||
int numExtensions;
|
||||
const char** extensions; // an array of pointers to existing constant char strings
|
||||
@ -145,7 +145,7 @@ protected:
|
||||
class TVariable : public TSymbol {
|
||||
public:
|
||||
TVariable(const TString *name, const TType& t, bool uT = false )
|
||||
: TSymbol(name),
|
||||
: TSymbol(name),
|
||||
userType(uT),
|
||||
constSubtree(nullptr),
|
||||
anonId(-1) { type.shallowCopy(t); }
|
||||
@ -192,7 +192,7 @@ struct TParameter {
|
||||
TString *name;
|
||||
TType* type;
|
||||
TIntermTyped* defaultValue;
|
||||
void copyParam(const TParameter& param)
|
||||
void copyParam(const TParameter& param)
|
||||
{
|
||||
if (param.name)
|
||||
name = NewPoolTString(param.name->c_str());
|
||||
@ -284,7 +284,7 @@ public:
|
||||
virtual const TAnonMember* getAsAnonMember() const { return this; }
|
||||
virtual const TVariable& getAnonContainer() const { return anonContainer; }
|
||||
virtual unsigned int getMemberNumber() const { return memberNumber; }
|
||||
|
||||
|
||||
virtual const TType& getType() const
|
||||
{
|
||||
const TTypeList& types = *anonContainer.getType().getStruct();
|
||||
@ -297,7 +297,7 @@ public:
|
||||
const TTypeList& types = *anonContainer.getType().getStruct();
|
||||
return *types[memberNumber].type;
|
||||
}
|
||||
|
||||
|
||||
virtual int getAnonId() const { return anonId; }
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
|
||||
@ -377,7 +377,7 @@ public:
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
if (it == level.end())
|
||||
if (it == level.end())
|
||||
return 0;
|
||||
else
|
||||
return (*it).second;
|
||||
@ -500,7 +500,7 @@ public:
|
||||
while (table.size() > adoptedLevels)
|
||||
pop(0);
|
||||
}
|
||||
|
||||
|
||||
void adoptLevels(TSymbolTable& symTable)
|
||||
{
|
||||
for (unsigned int level = 0; level < symTable.table.size(); ++level) {
|
||||
@ -532,7 +532,7 @@ public:
|
||||
|
||||
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
|
||||
void setSeparateNameSpaces() { separateNameSpaces = true; }
|
||||
|
||||
|
||||
void push()
|
||||
{
|
||||
table.push_back(new TSymbolTableLevel);
|
||||
@ -558,7 +558,7 @@ public:
|
||||
// make sure there isn't a function of this variable name
|
||||
if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
|
||||
return false;
|
||||
|
||||
|
||||
// check for not overloading or redefining a built-in function
|
||||
if (noBuiltInRedeclarations) {
|
||||
if (atGlobalLevel() && currentLevel() > 0) {
|
||||
@ -582,7 +582,7 @@ public:
|
||||
|
||||
//
|
||||
// To allocate an internal temporary, which will need to be uniquely
|
||||
// identified by the consumer of the AST, but never need to
|
||||
// identified by the consumer of the AST, but never need to
|
||||
// found by doing a symbol table search by name, hence allowed an
|
||||
// arbitrary name in the symbol with no worry of collision.
|
||||
//
|
||||
@ -684,7 +684,7 @@ public:
|
||||
for (unsigned int level = 0; level < table.size(); ++level)
|
||||
table[level]->relateToOperator(name, op);
|
||||
}
|
||||
|
||||
|
||||
void setFunctionExtensions(const char* name, int num, const char* const extensions[])
|
||||
{
|
||||
for (unsigned int level = 0; level < table.size(); ++level)
|
||||
|
@ -37,7 +37,7 @@
|
||||
//
|
||||
// Help manage multiple profiles, versions, extensions etc.
|
||||
//
|
||||
// These don't return error codes, as the presumption is parsing will
|
||||
// These don't return error codes, as the presumption is parsing will
|
||||
// always continue as if the tested feature were enabled, and thus there
|
||||
// is no error recovery needed.
|
||||
//
|
||||
@ -47,25 +47,25 @@
|
||||
//
|
||||
// To add a new hypothetical "Feature F" to the front end, where an extension
|
||||
// "XXX_extension_X" can be used to enable the feature, do the following.
|
||||
//
|
||||
//
|
||||
// OVERVIEW: Specific features are what are error-checked for, not
|
||||
// extensions: A specific Feature F might be enabled by an extension, or a
|
||||
// extensions: A specific Feature F might be enabled by an extension, or a
|
||||
// particular version in a particular profile, or a stage, or combinations, etc.
|
||||
//
|
||||
// The basic mechanism is to use the following to "declare" all the things that
|
||||
//
|
||||
// The basic mechanism is to use the following to "declare" all the things that
|
||||
// enable/disable Feature F, in a code path that implements Feature F:
|
||||
//
|
||||
//
|
||||
// requireProfile()
|
||||
// profileRequires()
|
||||
// requireStage()
|
||||
// checkDeprecated()
|
||||
// requireNotRemoved()
|
||||
// requireExtensions()
|
||||
//
|
||||
// Typically, only the first two calls are needed. They go into a code path that
|
||||
// implements Feature F, and will log the proper error/warning messages. Parsing
|
||||
//
|
||||
// Typically, only the first two calls are needed. They go into a code path that
|
||||
// implements Feature F, and will log the proper error/warning messages. Parsing
|
||||
// will then always continue as if the tested feature was enabled.
|
||||
//
|
||||
//
|
||||
// There is typically no if-testing or conditional parsing, just insertion of the calls above.
|
||||
// However, if symbols specific to the extension are added (step 5), they will
|
||||
// only be added under tests that the minimum version and profile are present.
|
||||
@ -73,10 +73,10 @@
|
||||
// 1) Add a symbol name for the extension string at the bottom of Versions.h:
|
||||
//
|
||||
// const char* const XXX_extension_X = "XXX_extension_X";
|
||||
//
|
||||
//
|
||||
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
|
||||
// the first function below:
|
||||
//
|
||||
//
|
||||
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
||||
//
|
||||
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
|
||||
@ -84,50 +84,50 @@
|
||||
// "#define XXX_extension_X 1\n"
|
||||
//
|
||||
// The new-line is important, as that ends preprocess tokens.
|
||||
//
|
||||
//
|
||||
// 4) Insert a profile check in the feature's path (unless all profiles support the feature,
|
||||
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
|
||||
//
|
||||
//
|
||||
// // ... in a path specific to Feature F...
|
||||
// requireProfile(loc,
|
||||
// ECoreProfile | ECompatibilityProfile,
|
||||
// "Feature F");
|
||||
//
|
||||
//
|
||||
// 5) For each profile that supports the feature, insert version/extension checks:
|
||||
//
|
||||
//
|
||||
// The mostly likely scenario is that Feature F can only be used with a
|
||||
// particular profile if XXX_extension_X is present or the version is
|
||||
// high enough that the core specification already incorporated it.
|
||||
//
|
||||
//
|
||||
// // following the requireProfile() call...
|
||||
// profileRequires(loc,
|
||||
// profileRequires(loc,
|
||||
// ECoreProfile | ECompatibilityProfile,
|
||||
// 420, // 0 if no version incorporated the feature into the core spec.
|
||||
// XXX_extension_X, // can be a list of extensions that all add the feature
|
||||
// "Feature F Description");
|
||||
//
|
||||
//
|
||||
// This allows the feature if either A) one of the extensions is enabled or
|
||||
// B) the version is high enough. If no version yet incorporates the feature
|
||||
// into core, pass in 0.
|
||||
//
|
||||
//
|
||||
// This can be called multiple times, if different profiles support the
|
||||
// feature starting at different version numbers or with different
|
||||
// feature starting at different version numbers or with different
|
||||
// extensions.
|
||||
//
|
||||
//
|
||||
// This must be called for each profile allowed by the initial call to requireProfile().
|
||||
//
|
||||
//
|
||||
// Profiles are all masks, which can be "or"-ed together.
|
||||
//
|
||||
//
|
||||
// ENoProfile
|
||||
// ECoreProfile
|
||||
// ECompatibilityProfile
|
||||
// EEsProfile
|
||||
//
|
||||
//
|
||||
// The ENoProfile profile is only for desktop, before profiles showed up in version 150;
|
||||
// All other #version with no profile default to either es or core, and so have profiles.
|
||||
//
|
||||
//
|
||||
// You can select all but a particular profile using ~. The following basically means "desktop":
|
||||
//
|
||||
//
|
||||
// ~EEsProfile
|
||||
//
|
||||
// 6) If built-in symbols are added by the extension, add them in Initialize.cpp: Their use
|
||||
@ -155,7 +155,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
||||
extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable;
|
||||
|
||||
|
||||
extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable;
|
||||
extensionBehavior[E_GL_3DL_array_objects] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shading_language_420pack] = EBhDisable;
|
||||
@ -195,7 +195,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
|
||||
#endif
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
||||
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
||||
#endif
|
||||
@ -234,7 +234,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
void TParseVersions::getPreamble(std::string& preamble)
|
||||
{
|
||||
if (profile == EEsProfile) {
|
||||
preamble =
|
||||
preamble =
|
||||
"#define GL_ES 1\n"
|
||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||
"#define GL_OES_texture_3D 1\n"
|
||||
@ -273,7 +273,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||
;
|
||||
} else {
|
||||
preamble =
|
||||
preamble =
|
||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||
"#define GL_ARB_texture_rectangle 1\n"
|
||||
"#define GL_ARB_shading_language_420pack 1\n"
|
||||
@ -308,7 +308,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
"#define GL_AMD_gpu_shader_half_float 1\n"
|
||||
#endif
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
"#define GL_NV_sample_mask_override_coverage 1\n"
|
||||
"#define GL_NV_geometry_shader_passthrough 1\n"
|
||||
#endif
|
||||
@ -316,7 +316,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
}
|
||||
|
||||
// #line and #include
|
||||
preamble +=
|
||||
preamble +=
|
||||
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
||||
"#define GL_GOOGLE_include_directive 1\n"
|
||||
;
|
||||
@ -343,7 +343,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
//
|
||||
// When to use requireProfile():
|
||||
//
|
||||
// Use if only some profiles support a feature. However, if within a profile the feature
|
||||
// Use if only some profiles support a feature. However, if within a profile the feature
|
||||
// is version or extension specific, follow this call with calls to profileRequires().
|
||||
//
|
||||
// Operation: If the current profile is not one of the profileMask,
|
||||
@ -358,7 +358,7 @@ void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, cons
|
||||
//
|
||||
// Map from stage enum to externally readable text name.
|
||||
//
|
||||
const char* StageName(EShLanguage stage)
|
||||
const char* StageName(EShLanguage stage)
|
||||
{
|
||||
switch(stage) {
|
||||
case EShLangVertex: return "vertex";
|
||||
@ -383,7 +383,7 @@ const char* StageName(EShLanguage stage)
|
||||
// Operation: Will issue warnings/errors based on the current profile, version, and extension
|
||||
// behaviors. It only checks extensions when the current profile is one of the profileMask.
|
||||
//
|
||||
// A minVersion of 0 means no version of the profileMask support this in core,
|
||||
// A minVersion of 0 means no version of the profileMask support this in core,
|
||||
// the extension must be present.
|
||||
//
|
||||
|
||||
@ -421,7 +421,7 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int
|
||||
//
|
||||
// When to use requireStage()
|
||||
//
|
||||
// If only some stages support a feature.
|
||||
// If only some stages support a feature.
|
||||
//
|
||||
// Operation: If the current stage is not present, give an error message.
|
||||
//
|
||||
@ -663,7 +663,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
||||
// Call for any operation needing full GLSL integer data-type support.
|
||||
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
||||
{
|
||||
profileRequires(loc, ENoProfile, 130, nullptr, op);
|
||||
profileRequires(loc, ENoProfile, 130, nullptr, op);
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, op);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ protected:
|
||||
// check binary operations for those modifying the loop index
|
||||
bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||
{
|
||||
if (node->modifiesState() && node->getLeft()->getAsSymbolNode() &&
|
||||
if (node->modifiesState() && node->getLeft()->getAsSymbolNode() &&
|
||||
node->getLeft()->getAsSymbolNode()->getId() == loopId) {
|
||||
bad = true;
|
||||
badLoc = node->getLoc();
|
||||
@ -95,7 +95,7 @@ bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||
// check unary operations for those modifying the loop index
|
||||
bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||
{
|
||||
if (node->modifiesState() && node->getOperand()->getAsSymbolNode() &&
|
||||
if (node->modifiesState() && node->getOperand()->getAsSymbolNode() &&
|
||||
node->getOperand()->getAsSymbolNode()->getId() == loopId) {
|
||||
bad = true;
|
||||
badLoc = node->getLoc();
|
||||
@ -145,7 +145,7 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo
|
||||
//
|
||||
// The "constant-index-expression" tranverser.
|
||||
//
|
||||
// Just look at things that can form an index.
|
||||
// Just look at things that can form an index.
|
||||
//
|
||||
|
||||
class TIndexTraverser : public TIntermTraverser {
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include "../Include/InfoSink.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
|
||||
//
|
||||
// Link-time error emitter.
|
||||
//
|
||||
@ -67,8 +67,8 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
||||
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
||||
}
|
||||
|
||||
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
||||
// name must have the exact same set of members qualified with offset and their integral-constant
|
||||
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
||||
// name must have the exact same set of members qualified with offset and their integral-constant
|
||||
// expression values must be the same, or a link-time error results."
|
||||
|
||||
//
|
||||
@ -112,12 +112,12 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||
inputPrimitive = unit.inputPrimitive;
|
||||
else if (inputPrimitive != unit.inputPrimitive)
|
||||
error(infoSink, "Contradictory input layout primitives");
|
||||
|
||||
|
||||
if (outputPrimitive == ElgNone)
|
||||
outputPrimitive = unit.outputPrimitive;
|
||||
else if (outputPrimitive != unit.outputPrimitive)
|
||||
error(infoSink, "Contradictory output layout primitives");
|
||||
|
||||
|
||||
if (vertices == TQualifier::layoutNotSet)
|
||||
vertices = unit.vertices;
|
||||
else if (vertices != unit.vertices) {
|
||||
@ -178,7 +178,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||
}
|
||||
|
||||
// Getting this far means we have two existing trees to merge...
|
||||
|
||||
|
||||
version = std::max(version, unit.version);
|
||||
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
|
||||
|
||||
@ -341,9 +341,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||
writeTypeComparison = true;
|
||||
}
|
||||
|
||||
// Layouts...
|
||||
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
|
||||
// requires separate user-supplied offset from actual computed offset, but
|
||||
// Layouts...
|
||||
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
|
||||
// requires separate user-supplied offset from actual computed offset, but
|
||||
// current implementation only has one offset.
|
||||
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
|
||||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
|
||||
@ -417,7 +417,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||
if (xfbBuffers[b].containsDouble)
|
||||
RoundToPow2(xfbBuffers[b].implicitStride, 8);
|
||||
|
||||
// "It is a compile-time or link-time error to have
|
||||
// "It is a compile-time or link-time error to have
|
||||
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
|
||||
// in different compilation units. While xfb_stride can be declared multiple times for the same buffer, it is a
|
||||
// compile-time or link-time error to have different values specified for the stride for the same buffer."
|
||||
@ -429,8 +429,8 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
|
||||
xfbBuffers[b].stride = xfbBuffers[b].implicitStride;
|
||||
|
||||
// "If the buffer is capturing any
|
||||
// outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a
|
||||
// "If the buffer is capturing any
|
||||
// outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a
|
||||
// multiple of 4, or a compile-time or link-time error results."
|
||||
if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) {
|
||||
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:");
|
||||
@ -442,7 +442,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||
}
|
||||
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
||||
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
|
||||
error(infoSink, "xfb_stride is too large:");
|
||||
@ -540,7 +540,7 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
|
||||
break;
|
||||
|
||||
// Otherwise, we found a new subgraph, process it:
|
||||
// See what all can be reached by this new root, and if any of
|
||||
// See what all can be reached by this new root, and if any of
|
||||
// that is recursive. This is done by depth-first traversals, seeing
|
||||
// if a new call is found that was already in the currentPath (a back edge),
|
||||
// thereby detecting recursion.
|
||||
@ -709,7 +709,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
|
||||
}
|
||||
|
||||
// See if a variable was both a user-declared output and used.
|
||||
// Note: the spec discusses writing to one, but this looks at read or write, which
|
||||
// Note: the spec discusses writing to one, but this looks at read or write, which
|
||||
// is more useful, and perhaps the spec should be changed to reflect that.
|
||||
bool TIntermediate::userOutputUsed() const
|
||||
{
|
||||
@ -720,7 +720,7 @@ bool TIntermediate::userOutputUsed() const
|
||||
const TIntermSymbol& symbolNode = *linkerObjects[i]->getAsSymbolNode();
|
||||
if (symbolNode.getQualifier().storage == EvqVaryingOut &&
|
||||
symbolNode.getName().compare(0, 3, "gl_") != 0 &&
|
||||
inIoAccessed(symbolNode.getName())) {
|
||||
inIoAccessed(symbolNode.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -899,7 +899,7 @@ bool TIntermediate::addUsedConstantId(int id)
|
||||
// Return the size of type, as measured by "locations".
|
||||
int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||
{
|
||||
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
|
||||
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
|
||||
// consecutive locations..."
|
||||
if (type.isArray()) {
|
||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||
@ -911,8 +911,8 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||
return type.getOuterArraySize() * computeTypeLocationSize(elementType);
|
||||
}
|
||||
|
||||
// "The locations consumed by block and structure members are determined by applying the rules above
|
||||
// recursively..."
|
||||
// "The locations consumed by block and structure members are determined by applying the rules above
|
||||
// recursively..."
|
||||
if (type.isStruct()) {
|
||||
int size = 0;
|
||||
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||
@ -924,9 +924,9 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||
|
||||
// ES: "If a shader input is any scalar or vector type, it will consume a single location."
|
||||
|
||||
// Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex
|
||||
// shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while
|
||||
// types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will
|
||||
// Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex
|
||||
// shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while
|
||||
// types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will
|
||||
// consume only a single location, in all stages."
|
||||
if (type.isScalar())
|
||||
return 1;
|
||||
@ -940,7 +940,7 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||
}
|
||||
|
||||
// "If the declared input is an n x m single- or double-precision matrix, ...
|
||||
// The number of locations assigned for each matrix will be the same as
|
||||
// The number of locations assigned for each matrix will be the same as
|
||||
// for an n-element array of m-component vectors..."
|
||||
if (type.isMatrix()) {
|
||||
TType columnType(type, 0);
|
||||
@ -986,14 +986,14 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
|
||||
// N.B. Caller must set containsDouble to false before calling.
|
||||
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const
|
||||
{
|
||||
// "...if applied to an aggregate containing a double, the offset must also be a multiple of 8,
|
||||
// "...if applied to an aggregate containing a double, the offset must also be a multiple of 8,
|
||||
// and the space taken in the buffer will be a multiple of 8.
|
||||
// ...within the qualified entity, subsequent components are each
|
||||
// ...within the qualified entity, subsequent components are each
|
||||
// assigned, in order, to the next available offset aligned to a multiple of
|
||||
// that component's size. Aggregate types are flattened down to the component
|
||||
// level to get this sequence of components."
|
||||
|
||||
if (type.isArray()) {
|
||||
if (type.isArray()) {
|
||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||
assert(type.isExplicitlySizedArray());
|
||||
TType elementType(type, 0);
|
||||
@ -1005,8 +1005,8 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||
bool structContainsDouble = false;
|
||||
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||
TType memberType(type, member);
|
||||
// "... if applied to
|
||||
// an aggregate containing a double, the offset must also be a multiple of 8,
|
||||
// "... if applied to
|
||||
// an aggregate containing a double, the offset must also be a multiple of 8,
|
||||
// and the space taken in the buffer will be a multiple of 8."
|
||||
bool memberContainsDouble = false;
|
||||
int memberSize = computeTypeXfbSize(memberType, memberContainsDouble);
|
||||
@ -1064,7 +1064,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||
// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
|
||||
// Operates recursively.
|
||||
//
|
||||
// If std140 is true, it does the rounding up to vec4 size required by std140,
|
||||
// If std140 is true, it does the rounding up to vec4 size required by std140,
|
||||
// otherwise it does not, yielding std430 rules.
|
||||
//
|
||||
// The size is returned in the 'size' parameter
|
||||
@ -1093,7 +1093,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
//
|
||||
// 1. If the member is a scalar consuming N basic machine units, the base alignment is N.
|
||||
//
|
||||
// 2. If the member is a two- or four-component vector with components consuming N basic
|
||||
// 2. If the member is a two- or four-component vector with components consuming N basic
|
||||
// machine units, the base alignment is 2N or 4N, respectively.
|
||||
//
|
||||
// 3. If the member is a three-component vector with components consuming N
|
||||
@ -1106,7 +1106,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
// the array is rounded up to the next multiple of the base alignment.
|
||||
//
|
||||
// 5. If the member is a column-major matrix with C columns and R rows, the
|
||||
// matrix is stored identically to an array of C column vectors with R
|
||||
// matrix is stored identically to an array of C column vectors with R
|
||||
// components each, according to rule (4).
|
||||
//
|
||||
// 6. If the member is an array of S column-major matrices with C columns and
|
||||
@ -1123,7 +1123,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
//
|
||||
// 9. If the member is a structure, the base alignment of the structure is N , where
|
||||
// N is the largest base alignment value of any of its members, and rounded
|
||||
// up to the base alignment of a vec4. The individual members of this substructure
|
||||
// up to the base alignment of a vec4. The individual members of this substructure
|
||||
// are then assigned offsets by applying this set of rules recursively,
|
||||
// where the base offset of the first member of the sub-structure is equal to the
|
||||
// aligned offset of the structure. The structure may have padding at the end;
|
||||
@ -1165,7 +1165,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
|
||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||
RoundToPow2(size, memberAlignment);
|
||||
RoundToPow2(size, memberAlignment);
|
||||
size += memberSize;
|
||||
}
|
||||
|
||||
@ -1188,7 +1188,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
case 2:
|
||||
size *= 2;
|
||||
return 2 * scalarAlign;
|
||||
default:
|
||||
default:
|
||||
size *= type.getVectorSize();
|
||||
return 4 * scalarAlign;
|
||||
}
|
||||
@ -1198,7 +1198,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||
if (type.isMatrix()) {
|
||||
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||
TType derefType(type, 0, rowMajor);
|
||||
|
||||
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||
if (std140)
|
||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||
|
@ -83,7 +83,7 @@ struct TCall {
|
||||
// A generic 1-D range.
|
||||
struct TRange {
|
||||
TRange(int start, int last) : start(start), last(last) { }
|
||||
bool overlap(const TRange& rhs) const
|
||||
bool overlap(const TRange& rhs) const
|
||||
{
|
||||
return last >= rhs.start && start <= rhs.last;
|
||||
}
|
||||
@ -151,7 +151,7 @@ public:
|
||||
shiftUboBinding(0),
|
||||
autoMapBindings(false),
|
||||
flattenUniformArrays(false),
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
layoutOverrideCoverage(false),
|
||||
geoPassthroughEXT(false),
|
||||
#endif
|
||||
@ -192,7 +192,7 @@ public:
|
||||
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||
void setNoStorageFormat(bool b) { useUnknownFormat = b; }
|
||||
bool getNoStorageFormat() const { return useUnknownFormat; }
|
||||
|
||||
|
||||
void setVersion(int v) { version = v; }
|
||||
int getVersion() const { return version; }
|
||||
void setProfile(EProfile p) { profile = p; }
|
||||
@ -273,7 +273,7 @@ public:
|
||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
||||
|
||||
bool setInvocations(int i)
|
||||
bool setInvocations(int i)
|
||||
{
|
||||
if (invocations != TQualifier::layoutNotSet)
|
||||
return invocations == i;
|
||||
@ -315,7 +315,7 @@ public:
|
||||
TVertexOrder getVertexOrder() const { return vertexOrder; }
|
||||
void setPointMode() { pointMode = true; }
|
||||
bool getPointMode() const { return pointMode; }
|
||||
|
||||
|
||||
bool setLocalSize(int dim, int size)
|
||||
{
|
||||
if (localSize[dim] > 1)
|
||||
@ -391,7 +391,7 @@ public:
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||
bool promote(TIntermOperator*);
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
||||
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
||||
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
||||
@ -417,7 +417,7 @@ protected:
|
||||
bool promoteBinary(TIntermBinary&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||
bool promoteAggregate(TIntermAggregate&);
|
||||
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
std::string entryPointName;
|
||||
@ -458,7 +458,7 @@ protected:
|
||||
bool xfbMode;
|
||||
bool multiStream;
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
#ifdef NV_EXTENSIONS
|
||||
bool layoutOverrideCoverage;
|
||||
bool geoPassthroughEXT;
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@
|
||||
//
|
||||
|
||||
//
|
||||
// Travarse a tree of constants to create a single folded constant.
|
||||
// Traverse a tree of constants to create a single folded constant.
|
||||
// It should only be used when the whole tree is known to be constant.
|
||||
//
|
||||
|
||||
@ -45,7 +45,7 @@ class TConstTraverser : public TIntermTraverser {
|
||||
public:
|
||||
TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
|
||||
: unionArray(cUnion), type(t),
|
||||
constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
|
||||
constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
|
||||
matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; }
|
||||
|
||||
virtual void visitConstantUnion(TIntermConstantUnion* node);
|
||||
@ -73,7 +73,7 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||
if (! node->isConstructor() && node->getOp() != EOpComma) {
|
||||
error = true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node->getSequence().size() == 0) {
|
||||
@ -84,7 +84,7 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||
|
||||
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
|
||||
if (flag) {
|
||||
singleConstantParam = true;
|
||||
singleConstantParam = true;
|
||||
constructorType = node->getOp();
|
||||
size = node->getType().computeNumComponents();
|
||||
|
||||
@ -93,19 +93,19 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||
matrixCols = node->getType().getMatrixCols();
|
||||
matrixRows = node->getType().getMatrixRows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TIntermSequence::iterator p = node->getSequence().begin();
|
||||
for (TIntermSequence::iterator p = node->getSequence().begin();
|
||||
p != node->getSequence().end(); p++) {
|
||||
|
||||
if (node->getOp() == EOpComma)
|
||||
index = 0;
|
||||
index = 0;
|
||||
|
||||
(*p)->traverse(this);
|
||||
}
|
||||
if (flag)
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
singleConstantParam = false;
|
||||
singleConstantParam = false;
|
||||
constructorType = EOpNull;
|
||||
size = 0;
|
||||
isMatrix = false;
|
||||
@ -126,7 +126,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||
|
||||
if (! singleConstantParam) {
|
||||
int rightUnionSize = node->getType().computeNumComponents();
|
||||
|
||||
|
||||
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
||||
for (int i = 0; i < rightUnionSize; i++) {
|
||||
if (index >= instanceSize)
|
||||
@ -148,7 +148,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||
leftUnionArray[i] = rightUnionArray[count];
|
||||
|
||||
(index)++;
|
||||
|
||||
|
||||
if (nodeComps > 1)
|
||||
count++;
|
||||
}
|
||||
@ -180,13 +180,13 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||
return;
|
||||
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
|
||||
leftUnionArray[i] = rightUnionArray[count];
|
||||
else
|
||||
else
|
||||
leftUnionArray[i].setDConst(0.0);
|
||||
|
||||
index++;
|
||||
|
||||
if (nodeComps > 1)
|
||||
count++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,7 +199,7 @@ bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArra
|
||||
return false;
|
||||
|
||||
TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
|
||||
|
||||
|
||||
root->traverse(&it);
|
||||
if (it.error)
|
||||
return true;
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
@ -113,7 +113,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||
mac.emptyArgs = 1;
|
||||
do {
|
||||
token = scanToken(ppToken);
|
||||
if (mac.args.size() == 0 && token == ')')
|
||||
if (mac.args.size() == 0 && token == ')')
|
||||
break;
|
||||
if (token != PpAtomIdentifier) {
|
||||
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
|
||||
@ -177,7 +177,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||
newToken = ReadToken(mac.body, &newPpToken);
|
||||
if (oldToken != newToken || oldPpToken != newPpToken) {
|
||||
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
} while (newToken > 0);
|
||||
}
|
||||
@ -238,8 +238,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||
|
||||
int nextAtom = atomStrings.getAtom(ppToken->name);
|
||||
if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
|
||||
depth++;
|
||||
ifdepth++;
|
||||
depth++;
|
||||
ifdepth++;
|
||||
elsetracker++;
|
||||
} else if (nextAtom == PpAtomEndif) {
|
||||
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
|
||||
@ -247,7 +247,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||
--elsetracker;
|
||||
if (depth == 0) {
|
||||
// found the #endif we are looking for
|
||||
if (ifdepth)
|
||||
if (ifdepth)
|
||||
--ifdepth;
|
||||
break;
|
||||
}
|
||||
@ -461,7 +461,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
||||
|
||||
// Perform evaluation of binary operation, if there is one, otherwise we are done.
|
||||
while (! err) {
|
||||
if (token == ')' || token == '\n')
|
||||
if (token == ')' || token == '\n')
|
||||
break;
|
||||
int op;
|
||||
for (op = NUM_ELEMENTS(binop) - 1; op >= 0; op--) {
|
||||
@ -523,7 +523,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
|
||||
}
|
||||
|
||||
// Handle #if
|
||||
int TPpContext::CPPif(TPpToken* ppToken)
|
||||
int TPpContext::CPPif(TPpToken* ppToken)
|
||||
{
|
||||
int token = scanToken(ppToken);
|
||||
elsetracker++;
|
||||
@ -554,7 +554,7 @@ int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
|
||||
if (token != PpAtomIdentifier) {
|
||||
if (defined)
|
||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
|
||||
else
|
||||
else
|
||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
|
||||
} else {
|
||||
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
|
||||
@ -617,6 +617,7 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
||||
epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") <<
|
||||
"#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
||||
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
|
||||
// There's no "current" location anymore.
|
||||
parseContext.setCurrentColumn(0);
|
||||
} else {
|
||||
// things are okay, but there is nothing to process
|
||||
@ -635,7 +636,7 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
|
||||
}
|
||||
|
||||
// Handle #line
|
||||
int TPpContext::CPPline(TPpToken* ppToken)
|
||||
int TPpContext::CPPline(TPpToken* ppToken)
|
||||
{
|
||||
// "#line must have, after macro substitution, one of the following forms:
|
||||
// "#line line
|
||||
@ -693,7 +694,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||
}
|
||||
|
||||
// Handle #error
|
||||
int TPpContext::CPPerror(TPpToken* ppToken)
|
||||
int TPpContext::CPPerror(TPpToken* ppToken)
|
||||
{
|
||||
int token = scanToken(ppToken);
|
||||
std::string message;
|
||||
@ -870,7 +871,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||
if (elseSeen[elsetracker])
|
||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||
// this token is really a dont care, but we still need to eat the tokens
|
||||
token = scanToken(ppToken);
|
||||
token = scanToken(ppToken);
|
||||
while (token != '\n' && token != EndOfInput)
|
||||
token = scanToken(ppToken);
|
||||
token = CPPelse(0, ppToken);
|
||||
@ -1004,7 +1005,7 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
|
||||
return expandedArg;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Return the next token for a macro expansion, handling macro arguments,
|
||||
// whose semantics are dependent on being adjacent to ##.
|
||||
//
|
||||
@ -1113,7 +1114,7 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken)
|
||||
// Check a token to see if it is a macro that should be expanded.
|
||||
// If it is, and defined, push a tInput that will produce the appropriate expansion
|
||||
// and return 1.
|
||||
// If it is, but undefined, and expandUndef is requested, push a tInput that will
|
||||
// If it is, but undefined, and expandUndef is requested, push a tInput that will
|
||||
// expand to 0 and return -1.
|
||||
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
|
||||
//
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
@ -82,7 +82,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace glslang {
|
||||
|
||||
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
||||
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
||||
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
||||
rootFileName(rootFileName),
|
||||
currentSourceFile(rootFileName)
|
||||
|
@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
@ -94,7 +94,7 @@ class TPpToken {
|
||||
public:
|
||||
TPpToken() : space(false), ival(0), dval(0.0), i64val(0)
|
||||
{
|
||||
loc.init();
|
||||
loc.init();
|
||||
name[0] = 0;
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ protected:
|
||||
|
||||
static const int maxIfNesting = 64;
|
||||
|
||||
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
||||
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
||||
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
|
||||
int elsetracker; // #if-#else and #endif constructs...Counter.
|
||||
|
||||
@ -359,11 +359,11 @@ protected:
|
||||
int extraTokenCheck(int atom, TPpToken* ppToken, int token);
|
||||
int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
|
||||
int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
|
||||
int CPPif (TPpToken * ppToken);
|
||||
int CPPif (TPpToken * ppToken);
|
||||
int CPPifdef(int defined, TPpToken * ppToken);
|
||||
int CPPinclude(TPpToken * ppToken);
|
||||
int CPPline(TPpToken * ppToken);
|
||||
int CPPerror(TPpToken * ppToken);
|
||||
int CPPline(TPpToken * ppToken);
|
||||
int CPPerror(TPpToken * ppToken);
|
||||
int CPPpragma(TPpToken * ppToken);
|
||||
int CPPversion(TPpToken * ppToken);
|
||||
int CPPextension(TPpToken * ppToken);
|
||||
@ -383,7 +383,7 @@ protected:
|
||||
int ReadToken(TokenStream&, TPpToken*);
|
||||
void pushTokenStreamInput(TokenStream&, bool pasting = false);
|
||||
void UngetToken(int token, TPpToken*);
|
||||
|
||||
|
||||
class tTokenInput : public tInput {
|
||||
public:
|
||||
tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { }
|
||||
@ -441,7 +441,7 @@ protected:
|
||||
return '\\';
|
||||
} while (ch == '\\');
|
||||
}
|
||||
|
||||
|
||||
// handle any non-escaped newline
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
if (ch == '\r' && input->peek() == '\n')
|
||||
@ -486,7 +486,7 @@ protected:
|
||||
TInputScanner* input;
|
||||
};
|
||||
|
||||
// Holds a reference to included file data, as well as a
|
||||
// Holds a reference to included file data, as well as a
|
||||
// prologue and an epilogue string. This can be scanned using the tInput
|
||||
// interface and acts as a single source string.
|
||||
class TokenizableIncludeFile : public tInput {
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
@ -224,7 +224,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
||||
parseContext.ppError(ppToken->loc, "float literal too long", "", "");
|
||||
len = 1,str_len=1;
|
||||
}
|
||||
} else
|
||||
} else
|
||||
ungetChar();
|
||||
|
||||
str[len]='\0';
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
|
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
|
@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses
|
||||
express or implied, are granted by NVIDIA herein, including but not
|
||||
limited to any patent rights that may be infringed by your derivative
|
||||
works or by other works in which the NVIDIA Software may be
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
incorporated. No hardware is licensed hereunder.
|
||||
|
||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
@ -128,7 +128,7 @@ enum EFixedAtoms {
|
||||
#endif
|
||||
PpAtomConstString,
|
||||
|
||||
// Identifiers
|
||||
// Identifiers
|
||||
PpAtomIdentifier,
|
||||
|
||||
// preprocessor "keywords"
|
||||
|
@ -63,7 +63,6 @@
|
||||
// there wasn't exactly one entry point.
|
||||
//
|
||||
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
@ -355,7 +354,6 @@ public:
|
||||
return blockIndex;
|
||||
}
|
||||
|
||||
|
||||
// Are we at a level in a dereference chain at which individual active uniform queries are made?
|
||||
bool isReflectionGranularity(const TType& type)
|
||||
{
|
||||
@ -694,7 +692,6 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
|
||||
addAttribute(*base);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement TReflection methods.
|
||||
//
|
||||
|
@ -55,7 +55,7 @@ class TReflectionTraverser;
|
||||
// Data needed for just a single object at the granularity exchanged by the reflection API
|
||||
class TObjectReflection {
|
||||
public:
|
||||
TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
||||
TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
|
||||
name(pName), type(pType.clone()),
|
||||
offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex) { }
|
||||
|
||||
@ -107,7 +107,7 @@ public:
|
||||
|
||||
// for mapping a block index to the block's description
|
||||
int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
|
||||
const TObjectReflection& getUniformBlock(int i) const
|
||||
const TObjectReflection& getUniformBlock(int i) const
|
||||
{
|
||||
if (i >= 0 && i < (int)indexToUniformBlock.size())
|
||||
return indexToUniformBlock[i];
|
||||
@ -126,7 +126,7 @@ public:
|
||||
}
|
||||
|
||||
// for mapping any name to its index (block names, uniform names and attribute names)
|
||||
int getIndex(const char* name) const
|
||||
int getIndex(const char* name) const
|
||||
{
|
||||
TNameToIndex::const_iterator it = nameToIndex.find(name);
|
||||
if (it == nameToIndex.end())
|
||||
|
@ -51,122 +51,119 @@ namespace glslang {
|
||||
//
|
||||
|
||||
//
|
||||
// Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects
|
||||
// Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects
|
||||
// the cleanup routine to return void.
|
||||
//
|
||||
//
|
||||
static void DetachThreadLinux(void *)
|
||||
{
|
||||
DetachThread();
|
||||
DetachThread();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Registers cleanup handler, sets cancel type and state, and executes the thread specific
|
||||
// cleanup handler. This function will be called in the Standalone.cpp for regression
|
||||
// testing. When OpenGL applications are run with the driver code, Linux OS does the
|
||||
// cleanup handler. This function will be called in the Standalone.cpp for regression
|
||||
// testing. When OpenGL applications are run with the driver code, Linux OS does the
|
||||
// thread cleanup.
|
||||
//
|
||||
//
|
||||
void OS_CleanupThreadData(void)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
DetachThreadLinux(NULL);
|
||||
DetachThreadLinux(NULL);
|
||||
#else
|
||||
int old_cancel_state, old_cancel_type;
|
||||
void *cleanupArg = NULL;
|
||||
int old_cancel_state, old_cancel_type;
|
||||
void *cleanupArg = NULL;
|
||||
|
||||
//
|
||||
// Set thread cancel state and push cleanup handler.
|
||||
//
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
|
||||
pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
|
||||
//
|
||||
// Set thread cancel state and push cleanup handler.
|
||||
//
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
|
||||
pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
|
||||
|
||||
//
|
||||
// Put the thread in deferred cancellation mode.
|
||||
//
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
|
||||
//
|
||||
// Put the thread in deferred cancellation mode.
|
||||
//
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
|
||||
|
||||
//
|
||||
// Pop cleanup handler and execute it prior to unregistering the cleanup handler.
|
||||
//
|
||||
pthread_cleanup_pop(1);
|
||||
//
|
||||
// Pop cleanup handler and execute it prior to unregistering the cleanup handler.
|
||||
//
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
//
|
||||
// Restore the thread's previous cancellation mode.
|
||||
//
|
||||
pthread_setcanceltype(old_cancel_state, NULL);
|
||||
//
|
||||
// Restore the thread's previous cancellation mode.
|
||||
//
|
||||
pthread_setcanceltype(old_cancel_state, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Thread Local Storage Operations
|
||||
//
|
||||
inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key)
|
||||
{
|
||||
return (OS_TLSIndex)((uintptr_t)key + 1);
|
||||
return (OS_TLSIndex)((uintptr_t)key + 1);
|
||||
}
|
||||
|
||||
inline pthread_key_t TLSIndexToPthreadKey(OS_TLSIndex nIndex)
|
||||
{
|
||||
return (pthread_key_t)((uintptr_t)nIndex - 1);
|
||||
return (pthread_key_t)((uintptr_t)nIndex - 1);
|
||||
}
|
||||
|
||||
OS_TLSIndex OS_AllocTLSIndex()
|
||||
{
|
||||
pthread_key_t pPoolIndex;
|
||||
pthread_key_t pPoolIndex;
|
||||
|
||||
//
|
||||
// Create global pool key.
|
||||
//
|
||||
if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
|
||||
assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
|
||||
return OS_INVALID_TLS_INDEX;
|
||||
}
|
||||
else
|
||||
return PthreadKeyToTLSIndex(pPoolIndex);
|
||||
//
|
||||
// Create global pool key.
|
||||
//
|
||||
if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
|
||||
assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
|
||||
return OS_INVALID_TLS_INDEX;
|
||||
}
|
||||
else
|
||||
return PthreadKeyToTLSIndex(pPoolIndex);
|
||||
}
|
||||
|
||||
|
||||
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
|
||||
{
|
||||
if (nIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
|
||||
return false;
|
||||
}
|
||||
if (nIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void* OS_GetTLSValue(OS_TLSIndex nIndex)
|
||||
{
|
||||
//
|
||||
// This function should return 0 if nIndex is invalid.
|
||||
//
|
||||
assert(nIndex != OS_INVALID_TLS_INDEX);
|
||||
return pthread_getspecific(TLSIndexToPthreadKey(nIndex));
|
||||
//
|
||||
// This function should return 0 if nIndex is invalid.
|
||||
//
|
||||
assert(nIndex != OS_INVALID_TLS_INDEX);
|
||||
return pthread_getspecific(TLSIndexToPthreadKey(nIndex));
|
||||
}
|
||||
|
||||
bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
|
||||
{
|
||||
if (nIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
|
||||
return false;
|
||||
}
|
||||
if (nIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Delete the global pool key.
|
||||
//
|
||||
if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
//
|
||||
// Delete the global pool key.
|
||||
//
|
||||
if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
pthread_mutex_t gMutex;
|
||||
pthread_mutex_t gMutex;
|
||||
}
|
||||
|
||||
void InitGlobalLock()
|
||||
|
@ -77,7 +77,6 @@ OS_TLSIndex OS_AllocTLSIndex()
|
||||
return ToGenericTLSIndex(dwIndex);
|
||||
}
|
||||
|
||||
|
||||
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
|
||||
{
|
||||
if (nIndex == OS_INVALID_TLS_INDEX) {
|
||||
|
@ -165,9 +165,9 @@ typedef struct {
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
// managed, and de-allocated by the compiler/linker. It's contents
|
||||
// managed, and de-allocated by the compiler/linker. It's contents
|
||||
// are defined by and used by the compiler and linker. For example,
|
||||
// symbol table information and object code passed from the compiler
|
||||
// symbol table information and object code passed from the compiler
|
||||
// to the linker can be stored where ShHandle points.
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
@ -187,7 +187,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle);
|
||||
// The return value of ShCompile is boolean, non-zero indicating
|
||||
// success.
|
||||
//
|
||||
// The info-log should be written by ShCompile into
|
||||
// The info-log should be written by ShCompile into
|
||||
// ShHandle, so it can answer future queries.
|
||||
//
|
||||
SH_IMPORT_EXPORT int ShCompile(
|
||||
@ -251,8 +251,8 @@ SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char*
|
||||
// -----------------------------------
|
||||
//
|
||||
// Below is a new alternate C++ interface that might potentially replace the above
|
||||
// opaque handle-based interface.
|
||||
//
|
||||
// opaque handle-based interface.
|
||||
//
|
||||
// The below is further designed to handle multiple compilation units per stage, where
|
||||
// the intermediate results, including the parse tree, are preserved until link time,
|
||||
// rather than the above interface which is designed to have each compilation unit
|
||||
@ -513,7 +513,7 @@ public:
|
||||
const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib()
|
||||
int getAttributeType(int index) const; // can be used for glGetActiveAttrib()
|
||||
const TType* getUniformTType(int index) const; // returns a TType*
|
||||
const TType* getUniformBlockTType(int index) const; // returns a TType*
|
||||
const TType* getUniformBlockTType(int index) const; // returns a TType*
|
||||
const TType* getAttributeTType(int index) const; // returns a TType*
|
||||
|
||||
void dumpReflection();
|
||||
|
@ -95,7 +95,7 @@ namespace glslang {
|
||||
|
||||
if (attr != EatNone)
|
||||
attributes[attr] = value;
|
||||
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
@ -106,5 +106,5 @@ namespace glslang {
|
||||
|
||||
return (entry == attributes.end()) ? nullptr : entry->second;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -89,7 +89,7 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
|
||||
// they ARE still accepted as identifiers. This is not a dense space: e.g, "void" is not a
|
||||
// valid identifier, nor is "linear". This code special cases the known instances of this, so
|
||||
// e.g, "int sample;" or "float float;" is accepted. Other cases can be added here if needed.
|
||||
|
||||
|
||||
TString* idString = nullptr;
|
||||
switch (peek()) {
|
||||
case EHTokSample: idString = NewPoolTString("sample"); break;
|
||||
@ -146,7 +146,7 @@ bool HlslGrammar::acceptCompilationUnit()
|
||||
}
|
||||
|
||||
// sampler_state
|
||||
// : LEFT_BRACE [sampler_state_assignment ... ] RIGHT_BRACE
|
||||
// : LEFT_BRACE [sampler_state_assignment ... ] RIGHT_BRACE
|
||||
//
|
||||
// sampler_state_assignment
|
||||
// : sampler_state_identifier EQUAL value SEMICOLON
|
||||
@ -171,7 +171,7 @@ bool HlslGrammar::acceptSamplerState()
|
||||
return true;
|
||||
|
||||
parseContext.warn(token.loc, "unimplemented", "immediate sampler state", "");
|
||||
|
||||
|
||||
do {
|
||||
// read state name
|
||||
HlslToken state;
|
||||
@ -250,7 +250,7 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/)
|
||||
{
|
||||
if (! acceptTokenClass(EHTokSampler))
|
||||
return false;
|
||||
|
||||
|
||||
// TODO: remove this when DX9 style declarations are implemented.
|
||||
unimplemented("Direct3D 9 sampler declaration");
|
||||
|
||||
@ -269,7 +269,6 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// declaration
|
||||
// : sampler_declaration_dx9 post_decls SEMICOLON
|
||||
// | fully_specified_type declarator_list SEMICOLON
|
||||
@ -312,7 +311,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
||||
// be possible to simultaneously compile D3D10+ style shaders and DX9 shaders. If we want to compile DX9
|
||||
// HLSL shaders, this will have to be a master level switch
|
||||
// As such, the sampler keyword in D3D10+ turns into an automatic sampler type, and is commonly used
|
||||
// For that reason, this line is commented out
|
||||
// For that reason, this line is commented out
|
||||
|
||||
// if (acceptSamplerDeclarationDX9(declaredType))
|
||||
// return true;
|
||||
@ -352,7 +351,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
||||
if (declaredType.getQualifier().storage == EvqTemporary && parseContext.symbolTable.atGlobalLevel())
|
||||
declaredType.getQualifier().storage = EvqUniform;
|
||||
|
||||
// We can handle multiple variables per type declaration, so
|
||||
// We can handle multiple variables per type declaration, so
|
||||
// the number of types can expand when arrayness is different.
|
||||
TType variableType;
|
||||
variableType.shallowCopy(declaredType);
|
||||
@ -444,7 +443,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
||||
expected(";");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -620,13 +619,13 @@ bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||
qualifier.storage = EvqIn;
|
||||
if (!parseContext.handleInputGeometry(token.loc, ElgLinesAdjacency))
|
||||
return false;
|
||||
break;
|
||||
break;
|
||||
case EHTokTriangleAdj:
|
||||
qualifier.storage = EvqIn;
|
||||
if (!parseContext.handleInputGeometry(token.loc, ElgTrianglesAdjacency))
|
||||
return false;
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@ -813,7 +812,7 @@ bool HlslGrammar::acceptMatrixTemplateType(TType& type)
|
||||
expected(",");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// integer cols
|
||||
if (! peekTokenClass(EHTokIntConstant)) {
|
||||
expected("literal integer");
|
||||
@ -870,7 +869,7 @@ bool HlslGrammar::acceptStreamOutTemplateType(TType& type, TLayoutGeometry& geom
|
||||
|
||||
if (! acceptTokenClass(EHTokLeftAngle))
|
||||
return false;
|
||||
|
||||
|
||||
if (! acceptType(type)) {
|
||||
expected("stream output type");
|
||||
return false;
|
||||
@ -885,7 +884,7 @@ bool HlslGrammar::acceptStreamOutTemplateType(TType& type, TLayoutGeometry& geom
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// annotations
|
||||
// : LEFT_ANGLE declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE
|
||||
//
|
||||
@ -993,7 +992,7 @@ bool HlslGrammar::acceptTextureType(TType& type)
|
||||
case EHTokTexture1darray: dim = Esd1D; array = true; break;
|
||||
case EHTokTexture2d: dim = Esd2D; break;
|
||||
case EHTokTexture2darray: dim = Esd2D; array = true; break;
|
||||
case EHTokTexture3d: dim = Esd3D; break;
|
||||
case EHTokTexture3d: dim = Esd3D; break;
|
||||
case EHTokTextureCube: dim = EsdCube; break;
|
||||
case EHTokTextureCubearray: dim = EsdCube; array = true; break;
|
||||
case EHTokTexture2DMS: dim = Esd2D; ms = true; break;
|
||||
@ -1011,7 +1010,7 @@ bool HlslGrammar::acceptTextureType(TType& type)
|
||||
advanceToken(); // consume the texture object keyword
|
||||
|
||||
TType txType(EbtFloat, EvqUniform, 4); // default type is float4
|
||||
|
||||
|
||||
TIntermTyped* msCount = nullptr;
|
||||
|
||||
// texture type: required for multisample types and RWBuffer/RWTextures!
|
||||
@ -1092,14 +1091,13 @@ bool HlslGrammar::acceptTextureType(TType& type)
|
||||
|
||||
// Remember the declared vector size.
|
||||
sampler.vectorSize = txType.getVectorSize();
|
||||
|
||||
|
||||
type.shallowCopy(TType(sampler, EvqUniform, arraySizes));
|
||||
type.getQualifier().layoutFormat = format;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// If token is for a type, update 'type' with the type information,
|
||||
// and return true and advance.
|
||||
// Otherwise, return false, and don't advance
|
||||
@ -1133,7 +1131,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
|
||||
if (! parseContext.handleOutputGeometry(token.loc, geometry))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1261,7 +1259,6 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
new(&type) TType(EbtUint, EvqTemporary, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokBool:
|
||||
new(&type) TType(EbtBool);
|
||||
break;
|
||||
@ -1295,7 +1292,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
case EHTokHalf4:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokMin16float:
|
||||
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@ -1312,7 +1309,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
case EHTokMin16float4:
|
||||
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokMin10float:
|
||||
new(&type) TType(min10float_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@ -1329,7 +1326,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
case EHTokMin10float4:
|
||||
new(&type) TType(min10float_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokMin16int:
|
||||
new(&type) TType(min16int_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@ -1346,7 +1343,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
case EHTokMin16int4:
|
||||
new(&type) TType(min16int_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokMin12int:
|
||||
new(&type) TType(min12int_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@ -1363,7 +1360,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
case EHTokMin12int4:
|
||||
new(&type) TType(min12int_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
|
||||
case EHTokMin16uint:
|
||||
new(&type) TType(min16uint_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@ -1814,7 +1811,6 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// default_parameter_declaration
|
||||
// : EQUAL conditional_expression
|
||||
// : EQUAL initializer
|
||||
@ -1837,9 +1833,9 @@ bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTy
|
||||
return false;
|
||||
|
||||
TIntermTyped* arguments = nullptr;
|
||||
for (int i=0; i<int(node->getAsAggregate()->getSequence().size()); i++)
|
||||
for (int i = 0; i < int(node->getAsAggregate()->getSequence().size()); i++)
|
||||
parseContext.handleFunctionArgument(constructor, arguments, node->getAsAggregate()->getSequence()[i]->getAsTyped());
|
||||
|
||||
|
||||
node = parseContext.handleFunctionCall(token.loc, constructor, node);
|
||||
}
|
||||
|
||||
@ -2243,7 +2239,7 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
|
||||
|
||||
// peek for "op unary_expression"
|
||||
TOperator unaryOp = HlslOpMap::preUnary(peek());
|
||||
|
||||
|
||||
// postfix_expression (if no unary operator)
|
||||
if (unaryOp == EOpNull)
|
||||
return acceptPostfixExpression(node);
|
||||
@ -2299,7 +2295,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
|
||||
return false;
|
||||
}
|
||||
} else if (acceptLiteral(node)) {
|
||||
// literal (nothing else to do yet), go on to the
|
||||
// literal (nothing else to do yet), go on to the
|
||||
} else if (acceptConstructor(node)) {
|
||||
// constructor (nothing else to do yet)
|
||||
} else if (acceptIdentifier(idToken)) {
|
||||
@ -2703,7 +2699,7 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
|
||||
|
||||
TIntermTyped* node;
|
||||
bool expectingExpression = false;
|
||||
|
||||
|
||||
while (acceptAssignmentExpression(node)) {
|
||||
expectingExpression = false;
|
||||
expressions->getSequence().push_back(node);
|
||||
@ -2990,7 +2986,7 @@ bool HlslGrammar::acceptJumpStatement(TIntermNode*& statement)
|
||||
// SEMICOLON
|
||||
if (! acceptTokenClass(EHTokSemicolon))
|
||||
expected(";");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3086,7 +3082,7 @@ void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes)
|
||||
void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
|
||||
{
|
||||
do {
|
||||
// COLON
|
||||
// COLON
|
||||
if (acceptTokenClass(EHTokColon)) {
|
||||
HlslToken idToken;
|
||||
if (peekTokenClass(EHTokLayout))
|
||||
|
@ -44,7 +44,7 @@
|
||||
namespace glslang {
|
||||
|
||||
class TAttributeMap; // forward declare
|
||||
|
||||
|
||||
// Should just be the grammar aspect of HLSL.
|
||||
// Described in more detail in hlslGrammar.cpp.
|
||||
|
||||
|
@ -99,7 +99,7 @@ TOperator HlslOpMap::preUnary(EHlslTokenClass op)
|
||||
case EHTokDash: return EOpNegative;
|
||||
case EHTokBang: return EOpLogicalNot;
|
||||
case EHTokTilde: return EOpBitwiseNot;
|
||||
|
||||
|
||||
case EHTokIncOp: return EOpPreIncrement;
|
||||
case EHTokDecOp: return EOpPreDecrement;
|
||||
|
||||
@ -114,7 +114,7 @@ TOperator HlslOpMap::postUnary(EHlslTokenClass op)
|
||||
switch (op) {
|
||||
case EHTokDot: return EOpIndexDirectStruct;
|
||||
case EHTokLeftBracket: return EOpIndexIndirect;
|
||||
|
||||
|
||||
case EHTokIncOp: return EOpPostIncrement;
|
||||
case EHTokDecOp: return EOpPostDecrement;
|
||||
|
||||
|
@ -78,7 +78,7 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
|
||||
globalInputDefaults.clear();
|
||||
globalOutputDefaults.clear();
|
||||
|
||||
// "Shaders in the transform
|
||||
// "Shaders in the transform
|
||||
// feedback capturing mode have an initial global default of
|
||||
// layout(xfb_buffer = 0) out;"
|
||||
if (language == EShLangVertex ||
|
||||
@ -199,7 +199,7 @@ bool HlslParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, T
|
||||
|
||||
TIntermAggregate* lhsAsAggregate = node->getAsAggregate();
|
||||
TIntermTyped* object = lhsAsAggregate->getSequence()[0]->getAsTyped();
|
||||
|
||||
|
||||
if (!object->getType().getSampler().isImage()) {
|
||||
error(loc, "operator[] on a non-RW texture must be an r-value", "", "");
|
||||
return true;
|
||||
@ -217,7 +217,7 @@ bool HlslParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, T
|
||||
// series of other image operations.
|
||||
//
|
||||
// Most things are passed through unmodified, except for error checking.
|
||||
//
|
||||
//
|
||||
TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char* op, TIntermTyped* node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
@ -344,7 +344,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
lhsAsAggregate = lhsAsBinary->getLeft()->getAsAggregate();
|
||||
lhsIsSwizzle = true;
|
||||
}
|
||||
|
||||
|
||||
TIntermTyped* object = lhsAsAggregate->getSequence()[0]->getAsTyped();
|
||||
TIntermTyped* coord = lhsAsAggregate->getSequence()[1]->getAsTyped();
|
||||
|
||||
@ -402,7 +402,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
|
||||
TIntermSymbol* rhsTmp = rhs->getAsSymbolNode();
|
||||
TIntermTyped* coordTmp = coord;
|
||||
|
||||
|
||||
if (rhsTmp == nullptr || isModifyOp || lhsIsSwizzle) {
|
||||
rhsTmp = addTmpVar("storeTemp", objDerefType);
|
||||
|
||||
@ -422,7 +422,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
// rhsTmp op= rhs.
|
||||
makeBinary(assignOp, addSwizzle(intermediate.addSymbol(*rhsTmp), lhsAsBinary), rhs);
|
||||
}
|
||||
|
||||
|
||||
makeStore(object, coordTmp, rhsTmp); // add a store
|
||||
return finishSequence(rhsTmp, objDerefType); // return rhsTmp from sequence
|
||||
}
|
||||
@ -446,10 +446,10 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
// rhsTmp op
|
||||
// OpImageStore(object, coordTmp, rhsTmp)
|
||||
// rhsTmp
|
||||
|
||||
|
||||
TIntermSymbol* rhsTmp = addTmpVar("storeTemp", objDerefType);
|
||||
TIntermTyped* coordTmp = addTmpVar("coordTemp", coord->getType());
|
||||
|
||||
|
||||
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
|
||||
makeLoad(rhsTmp, object, coordTmp, objDerefType); // rhsTmp = OpImageLoad(object, coordTmp)
|
||||
makeUnary(assignOp, rhsTmp); // op rhsTmp
|
||||
@ -479,7 +479,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
makeStore(object, coordTmp, rhsTmp2); // OpImageStore(object, coordTmp, rhsTmp2)
|
||||
return finishSequence(rhsTmp1, objDerefType); // return rhsTmp from sequence
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -488,7 +488,7 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
|
||||
if (lhs)
|
||||
if (lValueErrorCheck(loc, op, lhs))
|
||||
return nullptr;
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -796,7 +796,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
|
||||
|
||||
//
|
||||
// methods can't be resolved until we later see the function-calling syntax.
|
||||
// Save away the name in the AST for now. Processing is completed in
|
||||
// Save away the name in the AST for now. Processing is completed in
|
||||
// handleLengthMethod(), etc.
|
||||
//
|
||||
if (field == "length") {
|
||||
@ -987,7 +987,7 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
|
||||
// We can ignore arrayness: it's uninvolved.
|
||||
if (type.isStruct()) {
|
||||
TTypeList* userStructure = type.getWritableStruct();
|
||||
|
||||
|
||||
// Get iterator to (now at end) set of builtin iterstage IO members
|
||||
const auto firstIo = std::stable_partition(userStructure->begin(), userStructure->end(),
|
||||
[](const TTypeLoc& t) {return !t.type->isBuiltInInterstageIO();});
|
||||
@ -1023,7 +1023,7 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
|
||||
// Determine whether we should flatten an arbitrary type.
|
||||
bool HlslParseContext::shouldFlatten(const TType& type) const
|
||||
{
|
||||
return shouldFlattenIO(type) || shouldFlattenUniform(type);
|
||||
return shouldFlattenIO(type) || shouldFlattenUniform(type);
|
||||
}
|
||||
|
||||
// Is this an IO variable that can't be passed down the stack?
|
||||
@ -1058,13 +1058,13 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
|
||||
const TType& type = variable.getType();
|
||||
|
||||
// emplace gives back a pair whose .first is an iterator to the item...
|
||||
auto entry = flattenMap.emplace(variable.getUniqueId(),
|
||||
auto entry = flattenMap.emplace(variable.getUniqueId(),
|
||||
TFlattenData(type.getQualifier().layoutBinding));
|
||||
|
||||
// ... and the item is a map pair, so first->second is the TFlattenData itself.
|
||||
flatten(loc, variable, type, entry.first->second, "");
|
||||
}
|
||||
|
||||
|
||||
// Recursively flatten the given variable at the provided type, building the flattenData as we go.
|
||||
//
|
||||
// This is mutually recursive with flattenStruct and flattenArray.
|
||||
@ -1109,8 +1109,8 @@ int HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable,
|
||||
|
||||
// Add a single flattened member to the flattened data being tracked for the composite
|
||||
// Returns true for the final flattening level.
|
||||
int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
|
||||
const TVariable& variable, const TType& type, TFlattenData& flattenData,
|
||||
int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
|
||||
const TVariable& variable, const TType& type, TFlattenData& flattenData,
|
||||
const TString& memberName, bool track)
|
||||
{
|
||||
if (isFinalFlattening(type)) {
|
||||
@ -1141,7 +1141,7 @@ int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
|
||||
// effecting a transfer of this information to the flattened variable form.
|
||||
//
|
||||
// Assumes shouldFlatten() or equivalent was called first.
|
||||
int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType& type,
|
||||
int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType& type,
|
||||
TFlattenData& flattenData, TString name)
|
||||
{
|
||||
assert(type.isStruct());
|
||||
@ -1171,7 +1171,7 @@ int HlslParseContext::flattenStruct(const TSourceLoc& loc, const TVariable& vari
|
||||
// equivalent set of individual variables.
|
||||
//
|
||||
// Assumes shouldFlatten() or equivalent was called first.
|
||||
int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType& type,
|
||||
int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType& type,
|
||||
TFlattenData& flattenData, TString name)
|
||||
{
|
||||
assert(type.isArray());
|
||||
@ -1190,7 +1190,7 @@ int HlslParseContext::flattenArray(const TSourceLoc& loc, const TVariable& varia
|
||||
int pos = start;
|
||||
flattenData.offsets.resize(int(pos + size), -1);
|
||||
|
||||
for (int element=0; element < size; ++element) {
|
||||
for (int element=0; element < size; ++element) {
|
||||
char elementNumBuf[20]; // sufficient for MAXINT
|
||||
snprintf(elementNumBuf, sizeof(elementNumBuf)-1, "[%d]", element);
|
||||
const int mpos = addFlattenedMember(loc, variable, dereferencedType, flattenData,
|
||||
@ -1216,7 +1216,6 @@ bool HlslParseContext::wasSplit(const TIntermTyped* node) const
|
||||
wasSplit(node->getAsSymbolNode()->getId());
|
||||
}
|
||||
|
||||
|
||||
// Turn an access into an aggregate that was flattened to instead be
|
||||
// an access to the individual variable the member was flattened to.
|
||||
// Assumes shouldFlatten() or equivalent was called first.
|
||||
@ -1299,7 +1298,6 @@ void HlslParseContext::splitAccessArray(const TSourceLoc& loc, TIntermTyped* bas
|
||||
builtInIoIndex = index;
|
||||
}
|
||||
|
||||
|
||||
// Turn an access into an struct that was split to instead be an
|
||||
// access to either the modified structure, or a direct reference to
|
||||
// one of the split member variables.
|
||||
@ -1436,7 +1434,6 @@ TFunction& HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFu
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
// Add interstage IO variables to the linkage in canonical order.
|
||||
void HlslParseContext::addInterstageIoToLinkage()
|
||||
{
|
||||
@ -1454,10 +1451,10 @@ void HlslParseContext::addInterstageIoToLinkage()
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing the function prototype in front of a function definition in the grammar.
|
||||
// Handle seeing the function prototype in front of a function definition in the grammar.
|
||||
// The body is handled after this function returns.
|
||||
//
|
||||
TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function,
|
||||
TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function,
|
||||
const TAttributeMap& attributes)
|
||||
{
|
||||
currentCaller = function.getMangledName();
|
||||
@ -1565,7 +1562,7 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
|
||||
const TIntermAggregate* numThreads = attributes[EatNumThreads];
|
||||
if (numThreads != nullptr) {
|
||||
const TIntermSequence& sequence = numThreads->getSequence();
|
||||
|
||||
|
||||
for (int lid = 0; lid < int(sequence.size()); ++lid)
|
||||
intermediate.setLocalSize(lid, sequence[lid]->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
}
|
||||
@ -1754,7 +1751,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
// 1. 1 item to copy: Use the RHS directly.
|
||||
// 2. >1 item, simple symbol RHS: we'll create a new TIntermSymbol node for each, but no assign to temp.
|
||||
// 3. >1 item, complex RHS: assign it to a new temp variable, and create a TIntermSymbol for each member.
|
||||
|
||||
|
||||
if (memberCount <= 1) {
|
||||
// case 1: we'll use the symbol directly below. Nothing to do.
|
||||
} else {
|
||||
@ -1857,7 +1854,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
// subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to
|
||||
// recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for
|
||||
// a bunch of memberwise copies.
|
||||
if (isFinalFlattening(typeL) || (!isFlattenLeft && !isFlattenRight &&
|
||||
if (isFinalFlattening(typeL) || (!isFlattenLeft && !isFlattenRight &&
|
||||
!typeL.containsBuiltInInterstageIO() && !typeR.containsBuiltInInterstageIO())) {
|
||||
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc);
|
||||
} else {
|
||||
@ -1910,7 +1907,7 @@ TOperator HlslParseContext::mapAtomicOp(const TSourceLoc& loc, TOperator op, boo
|
||||
case EOpInterlockedOr: return isImage ? EOpImageAtomicOr : EOpAtomicOr;
|
||||
case EOpInterlockedXor: return isImage ? EOpImageAtomicXor : EOpAtomicXor;
|
||||
case EOpInterlockedExchange: return isImage ? EOpImageAtomicExchange : EOpAtomicExchange;
|
||||
case EOpInterlockedCompareStore: // TODO: ...
|
||||
case EOpInterlockedCompareStore: // TODO: ...
|
||||
default:
|
||||
error(loc, "unknown atomic operation", "unknown op", "");
|
||||
return EOpNull;
|
||||
@ -2009,7 +2006,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
tex->getSequence().push_back(arg0); // sampler
|
||||
tex->getSequence().push_back(constructCoord); // coordinate
|
||||
tex->getSequence().push_back(bias); // bias
|
||||
|
||||
|
||||
node = clampReturn(tex, sampler);
|
||||
|
||||
break;
|
||||
@ -2054,7 +2051,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EOpMethodSampleGrad: // ...
|
||||
{
|
||||
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
|
||||
@ -2161,7 +2158,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
} else {
|
||||
indexedOut = sizeQueryReturn;
|
||||
}
|
||||
|
||||
|
||||
TIntermTyped* outParam = argAggregate->getSequence()[outParamBase + compNum]->getAsTyped();
|
||||
TIntermTyped* compAssign = intermediate.addAssign(EOpAssign, outParam, indexedOut, loc);
|
||||
|
||||
@ -2189,7 +2186,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
samplesQuery->getSequence().push_back(argTex);
|
||||
samplesQuery->setType(TType(EbtUint, EvqTemporary, 1));
|
||||
samplesQuery->setLoc(loc);
|
||||
|
||||
|
||||
TIntermTyped* compAssign = intermediate.addAssign(EOpAssign, outParam, samplesQuery, loc);
|
||||
compoundStatement = intermediate.growAggregate(compoundStatement, compAssign);
|
||||
}
|
||||
@ -2215,7 +2212,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
// optional offset value
|
||||
if (argAggregate->getSequence().size() > 4)
|
||||
argOffset = argAggregate->getSequence()[4]->getAsTyped();
|
||||
|
||||
|
||||
const int coordDimWithCmpVal = argCoord->getType().getVectorSize() + 1; // +1 for cmp
|
||||
|
||||
// AST wants comparison value as one of the texture coordinates
|
||||
@ -2342,12 +2339,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
TIntermTyped* argLod = argAggregate->getSequence()[3]->getAsTyped();
|
||||
TIntermTyped* argOffset = nullptr;
|
||||
const TSampler& sampler = argTex->getType().getSampler();
|
||||
|
||||
|
||||
const int numArgs = (int)argAggregate->getSequence().size();
|
||||
|
||||
if (numArgs == 5) // offset, if present
|
||||
argOffset = argAggregate->getSequence()[4]->getAsTyped();
|
||||
|
||||
|
||||
const TOperator textureOp = (argOffset == nullptr ? EOpTextureLod : EOpTextureLodOffset);
|
||||
TIntermAggregate* txsample = new TIntermAggregate(textureOp);
|
||||
|
||||
@ -2394,7 +2391,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EOpMethodGatherRed: // fall through...
|
||||
case EOpMethodGatherGreen: // ...
|
||||
case EOpMethodGatherBlue: // ...
|
||||
@ -2578,7 +2575,7 @@ void HlslParseContext::decomposeGeometryMethods(const TSourceLoc& loc, TIntermTy
|
||||
emit->setType(TType(EbtVoid));
|
||||
|
||||
sequence = intermediate.growAggregate(sequence,
|
||||
handleAssign(loc, EOpAssign,
|
||||
handleAssign(loc, EOpAssign,
|
||||
argAggregate->getSequence()[0]->getAsTyped(),
|
||||
argAggregate->getSequence()[1]->getAsTyped()),
|
||||
loc);
|
||||
@ -2638,7 +2635,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
|
||||
if (!decomposeHlslIntrinsics || !node || !node->getAsOperator())
|
||||
return;
|
||||
|
||||
|
||||
const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr;
|
||||
TIntermUnary* fnUnary = node->getAsUnaryNode();
|
||||
const TOperator op = node->getAsOperator()->getOp();
|
||||
@ -2735,7 +2732,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
arg0->getType().isVector()));
|
||||
|
||||
// calculate # of components for comparison const
|
||||
const int constComponentCount =
|
||||
const int constComponentCount =
|
||||
std::max(arg0->getType().getVectorSize(), 1) *
|
||||
std::max(arg0->getType().getMatrixCols(), 1) *
|
||||
std::max(arg0->getType().getMatrixRows(), 1);
|
||||
@ -2751,12 +2748,12 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
TIntermTyped* zero = intermediate.addConstantUnion(0, type0, loc, true);
|
||||
compareNode = handleBinaryMath(loc, "clip", EOpLessThan, arg0, zero);
|
||||
}
|
||||
|
||||
|
||||
TIntermBranch* killNode = intermediate.addBranch(EOpKill, loc);
|
||||
|
||||
node = new TIntermSelection(compareNode, killNode, nullptr);
|
||||
node->setLoc(loc);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2825,7 +2822,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
atomic->setType(arg0->getType());
|
||||
atomic->getWritableType().getQualifier().makeTemporary();
|
||||
atomic->setLoc(loc);
|
||||
|
||||
|
||||
if (isImage) {
|
||||
// orig_value = imageAtomicOp(image, loc, data)
|
||||
imageAtomicParams(atomic, arg0);
|
||||
@ -2876,7 +2873,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
atomic->getSequence().push_back(arg1);
|
||||
atomic->getSequence().push_back(arg2);
|
||||
node = intermediate.addAssign(EOpAssign, arg3, atomic, loc);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2902,7 +2899,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
intermediate.addConversion(EOpConstructFloat,
|
||||
TType(EbtFloat, EvqTemporary, 2), iU),
|
||||
recip16);
|
||||
|
||||
|
||||
TIntermAggregate* interp = new TIntermAggregate(EOpInterpolateAtOffset);
|
||||
interp->getSequence().push_back(arg0);
|
||||
interp->getSequence().push_back(floatOffset);
|
||||
@ -2946,7 +2943,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
TIntermTyped* n_dot_h_m = handleBinaryMath(loc, "mul", EOpMul, n_dot_h, m); // n_dot_h * m
|
||||
|
||||
dst->getSequence().push_back(intermediate.addSelection(compare, zero, n_dot_h_m, loc));
|
||||
|
||||
|
||||
// One:
|
||||
dst->getSequence().push_back(intermediate.addConstantUnion(1.0, EbtFloat, loc, true));
|
||||
|
||||
@ -2981,10 +2978,10 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
convert->setLoc(loc);
|
||||
convert->setType(TType(EbtDouble, EvqTemporary));
|
||||
node = convert;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EOpF16tof32:
|
||||
case EOpF32tof16:
|
||||
{
|
||||
@ -3100,7 +3097,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
||||
|
||||
// for decompositions, since we want to operate on the function node, not the aggregate holding
|
||||
// output conversions.
|
||||
const TIntermTyped* fnNode = result;
|
||||
const TIntermTyped* fnNode = result;
|
||||
|
||||
decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions
|
||||
decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
|
||||
@ -3131,7 +3128,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
||||
}
|
||||
|
||||
// Finish processing object.length(). This started earlier in handleDotDereference(), where
|
||||
// the ".length" part was recognized and semantically checked, and finished here where the
|
||||
// the ".length" part was recognized and semantically checked, and finished here where the
|
||||
// function syntax "()" is recognized.
|
||||
//
|
||||
// Return resulting tree node.
|
||||
@ -3211,7 +3208,7 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
|
||||
// object itself.
|
||||
TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type);
|
||||
internalAggregate->getWritableType().getQualifier().makeTemporary();
|
||||
TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
|
||||
TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
|
||||
internalAggregate->getName(),
|
||||
internalAggregate->getType());
|
||||
internalSymbolNode->setLoc(arg->getLoc());
|
||||
@ -3503,8 +3500,7 @@ void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, con
|
||||
// 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")
|
||||
@ -3592,7 +3588,7 @@ void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, con
|
||||
else if( semanticUpperCase == "SV_COVERAGE")
|
||||
qualifier.builtIn = EbvSampleMask;
|
||||
|
||||
//TODO, these need to get refined to be more specific
|
||||
//TODO, these need to get refined to be more specific
|
||||
else if( semanticUpperCase == "SV_DEPTHGREATEREQUAL")
|
||||
qualifier.builtIn = EbvFragDepthGreater;
|
||||
else if( semanticUpperCase == "SV_DEPTHLESSEQUAL")
|
||||
@ -3794,7 +3790,6 @@ void HlslParseContext::globalCheck(const TSourceLoc& loc, const char* token)
|
||||
error(loc, "not allowed in nested scope", token, "");
|
||||
}
|
||||
|
||||
|
||||
bool HlslParseContext::builtInName(const TString& /*identifier*/)
|
||||
{
|
||||
return false;
|
||||
@ -4666,9 +4661,9 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua
|
||||
qualifier.layoutComponent = value;
|
||||
return;
|
||||
} else if (id.compare(0, 4, "xfb_") == 0) {
|
||||
// "Any shader making any static use (after preprocessing) of any of these
|
||||
// *xfb_* qualifiers will cause the shader to be in a transform feedback
|
||||
// capturing mode and hence responsible for describing the transform feedback
|
||||
// "Any shader making any static use (after preprocessing) of any of these
|
||||
// *xfb_* qualifiers will cause the shader to be in a transform feedback
|
||||
// capturing mode and hence responsible for describing the transform feedback
|
||||
// setup."
|
||||
intermediate.setXfbMode();
|
||||
if (id == "xfb_buffer") {
|
||||
@ -4688,7 +4683,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua
|
||||
qualifier.layoutXfbOffset = value;
|
||||
return;
|
||||
} else if (id == "xfb_stride") {
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
||||
if (value > 4 * resources.maxTransformFeedbackInterleavedComponents)
|
||||
error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents);
|
||||
@ -4815,17 +4810,17 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua
|
||||
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone
|
||||
//
|
||||
// "More than one layout qualifier may appear in a single declaration.
|
||||
// Additionally, the same layout-qualifier-name can occur multiple times
|
||||
// within a layout qualifier or across multiple layout qualifiers in the
|
||||
// same declaration. When the same layout-qualifier-name occurs
|
||||
// multiple times, in a single declaration, the last occurrence overrides
|
||||
// the former occurrence(s). Further, if such a layout-qualifier-name
|
||||
// will effect subsequent declarations or other observable behavior, it
|
||||
// is only the last occurrence that will have any effect, behaving as if
|
||||
// the earlier occurrence(s) within the declaration are not present.
|
||||
// This is also true for overriding layout-qualifier-names, where one
|
||||
// overrides the other (e.g., row_major vs. column_major); only the last
|
||||
// occurrence has any effect."
|
||||
// Additionally, the same layout-qualifier-name can occur multiple times
|
||||
// within a layout qualifier or across multiple layout qualifiers in the
|
||||
// same declaration. When the same layout-qualifier-name occurs
|
||||
// multiple times, in a single declaration, the last occurrence overrides
|
||||
// the former occurrence(s). Further, if such a layout-qualifier-name
|
||||
// will effect subsequent declarations or other observable behavior, it
|
||||
// is only the last occurrence that will have any effect, behaving as if
|
||||
// the earlier occurrence(s) within the declaration are not present.
|
||||
// This is also true for overriding layout-qualifier-names, where one
|
||||
// overrides the other (e.g., row_major vs. column_major); only the last
|
||||
// occurrence has any effect."
|
||||
//
|
||||
void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
|
||||
{
|
||||
@ -4880,7 +4875,7 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
|
||||
// Look up a function name in the symbol table, and make sure it is a function.
|
||||
//
|
||||
// First, look for an exact match. If there is none, use the generic selector
|
||||
// TParseContextBase::selectFunction() to find one, parameterized by the
|
||||
// TParseContextBase::selectFunction() to find one, parameterized by the
|
||||
// convertible() and better() predicates defined below.
|
||||
//
|
||||
// Return the function symbol if found, otherwise nullptr.
|
||||
@ -4905,7 +4900,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
// create list of candidates to send
|
||||
TVector<const TFunction*> candidateList;
|
||||
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
|
||||
|
||||
|
||||
// These builtin ops can accept any type, so we bypass the argument selection
|
||||
if (candidateList.size() == 1 && builtIn &&
|
||||
(candidateList[0]->getBuiltInOp() == EOpMethodAppend ||
|
||||
@ -4922,7 +4917,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
return true;
|
||||
|
||||
// no aggregate conversions
|
||||
if (from.isArray() || to.isArray() ||
|
||||
if (from.isArray() || to.isArray() ||
|
||||
from.isStruct() || to.isStruct())
|
||||
return false;
|
||||
|
||||
@ -4939,7 +4934,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
// We do not promote the texture or image type for these ocodes. Normally that would not
|
||||
// be an issue because it's a buffer, but we haven't decomposed the opcode yet, and at this
|
||||
// stage it's merely e.g, a basic integer type.
|
||||
//
|
||||
//
|
||||
// Instead, we want to promote other arguments, but stay within the same family. In other
|
||||
// words, InterlockedAdd(RWBuffer<int>, ...) will always use the int flavor, never the uint flavor,
|
||||
// but it is allowed to promote its other arguments.
|
||||
@ -5030,7 +5025,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
|
||||
// for ambiguity reporting
|
||||
bool tie = false;
|
||||
|
||||
|
||||
// send to the generic selector
|
||||
const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
|
||||
|
||||
@ -5131,7 +5126,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
|
||||
//
|
||||
// Do everything necessary to handle a typedef declaration, for a single symbol.
|
||||
//
|
||||
//
|
||||
// 'parseType' is the type part of the declaration (to the left)
|
||||
// 'arraySizes' is the arrayness tagged on the identifier (to the right)
|
||||
//
|
||||
@ -5798,9 +5793,9 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS
|
||||
error(memberLoc, "member cannot contradict block", "stream", "");
|
||||
}
|
||||
|
||||
// "This includes a block's inheritance of the
|
||||
// current global default buffer, a block member's inheritance of the block's
|
||||
// buffer, and the requirement that any *xfb_buffer* declared on a block
|
||||
// "This includes a block's inheritance of the
|
||||
// current global default buffer, a block member's inheritance of the block's
|
||||
// buffer, and the requirement that any *xfb_buffer* declared on a block
|
||||
// member must match the buffer inherited from the block."
|
||||
if (memberQualifier.hasXfbBuffer()) {
|
||||
if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
|
||||
@ -5877,15 +5872,15 @@ void HlslParseContext::finalizeGlobalUniformBlockLayout(TVariable& block)
|
||||
}
|
||||
|
||||
//
|
||||
// "For a block, this process applies to the entire block, or until the first member
|
||||
// is reached that has a location layout qualifier. When a block member is declared with a location
|
||||
// "For a block, this process applies to the entire block, or until the first member
|
||||
// is reached that has a location layout qualifier. When a block member is declared with a location
|
||||
// qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
|
||||
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
|
||||
// until the next member declared with a location qualifier. The values used for locations do not have to be
|
||||
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
|
||||
// until the next member declared with a location qualifier. The values used for locations do not have to be
|
||||
// declared in increasing order."
|
||||
void HlslParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
|
||||
{
|
||||
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members
|
||||
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members
|
||||
// have a location layout qualifier, or a compile-time error results."
|
||||
if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
|
||||
error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
|
||||
@ -5921,9 +5916,9 @@ void HlslParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qual
|
||||
|
||||
void HlslParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
|
||||
{
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
// members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
|
||||
// "If a block is qualified with xfb_offset, all its
|
||||
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
|
||||
// members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
|
||||
// offsets."
|
||||
|
||||
if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
|
||||
@ -5950,10 +5945,10 @@ void HlslParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& type
|
||||
qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
|
||||
}
|
||||
|
||||
// Calculate and save the offset of each block member, using the recursively
|
||||
// Calculate and save the offset of each block member, using the recursively
|
||||
// defined block offset rules and the user-provided offset and align.
|
||||
//
|
||||
// Also, compute and save the total size of the block. For the block's size, arrayness
|
||||
// Also, compute and save the total size of the block. For the block's size, arrayness
|
||||
// is not taken into account, as each element is backed by a separate buffer.
|
||||
//
|
||||
void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TTypeList& typeList)
|
||||
@ -5979,25 +5974,25 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor
|
||||
: qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (memberQualifier.hasOffset()) {
|
||||
// "The specified offset must be a multiple
|
||||
// "The specified offset must be a multiple
|
||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
|
||||
|
||||
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||
// "The actual offset of a member is computed as
|
||||
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||
// "The actual offset of a member is computed as
|
||||
// follows: If offset was declared, start with that offset, otherwise start with the next available offset."
|
||||
offset = std::max(offset, memberQualifier.layoutOffset);
|
||||
}
|
||||
|
||||
// "The actual alignment of a member will be the greater of the specified align alignment and the standard
|
||||
// "The actual alignment of a member will be the greater of the specified align alignment and the standard
|
||||
// (e.g., std140) base alignment for the member's type."
|
||||
if (memberQualifier.hasAlign())
|
||||
memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
|
||||
|
||||
// "If the resulting offset is not a multiple of the actual alignment,
|
||||
// increase it to the first offset that is a multiple of
|
||||
// increase it to the first offset that is a multiple of
|
||||
// the actual alignment."
|
||||
RoundToPow2(offset, memberAlignment);
|
||||
typeList[member].type->getQualifier().layoutOffset = offset;
|
||||
@ -6288,5 +6283,4 @@ void HlslParseContext::finish()
|
||||
TParseContextBase::finish();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -286,7 +286,7 @@ protected:
|
||||
// * note, that appropriately gives an error if redeclaring a block that
|
||||
// was already used and hence already copied-up
|
||||
//
|
||||
// - on seeing a layout declaration that sizes the array, fix everything in the
|
||||
// - on seeing a layout declaration that sizes the array, fix everything in the
|
||||
// resize-list, giving errors for mismatch
|
||||
//
|
||||
// - on seeing an array size declaration, give errors on mismatch between it and previous
|
||||
|
@ -34,7 +34,7 @@
|
||||
//
|
||||
|
||||
//
|
||||
// Create strings that declare built-in definitions, add built-ins programmatically
|
||||
// Create strings that declare built-in definitions, add built-ins programmatically
|
||||
// that cannot be expressed in the strings, and establish mappings between
|
||||
// built-in functions and operators.
|
||||
//
|
||||
@ -102,14 +102,14 @@ bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool isGather =
|
||||
(name == "Gather" ||
|
||||
const bool isGather =
|
||||
(name == "Gather" ||
|
||||
name == "GatherRed" ||
|
||||
name == "GatherGreen" ||
|
||||
name == "GatherGreen" ||
|
||||
name == "GatherBlue" ||
|
||||
name == "GatherAlpha");
|
||||
|
||||
const bool isGatherCmp =
|
||||
const bool isGatherCmp =
|
||||
(name == "GatherCmpRed" ||
|
||||
name == "GatherCmpGreen" ||
|
||||
name == "GatherCmpBlue" ||
|
||||
@ -174,7 +174,7 @@ const char* IoParam(glslang::TString& s, const char* nthArgOrder)
|
||||
} else if (*nthArgOrder == '<') { // input params
|
||||
++nthArgOrder;
|
||||
s.append("in ");
|
||||
}
|
||||
}
|
||||
|
||||
return nthArgOrder;
|
||||
}
|
||||
@ -195,9 +195,8 @@ inline bool IsEndOfArg(const char* arg)
|
||||
return arg == nullptr || *arg == '\0' || *arg == ',';
|
||||
}
|
||||
|
||||
|
||||
// If this is a fixed vector size, such as V3, return the size. Else return 0.
|
||||
int FixedVecSize(const char* arg)
|
||||
int FixedVecSize(const char* arg)
|
||||
{
|
||||
while (!IsEndOfArg(arg)) {
|
||||
if (isdigit(*arg))
|
||||
@ -208,7 +207,6 @@ int FixedVecSize(const char* arg)
|
||||
return 0; // none found.
|
||||
}
|
||||
|
||||
|
||||
// Create and return a type name. This is done in GLSL, not HLSL conventions, until such
|
||||
// time as builtins are parsed using the HLSL parser.
|
||||
//
|
||||
@ -229,7 +227,7 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
|
||||
char type = *argType;
|
||||
|
||||
if (isTranspose) { // Take transpose of matrix dimensions
|
||||
std::swap(dim0, dim1);
|
||||
std::swap(dim0, dim1);
|
||||
} else if (isTexture) {
|
||||
if (type == 'F') // map base type to texture of that type.
|
||||
type = 'T'; // e.g, int -> itexture, uint -> utexture, etc.
|
||||
@ -255,10 +253,10 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
|
||||
case 'S': s += "sampler"; break;
|
||||
case 's': s += "SamplerComparisonState"; break;
|
||||
case 'T': s += ((isBuffer && isImage) ? "RWBuffer" :
|
||||
isBuffer ? "Buffer" :
|
||||
isBuffer ? "Buffer" :
|
||||
isImage ? "RWTexture" : "Texture"); break;
|
||||
case 'i': s += ((isBuffer && isImage) ? "RWBuffer" :
|
||||
isBuffer ? "Buffer" :
|
||||
isBuffer ? "Buffer" :
|
||||
isImage ? "RWTexture" : "Texture"); break;
|
||||
case 'u': s += ((isBuffer && isImage) ? "RWBuffer" :
|
||||
isBuffer ? "Buffer" :
|
||||
@ -322,7 +320,7 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
|
||||
case 'V':
|
||||
s += ('0' + char(dim0));
|
||||
break;
|
||||
case 'M':
|
||||
case 'M':
|
||||
s += ('0' + char(dim0));
|
||||
s += 'x';
|
||||
s += ('0' + char(dim1));
|
||||
@ -389,7 +387,6 @@ inline bool IsValid(const char* cname, char retOrder, char retType, char argOrde
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// return position of end of argument specifier
|
||||
inline const char* FindEndOfArg(const char* arg)
|
||||
{
|
||||
@ -424,7 +421,7 @@ inline void FindVectorMatrixBounds(const char* argOrder, int fixedVecSize, int&
|
||||
if (fixedVecSize > 0) // handle fixed sized vectors
|
||||
dim0Min = dim0Max = fixedVecSize;
|
||||
}
|
||||
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace glslang {
|
||||
@ -433,7 +430,6 @@ TBuiltInParseablesHlsl::TBuiltInParseablesHlsl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handle creation of mat*mat specially, since it doesn't fall conveniently out of
|
||||
// the generic prototype creation code below.
|
||||
@ -476,7 +472,6 @@ void TBuiltInParseablesHlsl::createMatTimesMat()
|
||||
|
||||
s.append(");\n"); // close paren
|
||||
|
||||
|
||||
// Create V*M
|
||||
AppendTypeName(s, "V", "F", xCols, 1); // add return type
|
||||
s.append(" "); // space between type and name
|
||||
@ -508,7 +503,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
// needed for furture validation. For now, they are commented out, and set below
|
||||
// to EShLangAll, to allow any intrinsic to be used in any shader, which is legal
|
||||
// if it is not called.
|
||||
//
|
||||
//
|
||||
// static const EShLanguageMask EShLangPSCS = EShLanguageMask(EShLangFragmentMask | EShLangComputeMask);
|
||||
// static const EShLanguageMask EShLangVSPSGS = EShLanguageMask(EShLangVertexMask | EShLangFragmentMask | EShLangGeometryMask);
|
||||
// static const EShLanguageMask EShLangCS = EShLangComputeMask;
|
||||
@ -745,7 +740,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
|
||||
{ "GetSamplePosition", "V2", "F", "$&2,S", "FUI,I", EShLangVSPSGS },
|
||||
|
||||
//
|
||||
//
|
||||
// UINT Width
|
||||
// UINT MipLevel, UINT Width, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 1D */ "-", "-", "%!~1,>S", "FUI,U", EShLangAll },
|
||||
@ -947,7 +942,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
|
||||
AppendTypeName(s, nthArgOrder, nthArgType, argDim0, dim1); // Add arguments
|
||||
}
|
||||
|
||||
|
||||
s.append(");\n"); // close paren and trailing semicolon
|
||||
} // dim 1 loop
|
||||
} // dim 0 loop
|
||||
@ -956,10 +951,10 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
// skip over special characters
|
||||
if (isTexture && isalpha(argOrder[1]))
|
||||
++argOrder;
|
||||
if (isdigit(argOrder[1]))
|
||||
if (isdigit(argOrder[1]))
|
||||
++argOrder;
|
||||
} // arg order loop
|
||||
|
||||
|
||||
if (intrinsic.stage == EShLangAll) // common builtins are only added once.
|
||||
break;
|
||||
}
|
||||
@ -988,7 +983,6 @@ void TBuiltInParseablesHlsl::initialize(const TBuiltInResource& /*resources*/, i
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Finish adding/processing context-independent built-in symbols.
|
||||
// 1) Programmatically add symbols that could not be added by simple text strings above.
|
||||
@ -1167,7 +1161,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
|
||||
|
||||
//
|
||||
// Add context-dependent (resource-specific) built-ins not handled by the above. These
|
||||
// would be ones that need to be programmatically added because they cannot
|
||||
// would be ones that need to be programmatically added because they cannot
|
||||
// be added by simple text strings. For these, also
|
||||
// 1) Map built-in functions to operators, for those that will turn into an operation node
|
||||
// instead of remaining a function call.
|
||||
@ -1179,5 +1173,4 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage);
|
||||
|
||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
|
||||
|
||||
|
||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
||||
|
||||
private:
|
||||
|
@ -52,7 +52,7 @@
|
||||
// preprocessor includes
|
||||
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
|
||||
#include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct str_eq
|
||||
@ -142,7 +142,7 @@ void HlslScanContext::fillInKeywordMap()
|
||||
(*KeywordMap)["half"] = EHTokHalf;
|
||||
(*KeywordMap)["float"] = EHTokFloat;
|
||||
(*KeywordMap)["double"] = EHTokDouble;
|
||||
(*KeywordMap)["min16float"] = EHTokMin16float;
|
||||
(*KeywordMap)["min16float"] = EHTokMin16float;
|
||||
(*KeywordMap)["min10float"] = EHTokMin10float;
|
||||
(*KeywordMap)["min16int"] = EHTokMin16int;
|
||||
(*KeywordMap)["min12int"] = EHTokMin12int;
|
||||
@ -316,7 +316,6 @@ void HlslScanContext::fillInKeywordMap()
|
||||
(*KeywordMap)["RWTexture3D"] = EHTokRWTexture3d;
|
||||
(*KeywordMap)["RWBuffer"] = EHTokRWBuffer;
|
||||
|
||||
|
||||
(*KeywordMap)["struct"] = EHTokStruct;
|
||||
(*KeywordMap)["cbuffer"] = EHTokCBuffer;
|
||||
(*KeywordMap)["tbuffer"] = EHTokTBuffer;
|
||||
@ -340,7 +339,7 @@ void HlslScanContext::fillInKeywordMap()
|
||||
|
||||
// TODO: get correct set here
|
||||
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
||||
|
||||
|
||||
ReservedSet->insert("auto");
|
||||
ReservedSet->insert("catch");
|
||||
ReservedSet->insert("char");
|
||||
|
@ -251,7 +251,6 @@ enum EHlslTokenClass {
|
||||
EHTokRWTexture2darray,
|
||||
EHTokRWTexture3d,
|
||||
EHTokRWBuffer,
|
||||
|
||||
|
||||
// variable, user type, ...
|
||||
EHTokIdentifier,
|
||||
|
Loading…
Reference in New Issue
Block a user