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