mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated glslang.
This commit is contained in:
11
3rdparty/glslang/CHANGES.md
vendored
11
3rdparty/glslang/CHANGES.md
vendored
@@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## 11.6.0 2021-08-25
|
||||
|
||||
### Other changes
|
||||
* Atomic memory function only for shader storage block member or shared variable
|
||||
* Add support for gl_MaxVaryingVectors for ogl
|
||||
* Fix loading bool arrays from interface blocks
|
||||
* Generate separate stores for partially swizzled memory stores
|
||||
* Allow layout(std430) uniform with GL_EXT_scalar_block_layout
|
||||
* Support for pragma STDGL invariant(all)
|
||||
* Support for GL_NV_ray_tracing_motion_blur
|
||||
|
||||
## 11.5.0 2021-06-23
|
||||
|
||||
### Other changes
|
||||
|
||||
18
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
18
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@@ -3384,7 +3384,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
const auto& spirvInst = node->getSpirvInstruction();
|
||||
if (spirvInst.set == "") {
|
||||
std::vector<spv::IdImmediate> idImmOps;
|
||||
for (int i = 0; i < glslangOperands.size(); ++i) {
|
||||
for (unsigned int i = 0; i < glslangOperands.size(); ++i) {
|
||||
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||
// Translate the constant to a literal value
|
||||
std::vector<unsigned> literals;
|
||||
@@ -3940,12 +3940,14 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
|
||||
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
return builder.makeFloatType(16);
|
||||
case glslang::EbtInt64: return builder.makeIntType(64);
|
||||
case glslang::EbtInt64:
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
case glslang::EbtUint64: return builder.makeUintType(64);
|
||||
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||
return builder.makeIntType(64);
|
||||
case glslang::EbtUint64:
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||
return builder.makeUintType(64);
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
@@ -7506,6 +7508,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
|
||||
break;
|
||||
case glslang::EOpReadFirstInvocation:
|
||||
opCode = spv::OpSubgroupFirstInvocationKHR;
|
||||
if (builder.isVectorType(typeId))
|
||||
return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
|
||||
break;
|
||||
case glslang::EOpBallot:
|
||||
{
|
||||
@@ -7630,7 +7634,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
|
||||
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
|
||||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
|
||||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
|
||||
op == spv::OpSubgroupReadInvocationKHR ||
|
||||
op == spv::OpSubgroupReadInvocationKHR || op == spv::OpSubgroupFirstInvocationKHR ||
|
||||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
|
||||
op == spv::OpGroupSMinNonUniformAMD ||
|
||||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
|
||||
@@ -7659,6 +7663,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
|
||||
spvGroupOperands.push_back(scalar);
|
||||
spv::IdImmediate operand = { true, operands[1] };
|
||||
spvGroupOperands.push_back(operand);
|
||||
} else if (op == spv::OpSubgroupFirstInvocationKHR) {
|
||||
spvGroupOperands.push_back(scalar);
|
||||
} else if (op == spv::OpGroupBroadcast) {
|
||||
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
||||
spvGroupOperands.push_back(scope);
|
||||
|
||||
2
3rdparty/glslang/build_info.h
vendored
2
3rdparty/glslang/build_info.h
vendored
@@ -35,7 +35,7 @@
|
||||
#define GLSLANG_BUILD_INFO
|
||||
|
||||
#define GLSLANG_VERSION_MAJOR 11
|
||||
#define GLSLANG_VERSION_MINOR 5
|
||||
#define GLSLANG_VERSION_MINOR 6
|
||||
#define GLSLANG_VERSION_PATCH 0
|
||||
#define GLSLANG_VERSION_FLAVOR ""
|
||||
|
||||
|
||||
@@ -4017,12 +4017,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
txsample->getSequence().push_back(txcombine);
|
||||
txsample->getSequence().push_back(argCoord);
|
||||
|
||||
if (argBias != nullptr)
|
||||
txsample->getSequence().push_back(argBias);
|
||||
|
||||
if (argOffset != nullptr)
|
||||
txsample->getSequence().push_back(argOffset);
|
||||
|
||||
if (argBias != nullptr)
|
||||
txsample->getSequence().push_back(argBias);
|
||||
|
||||
node = convertReturn(txsample, sampler);
|
||||
|
||||
break;
|
||||
|
||||
@@ -665,8 +665,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
{ "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS, true },
|
||||
{ "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS, true },
|
||||
|
||||
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS, true },
|
||||
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS, true },
|
||||
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,F", EShLangPS, true },
|
||||
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,F,I", EShLangPS, true },
|
||||
|
||||
// TODO: FXC accepts int/uint samplers here. unclear what that means.
|
||||
{ "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS, true },
|
||||
|
||||
4
3rdparty/glslang/glslang/Include/Common.h
vendored
4
3rdparty/glslang/glslang/Include/Common.h
vendored
@@ -62,7 +62,7 @@ std::string to_string(const T& val) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
|
||||
#include <basetsd.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf sprintf_s
|
||||
@@ -214,7 +214,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
|
||||
//
|
||||
// Create a TString object from an integer.
|
||||
//
|
||||
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
|
||||
#if defined _MSC_VER || MINGW_HAS_SECURE_API
|
||||
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
|
||||
|
||||
10
3rdparty/glslang/glslang/Include/Types.h
vendored
10
3rdparty/glslang/glslang/Include/Types.h
vendored
@@ -741,6 +741,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool isUniform() const
|
||||
{
|
||||
switch (storage) {
|
||||
case EvqUniform:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isIo() const
|
||||
{
|
||||
switch (storage) {
|
||||
|
||||
@@ -1643,6 +1643,7 @@ public:
|
||||
~TIntermAggregate() { delete pragmaTable; }
|
||||
virtual TIntermAggregate* getAsAggregate() { return this; }
|
||||
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
||||
virtual void updatePrecision();
|
||||
virtual void setOperator(TOperator o) { op = o; }
|
||||
virtual TIntermSequence& getSequence() { return sequence; }
|
||||
virtual const TIntermSequence& getSequence() const { return sequence; }
|
||||
|
||||
@@ -531,7 +531,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||
// Note: avoid UBSAN error regarding negating 0x80000000
|
||||
case EbtInt: newConstArray[i].setIConst(
|
||||
unionArray[i].getIConst() == 0x80000000
|
||||
static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
|
||||
? -0x7FFFFFFF - 1
|
||||
: -unionArray[i].getIConst());
|
||||
break;
|
||||
|
||||
@@ -7701,6 +7701,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
|
||||
symQualifier.builtIn = builtIn;
|
||||
}
|
||||
|
||||
static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
|
||||
{
|
||||
symbolTable.retargetSymbol(from, to);
|
||||
}
|
||||
|
||||
//
|
||||
// For built-in variables inside a named block.
|
||||
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
|
||||
@@ -7768,8 +7773,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
|
||||
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
|
||||
// treat these built-ins as aliases of VertexIndex and InstanceIndex
|
||||
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
|
||||
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
|
||||
RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
|
||||
RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile) {
|
||||
|
||||
@@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
|
||||
// TODO: but, did this bypass constant folding?
|
||||
//
|
||||
switch (op) {
|
||||
case EOpConstructInt8:
|
||||
case EOpConstructUint8:
|
||||
case EOpConstructInt16:
|
||||
case EOpConstructUint16:
|
||||
case EOpConstructInt:
|
||||
case EOpConstructUint:
|
||||
case EOpConstructInt64:
|
||||
case EOpConstructUint64:
|
||||
case EOpConstructBool:
|
||||
case EOpConstructFloat:
|
||||
case EOpConstructDouble:
|
||||
case EOpConstructFloat16:
|
||||
return child;
|
||||
default: break; // some compilers want this
|
||||
case EOpConstructInt8:
|
||||
case EOpConstructUint8:
|
||||
case EOpConstructInt16:
|
||||
case EOpConstructUint16:
|
||||
case EOpConstructInt:
|
||||
case EOpConstructUint:
|
||||
case EOpConstructInt64:
|
||||
case EOpConstructUint64:
|
||||
case EOpConstructBool:
|
||||
case EOpConstructFloat:
|
||||
case EOpConstructDouble:
|
||||
case EOpConstructFloat16: {
|
||||
TIntermUnary* unary_node = child->getAsUnaryNode();
|
||||
if (unary_node != nullptr)
|
||||
unary_node->updatePrecision();
|
||||
return child;
|
||||
}
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
|
||||
//
|
||||
@@ -3776,6 +3780,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent, and then
|
||||
// back *down* again to the children's subtrees.
|
||||
void TIntermAggregate::updatePrecision()
|
||||
{
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
TPrecisionQualifier maxPrecision = EpqNone;
|
||||
TIntermSequence operands = getSequence();
|
||||
for (unsigned int i = 0; i < operands.size(); ++i) {
|
||||
TIntermTyped* typedNode = operands[i]->getAsTyped();
|
||||
assert(typedNode);
|
||||
maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
|
||||
}
|
||||
getQualifier().precision = maxPrecision;
|
||||
for (unsigned int i = 0; i < operands.size(); ++i) {
|
||||
TIntermTyped* typedNode = operands[i]->getAsTyped();
|
||||
assert(typedNode);
|
||||
typedNode->propagatePrecision(maxPrecision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent, and then
|
||||
// back *down* again to the children's subtrees.
|
||||
void TIntermBinary::updatePrecision()
|
||||
|
||||
@@ -622,6 +622,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
|
||||
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
|
||||
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
|
||||
|
||||
// Check for declarations of this default uniform that already exist due to other compilation units.
|
||||
TSymbol* symbol = symbolTable.find(memberName);
|
||||
if (symbol) {
|
||||
if (memberType != symbol->getType()) {
|
||||
TString err;
|
||||
err += "\"" + memberType.getCompleteString() + "\"";
|
||||
err += " versus ";
|
||||
err += "\"" + symbol->getType().getCompleteString() + "\"";
|
||||
error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the requested member as a member to the global block.
|
||||
TType* type = new TType;
|
||||
type->shallowCopy(memberType);
|
||||
|
||||
@@ -7691,7 +7691,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
|
||||
TIntermAggregate *agg_node = ret_node->getAsAggregate();
|
||||
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
|
||||
agg_node->updatePrecision();
|
||||
|
||||
return ret_node;
|
||||
}
|
||||
|
||||
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
|
||||
|
||||
@@ -241,7 +241,7 @@ protected:
|
||||
// override this to set the language-specific name
|
||||
virtual const char* getAtomicCounterBlockName() const { return ""; }
|
||||
virtual void setAtomicCounterBlockDefaults(TType&) const {}
|
||||
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
|
||||
virtual void setInvariant(const TSourceLoc&, const char*) {}
|
||||
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
|
||||
bool isAtomicCounterBlock(const TSymbol& symbol) {
|
||||
const TVariable* var = symbol.getAsVariable();
|
||||
@@ -472,7 +472,7 @@ public:
|
||||
// Determine loop control from attributes
|
||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
// Function attributes
|
||||
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
|
||||
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
|
||||
|
||||
@@ -279,8 +279,14 @@ TFunction::~TFunction()
|
||||
//
|
||||
TSymbolTableLevel::~TSymbolTableLevel()
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
||||
delete (*it).second;
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||
const TString& name = it->first;
|
||||
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
|
||||
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
|
||||
if (retargetIter == retargetedSymbols.end())
|
||||
delete (*it).second;
|
||||
}
|
||||
|
||||
|
||||
delete [] defaultPrecision;
|
||||
}
|
||||
@@ -418,6 +424,15 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||
symTableLevel->anonId = anonId;
|
||||
symTableLevel->thisLevel = thisLevel;
|
||||
symTableLevel->retargetedSymbols.clear();
|
||||
for (auto &s : retargetedSymbols) {
|
||||
// Extra constructions to make sure they use the correct allocator pool
|
||||
TString newFrom;
|
||||
newFrom = s.first;
|
||||
TString newTo;
|
||||
newTo = s.second;
|
||||
symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
|
||||
}
|
||||
std::vector<bool> containerCopied(anonId, false);
|
||||
tLevel::const_iterator iter;
|
||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||
@@ -433,8 +448,25 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||
symTableLevel->insert(*container, false);
|
||||
containerCopied[anon->getAnonId()] = true;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
const TString& name = iter->first;
|
||||
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
|
||||
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
|
||||
if (retargetIter != retargetedSymbols.end())
|
||||
continue;
|
||||
symTableLevel->insert(*iter->second->clone(), false);
|
||||
}
|
||||
}
|
||||
// Now point retargeted symbols to the newly created versions of them
|
||||
for (auto &s : retargetedSymbols) {
|
||||
TSymbol* sym = symTableLevel->find(s.second);
|
||||
if (!sym)
|
||||
continue;
|
||||
|
||||
// Need to declare and assign so newS is using the correct pool allocator
|
||||
TString newS;
|
||||
newS = s.first;
|
||||
symTableLevel->insert(newS, sym);
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
|
||||
@@ -413,13 +413,20 @@ public:
|
||||
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
|
||||
~TSymbolTableLevel();
|
||||
|
||||
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
||||
bool insert(const TString& name, TSymbol* symbol) {
|
||||
return level.insert(tLevelPair(name, symbol)).second;
|
||||
}
|
||||
|
||||
bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
|
||||
{
|
||||
//
|
||||
// returning true means symbol was added to the table with no semantic errors
|
||||
//
|
||||
const TString& name = symbol.getName();
|
||||
if (name == "") {
|
||||
if (forcedKeyName.length()) {
|
||||
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
|
||||
}
|
||||
else if (name == "") {
|
||||
symbol.getAsVariable()->setAnonId(anonId++);
|
||||
// An empty name means an anonymous container, exposing its members to the external scope.
|
||||
// Give it a name and insert its members in the symbol table, pointing to the container.
|
||||
@@ -471,6 +478,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void retargetSymbol(const TString& from, const TString& to) {
|
||||
tLevel::const_iterator fromIt = level.find(from);
|
||||
tLevel::const_iterator toIt = level.find(to);
|
||||
if (fromIt == level.end() || toIt == level.end())
|
||||
return;
|
||||
delete fromIt->second;
|
||||
level[from] = toIt->second;
|
||||
retargetedSymbols.push_back({from, to});
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
@@ -583,6 +600,8 @@ protected:
|
||||
|
||||
tLevel level; // named mappings
|
||||
TPrecisionQualifier *defaultPrecision;
|
||||
// pair<FromName, ToName>
|
||||
TVector<std::pair<TString, TString>> retargetedSymbols;
|
||||
int anonId;
|
||||
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
|
||||
// that are supposed to see anonymous access to member variables.
|
||||
@@ -788,6 +807,12 @@ public:
|
||||
return symbol;
|
||||
}
|
||||
|
||||
void retargetSymbol(const TString& from, const TString& to) {
|
||||
int level = currentLevel();
|
||||
table[level]->retargetSymbol(from, to);
|
||||
}
|
||||
|
||||
|
||||
// Find of a symbol that returns how many layers deep of nested
|
||||
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||
// found in.
|
||||
|
||||
@@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
|
||||
//
|
||||
// Function attributes
|
||||
//
|
||||
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
|
||||
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
|
||||
{
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->size() > 0) {
|
||||
|
||||
@@ -983,20 +983,20 @@ function_prototype
|
||||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
}
|
||||
| DO {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
++parseContext.statementNestingLevel;
|
||||
++parseContext.controlFlowNestingLevel;
|
||||
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
|
||||
parseContext.boolCheck($8.loc, $6);
|
||||
|
||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
--parseContext.loopNestingLevel;
|
||||
--parseContext.statementNestingLevel;
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
@@ -983,20 +983,20 @@ function_prototype
|
||||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
}
|
||||
| DO {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
++parseContext.statementNestingLevel;
|
||||
++parseContext.controlFlowNestingLevel;
|
||||
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
|
||||
parseContext.boolCheck($8.loc, $6);
|
||||
|
||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
--parseContext.loopNestingLevel;
|
||||
--parseContext.statementNestingLevel;
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1633,6 +1633,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
|
||||
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
||||
});
|
||||
resolver->endResolve(EShLangCount);
|
||||
if (autoPushConstantBlockName.length()) {
|
||||
bool upgraded = false;
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
if (intermediates[stage] != nullptr) {
|
||||
TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
|
||||
auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
|
||||
if (at == pUniformVarMap[stage]->end())
|
||||
continue;
|
||||
TQualifier& qualifier = at->second.symbol->getQualifier();
|
||||
if (!qualifier.isUniform())
|
||||
continue;
|
||||
TType& t = at->second.symbol->getWritableType();
|
||||
int size, stride;
|
||||
TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
|
||||
qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (size <= int(autoPushConstantMaxSize)) {
|
||||
qualifier.setBlockStorage(EbsPushConstant);
|
||||
qualifier.layoutPacking = autoPushConstantBlockPacking;
|
||||
upgraded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If it's been upgraded to push_constant, then remove it from the uniformVector
|
||||
// so it doesn't get a set/binding assigned to it.
|
||||
if (upgraded) {
|
||||
auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
|
||||
[this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
|
||||
if (at != uniformVector.end())
|
||||
uniformVector.erase(at);
|
||||
}
|
||||
}
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
if (intermediates[stage] != nullptr) {
|
||||
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
||||
|
||||
@@ -291,7 +291,7 @@ public:
|
||||
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
||||
};
|
||||
|
||||
// I/O mapper for OpenGL
|
||||
// I/O mapper for GLSL
|
||||
class TGlslIoMapper : public TIoMapper {
|
||||
public:
|
||||
TGlslIoMapper() {
|
||||
@@ -301,6 +301,8 @@ public:
|
||||
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
||||
profile = ENoProfile;
|
||||
version = 0;
|
||||
autoPushConstantMaxSize = 128;
|
||||
autoPushConstantBlockPacking = ElpStd430;
|
||||
}
|
||||
virtual ~TGlslIoMapper() {
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
@@ -319,6 +321,13 @@ public:
|
||||
if (intermediates[stage] != nullptr)
|
||||
intermediates[stage] = nullptr;
|
||||
}
|
||||
}
|
||||
// If set, the uniform block with the given name will be changed to be backed by
|
||||
// push_constant if it's size is <= maxSize
|
||||
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
|
||||
autoPushConstantBlockName = name;
|
||||
autoPushConstantMaxSize = maxSize;
|
||||
autoPushConstantBlockPacking = packing;
|
||||
}
|
||||
// grow the reflection stage by stage
|
||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
||||
@@ -329,6 +338,11 @@ public:
|
||||
bool hadError = false;
|
||||
EProfile profile;
|
||||
int version;
|
||||
|
||||
private:
|
||||
TString autoPushConstantBlockName;
|
||||
unsigned int autoPushConstantMaxSize;
|
||||
TLayoutPacking autoPushConstantBlockPacking;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
@@ -1934,7 +1934,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
||||
}
|
||||
|
||||
// rule 9
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
|
||||
const TTypeList& memberList = *type.getStruct();
|
||||
|
||||
size = 0;
|
||||
@@ -2159,8 +2159,9 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
|
||||
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
|
||||
return type.isArray() &&
|
||||
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
|
||||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
|
||||
(language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
|
||||
! type.getQualifier().patch) ||
|
||||
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
|
||||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
|
||||
type.getQualifier().pervertexNV) ||
|
||||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
|
||||
|
||||
Reference in New Issue
Block a user