mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-19 13:32:59 +01:00
Updated glslang.
This commit is contained in:
2
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
2
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@@ -1448,7 +1448,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
|
||||
}
|
||||
|
||||
if (sourceExtensions.find("GL_EXT_ray_flags_primitive_culling") != sourceExtensions.end()) {
|
||||
if (glslangIntermediate->getLayoutPrimitiveCulling()) {
|
||||
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
|
||||
}
|
||||
|
||||
|
||||
4
3rdparty/glslang/glslang/Include/Types.h
vendored
4
3rdparty/glslang/glslang/Include/Types.h
vendored
@@ -1235,6 +1235,7 @@ struct TShaderQualifiers {
|
||||
bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set
|
||||
bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
||||
int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set
|
||||
bool layoutPrimitiveCulling; // true if layout primitive_culling set
|
||||
TLayoutDepth getDepth() const { return layoutDepth; }
|
||||
#else
|
||||
TLayoutDepth getDepth() const { return EldNone; }
|
||||
@@ -1268,6 +1269,7 @@ struct TShaderQualifiers {
|
||||
layoutOverrideCoverage = false;
|
||||
layoutDerivativeGroupQuads = false;
|
||||
layoutDerivativeGroupLinear = false;
|
||||
layoutPrimitiveCulling = false;
|
||||
primitives = TQualifier::layoutNotSet;
|
||||
interlockOrdering = EioNone;
|
||||
#endif
|
||||
@@ -1331,6 +1333,8 @@ struct TShaderQualifiers {
|
||||
primitives = src.primitives;
|
||||
if (src.interlockOrdering != EioNone)
|
||||
interlockOrdering = src.interlockOrdering;
|
||||
if (src.layoutPrimitiveCulling)
|
||||
layoutPrimitiveCulling = src.layoutPrimitiveCulling;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
2
3rdparty/glslang/glslang/Include/revision.h
vendored
2
3rdparty/glslang/glslang/Include/revision.h
vendored
@@ -1,3 +1,3 @@
|
||||
// This header is generated by the make-revision script.
|
||||
|
||||
#define GLSLANG_PATCH_LEVEL 3763
|
||||
#define GLSLANG_PATCH_LEVEL 3766
|
||||
|
||||
@@ -1733,12 +1733,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||
case EbtUint64:
|
||||
case EbtFloat:
|
||||
case EbtDouble:
|
||||
return true;
|
||||
return version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64);
|
||||
case EbtInt16:
|
||||
case EbtUint16:
|
||||
return extensionRequested(E_GL_AMD_gpu_shader_int16);
|
||||
return (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) &&
|
||||
extensionRequested(E_GL_AMD_gpu_shader_int16);
|
||||
case EbtFloat16:
|
||||
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
||||
return (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) &&
|
||||
extensionRequested(E_GL_AMD_gpu_shader_half_float);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5173,6 +5173,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id == "primitive_culling") {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling");
|
||||
publicType.shaderQualifiers.layoutPrimitiveCulling = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
||||
@@ -6104,6 +6110,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
|
||||
error(loc, message, "num_views", "");
|
||||
if (shaderQualifiers.interlockOrdering != EioNone)
|
||||
error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
|
||||
if (shaderQualifiers.layoutPrimitiveCulling)
|
||||
error(loc, "can only be applied as standalone", "primitive_culling", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -8368,6 +8376,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
||||
{
|
||||
checkIoArraysConsistency(loc);
|
||||
}
|
||||
|
||||
if (publicType.shaderQualifiers.layoutPrimitiveCulling) {
|
||||
if (publicType.qualifier.storage != EvqTemporary)
|
||||
error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", "");
|
||||
else {
|
||||
intermediate.setLayoutPrimitiveCulling();
|
||||
}
|
||||
// Exit early as further checks are not valid
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const TQualifier& qualifier = publicType.qualifier;
|
||||
|
||||
@@ -8527,7 +8545,7 @@ const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TT
|
||||
size_t memberCount = tmpType->getStruct()->size();
|
||||
size_t originHash = 0, tmpHash = 0;
|
||||
std::hash<size_t> hasher;
|
||||
for (uint32_t i = 0; i < memberCount; i++) {
|
||||
for (size_t i = 0; i < memberCount; i++) {
|
||||
size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking +
|
||||
originType->getStruct()->at(i).type->getQualifier().layoutMatrix);
|
||||
size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking +
|
||||
|
||||
@@ -579,10 +579,7 @@ TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate
|
||||
|
||||
int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) {
|
||||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = IsAnonymous(ent.symbol->getName()) ?
|
||||
ent.symbol->getType().getTypeName()
|
||||
:
|
||||
ent.symbol->getName();
|
||||
const TString& name = getAccessName(ent.symbol);
|
||||
if (currentStage != stage) {
|
||||
preStage = currentStage;
|
||||
currentStage = stage;
|
||||
@@ -630,7 +627,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
||||
TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name);
|
||||
if (iter != storageSlotMap[resourceKey].end()) {
|
||||
// If interface resource be found, set it has location and this symbol's new location
|
||||
// equal the symbol's explicit location declarated in pre or next stage.
|
||||
// equal the symbol's explicit location declaration in pre or next stage.
|
||||
//
|
||||
// vs: out vec4 a;
|
||||
// fs: layout(..., location = 3,...) in vec4 a;
|
||||
@@ -666,10 +663,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
||||
|
||||
int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
||||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = IsAnonymous(ent.symbol->getName()) ?
|
||||
ent.symbol->getType().getTypeName()
|
||||
:
|
||||
ent.symbol->getName();
|
||||
const TString& name = getAccessName(ent.symbol);
|
||||
// kick out of not doing this
|
||||
if (! doAutoLocationMapping()) {
|
||||
return ent.newLocation = -1;
|
||||
@@ -712,7 +706,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||
TVarSlotMap::iterator iter = slotMap.find(name);
|
||||
if (iter != slotMap.end()) {
|
||||
// If uniform resource be found, set it has location and this symbol's new location
|
||||
// equal the uniform's explicit location declarated in other stage.
|
||||
// equal the uniform's explicit location declaration in other stage.
|
||||
//
|
||||
// vs: uniform vec4 a;
|
||||
// fs: layout(..., location = 3,...) uniform vec4 a;
|
||||
@@ -720,7 +714,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||
location = iter->second;
|
||||
}
|
||||
if (! hasLocation) {
|
||||
// No explicit location declaraten in other stage.
|
||||
// No explicit location declaration in other stage.
|
||||
// So we should find a new slot for this uniform.
|
||||
//
|
||||
// vs: uniform vec4 a;
|
||||
@@ -729,7 +723,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||
storageSlotMap[resourceKey][name] = location;
|
||||
}
|
||||
} else {
|
||||
// the first uniform declarated in a program.
|
||||
// the first uniform declaration in a program.
|
||||
TVarSlotMap varSlotMap;
|
||||
location = getFreeSlot(resourceKey, 0, size);
|
||||
varSlotMap[name] = location;
|
||||
@@ -740,11 +734,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
||||
|
||||
int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
|
||||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = IsAnonymous(ent.symbol->getName()) ?
|
||||
ent.symbol->getType().getTypeName()
|
||||
:
|
||||
ent.symbol->getName();
|
||||
// On OpenGL arrays of opaque types take a seperate binding for each element
|
||||
const TString& name = getAccessName(ent.symbol);
|
||||
// On OpenGL arrays of opaque types take a separate binding for each element
|
||||
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
TResourceType resource = getResourceType(type);
|
||||
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
||||
@@ -818,10 +809,7 @@ void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) {
|
||||
|
||||
void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
||||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = IsAnonymous(ent.symbol->getName()) ?
|
||||
ent.symbol->getType().getTypeName()
|
||||
:
|
||||
ent.symbol->getName();
|
||||
const TString& name = getAccessName(ent.symbol);
|
||||
TStorageQualifier storage = type.getQualifier().storage;
|
||||
EShLanguage stage(EShLangCount);
|
||||
switch (storage) {
|
||||
@@ -881,10 +869,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
|
||||
|
||||
void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
|
||||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = IsAnonymous(ent.symbol->getName()) ?
|
||||
ent.symbol->getType().getTypeName()
|
||||
:
|
||||
ent.symbol->getName();
|
||||
const TString& name = getAccessName(ent.symbol);
|
||||
int resource = getResourceType(type);
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
TVarSlotMap& varSlotMap = resourceSlotMap[resource];
|
||||
@@ -907,6 +892,13 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
||||
}
|
||||
}
|
||||
|
||||
const TString& TDefaultGlslIoResolver::getAccessName(const TIntermSymbol* symbol)
|
||||
{
|
||||
return symbol->getBasicType() == EbtBlock ?
|
||||
symbol->getType().getTypeName() :
|
||||
symbol->getName();
|
||||
}
|
||||
|
||||
//TDefaultGlslIoResolver end
|
||||
|
||||
/*
|
||||
|
||||
@@ -203,6 +203,7 @@ public:
|
||||
void endCollect(EShLanguage) override;
|
||||
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||
const TString& getAccessName(const TIntermSymbol*);
|
||||
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
|
||||
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
|
||||
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
|
||||
|
||||
@@ -153,7 +153,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
||||
|
||||
if (vertices == TQualifier::layoutNotSet)
|
||||
vertices = unit.vertices;
|
||||
else if (vertices != unit.vertices) {
|
||||
else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) {
|
||||
if (language == EShLangGeometry || language == EShLangMeshNV)
|
||||
error(infoSink, "Contradictory layout max_vertices values");
|
||||
else if (language == EShLangTessControl)
|
||||
@@ -172,12 +172,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
||||
|
||||
if (inputPrimitive == ElgNone)
|
||||
inputPrimitive = unit.inputPrimitive;
|
||||
else if (inputPrimitive != unit.inputPrimitive)
|
||||
else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive)
|
||||
error(infoSink, "Contradictory input layout primitives");
|
||||
|
||||
if (outputPrimitive == ElgNone)
|
||||
outputPrimitive = unit.outputPrimitive;
|
||||
else if (outputPrimitive != unit.outputPrimitive)
|
||||
else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive)
|
||||
error(infoSink, "Contradictory output layout primitives");
|
||||
|
||||
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
||||
|
||||
@@ -265,6 +265,7 @@ public:
|
||||
computeDerivativeMode(LayoutDerivativeNone),
|
||||
primitives(TQualifier::layoutNotSet),
|
||||
numTaskNVBlocks(0),
|
||||
layoutPrimitiveCulling(false),
|
||||
autoMapBindings(false),
|
||||
autoMapLocations(false),
|
||||
flattenUniformArrays(false),
|
||||
@@ -742,6 +743,8 @@ public:
|
||||
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
||||
bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
|
||||
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
||||
void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; }
|
||||
bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; }
|
||||
bool setPrimitives(int m)
|
||||
{
|
||||
if (primitives != TQualifier::layoutNotSet)
|
||||
@@ -974,6 +977,7 @@ protected:
|
||||
ComputeDerivativeMode computeDerivativeMode;
|
||||
int primitives;
|
||||
int numTaskNVBlocks;
|
||||
bool layoutPrimitiveCulling;
|
||||
|
||||
// Base shift values
|
||||
std::array<unsigned int, EResCount> shiftBinding;
|
||||
|
||||
@@ -92,8 +92,8 @@ public:
|
||||
if (processedDerefs.find(&base) == processedDerefs.end()) {
|
||||
processedDerefs.insert(&base);
|
||||
|
||||
uint32_t blockIndex = -1;
|
||||
uint32_t offset = -1;
|
||||
int blockIndex = -1;
|
||||
int offset = -1;
|
||||
TList<TIntermBinary*> derefs;
|
||||
TString baseName = base.getName();
|
||||
|
||||
|
||||
2
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
2
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
@@ -68,7 +68,7 @@
|
||||
// This should always increase, as some paths to do not consume
|
||||
// a more major number.
|
||||
// It should increment by one when new functionality is added.
|
||||
#define GLSLANG_MINOR_VERSION 13
|
||||
#define GLSLANG_MINOR_VERSION 14
|
||||
|
||||
//
|
||||
// Call before doing any other compiler/linker operations.
|
||||
|
||||
87
3rdparty/glslang/hlsl/hlslParseHelper.cpp
vendored
87
3rdparty/glslang/hlsl/hlslParseHelper.cpp
vendored
@@ -1169,7 +1169,7 @@ bool HlslParseContext::shouldFlatten(const TType& type, TStorageQualifier qualif
|
||||
}
|
||||
|
||||
// Top level variable flattening: construct data
|
||||
void HlslParseContext::flatten(const TVariable& variable, bool linkage)
|
||||
void HlslParseContext::flatten(const TVariable& variable, bool linkage, bool arrayed)
|
||||
{
|
||||
const TType& type = variable.getType();
|
||||
|
||||
@@ -1181,8 +1181,15 @@ void HlslParseContext::flatten(const TVariable& variable, bool linkage)
|
||||
TFlattenData(type.getQualifier().layoutBinding,
|
||||
type.getQualifier().layoutLocation)));
|
||||
|
||||
// the item is a map pair, so first->second is the TFlattenData itself.
|
||||
flatten(variable, type, entry.first->second, variable.getName(), linkage, type.getQualifier(), nullptr);
|
||||
// if flattening arrayed io struct, array each member of dereferenced type
|
||||
if (arrayed) {
|
||||
const TType dereferencedType(type, 0);
|
||||
flatten(variable, dereferencedType, entry.first->second, variable.getName(), linkage,
|
||||
type.getQualifier(), type.getArraySizes());
|
||||
} else {
|
||||
flatten(variable, type, entry.first->second, variable.getName(), linkage,
|
||||
type.getQualifier(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively flatten the given variable at the provided type, building the flattenData as we go.
|
||||
@@ -1256,6 +1263,10 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType&
|
||||
}
|
||||
}
|
||||
|
||||
// Only propagate arraysizes here for arrayed io
|
||||
if (variable.getType().getQualifier().isArrayedIo(language) && builtInArraySizes != nullptr)
|
||||
memberVariable->getWritableType().copyArraySizes(*builtInArraySizes);
|
||||
|
||||
flattenData.offsets.push_back(static_cast<int>(flattenData.members.size()));
|
||||
flattenData.members.push_back(memberVariable);
|
||||
|
||||
@@ -2068,11 +2079,8 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
|
||||
// Further this return/in/out transform by flattening, splitting, and assigning locations
|
||||
const auto makeVariableInOut = [&](TVariable& variable) {
|
||||
if (variable.getType().isStruct()) {
|
||||
if (variable.getType().getQualifier().isArrayedIo(language)) {
|
||||
if (variable.getType().containsBuiltIn())
|
||||
split(variable);
|
||||
} else if (shouldFlatten(variable.getType(), EvqVaryingIn /* not assigned yet, but close enough */, true))
|
||||
flatten(variable, false /* don't track linkage here, it will be tracked in assignToInterface() */);
|
||||
bool arrayed = variable.getType().getQualifier().isArrayedIo(language);
|
||||
flatten(variable, false /* don't track linkage here, it will be tracked in assignToInterface() */, arrayed);
|
||||
}
|
||||
// TODO: flatten arrays too
|
||||
// TODO: flatten everything in I/O
|
||||
@@ -2733,17 +2741,33 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
wasSplit(binaryNode->getLeft());
|
||||
};
|
||||
|
||||
// Return symbol if node is symbol or index ref
|
||||
const auto getSymbol = [](const TIntermTyped* node) -> const TIntermSymbol* {
|
||||
const TIntermSymbol* symbolNode = node->getAsSymbolNode();
|
||||
if (symbolNode != nullptr)
|
||||
return symbolNode;
|
||||
|
||||
const TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||
if (binaryNode != nullptr && (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect))
|
||||
return binaryNode->getLeft()->getAsSymbolNode();
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
// Return true if this stage assigns clip position with potentially inverted Y
|
||||
const auto assignsClipPos = [this](const TIntermTyped* node) -> bool {
|
||||
return node->getType().getQualifier().builtIn == EbvPosition &&
|
||||
(language == EShLangVertex || language == EShLangGeometry || language == EShLangTessEvaluation);
|
||||
};
|
||||
|
||||
const TIntermSymbol* leftSymbol = getSymbol(left);
|
||||
const TIntermSymbol* rightSymbol = getSymbol(right);
|
||||
|
||||
const bool isSplitLeft = wasSplit(left) || indexesSplit(left);
|
||||
const bool isSplitRight = wasSplit(right) || indexesSplit(right);
|
||||
|
||||
const bool isFlattenLeft = wasFlattened(left);
|
||||
const bool isFlattenRight = wasFlattened(right);
|
||||
const bool isFlattenLeft = wasFlattened(leftSymbol);
|
||||
const bool isFlattenRight = wasFlattened(rightSymbol);
|
||||
|
||||
// OK to do a single assign if neither side is split or flattened. Otherwise,
|
||||
// fall through to a member-wise copy.
|
||||
@@ -2791,10 +2815,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
memberCount = left->getType().getCumulativeArraySize();
|
||||
|
||||
if (isFlattenLeft)
|
||||
leftVariables = &flattenMap.find(left->getAsSymbolNode()->getId())->second.members;
|
||||
leftVariables = &flattenMap.find(leftSymbol->getId())->second.members;
|
||||
|
||||
if (isFlattenRight) {
|
||||
rightVariables = &flattenMap.find(right->getAsSymbolNode()->getId())->second.members;
|
||||
rightVariables = &flattenMap.find(rightSymbol->getId())->second.members;
|
||||
} else {
|
||||
// The RHS is not flattened. There are several cases:
|
||||
// 1. 1 item to copy: Use the RHS directly.
|
||||
@@ -2828,8 +2852,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
TStorageQualifier leftStorage = left->getType().getQualifier().storage;
|
||||
TStorageQualifier rightStorage = right->getType().getQualifier().storage;
|
||||
|
||||
int leftOffset = findSubtreeOffset(*left);
|
||||
int rightOffset = findSubtreeOffset(*right);
|
||||
int leftOffsetStart = findSubtreeOffset(*left);
|
||||
int rightOffsetStart = findSubtreeOffset(*right);
|
||||
int leftOffset = leftOffsetStart;
|
||||
int rightOffset = rightOffsetStart;
|
||||
|
||||
const auto getMember = [&](bool isLeft, const TType& type, int member, TIntermTyped* splitNode, int splitMember,
|
||||
bool flattened)
|
||||
@@ -2869,10 +2895,35 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
}
|
||||
}
|
||||
} else if (flattened && !shouldFlatten(derefType, isLeft ? leftStorage : rightStorage, false)) {
|
||||
if (isLeft)
|
||||
if (isLeft) {
|
||||
// offset will cycle through variables for arrayed io
|
||||
if (leftOffset >= static_cast<int>(leftVariables->size()))
|
||||
leftOffset = leftOffsetStart;
|
||||
subTree = intermediate.addSymbol(*(*leftVariables)[leftOffset++]);
|
||||
else
|
||||
} else {
|
||||
// offset will cycle through variables for arrayed io
|
||||
if (rightOffset >= static_cast<int>(rightVariables->size()))
|
||||
rightOffset = rightOffsetStart;
|
||||
subTree = intermediate.addSymbol(*(*rightVariables)[rightOffset++]);
|
||||
}
|
||||
|
||||
// arrayed io
|
||||
if (subTree->getType().isArray()) {
|
||||
if (!arrayElement.empty()) {
|
||||
const TType derefType(subTree->getType(), arrayElement.front());
|
||||
subTree = intermediate.addIndex(EOpIndexDirect, subTree,
|
||||
intermediate.addConstantUnion(arrayElement.front(), loc), loc);
|
||||
subTree->setType(derefType);
|
||||
} else {
|
||||
// There's an index operation we should transfer to the output builtin.
|
||||
assert(splitNode->getAsOperator() != nullptr &&
|
||||
splitNode->getAsOperator()->getOp() == EOpIndexIndirect);
|
||||
const TType splitDerefType(subTree->getType(), 0);
|
||||
subTree = intermediate.addIndex(splitNode->getAsOperator()->getOp(), subTree,
|
||||
splitNode->getAsBinaryNode()->getRight(), loc);
|
||||
subTree->setType(splitDerefType);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Index operator if it's an aggregate, else EOpNull
|
||||
const TOperator accessOp = type.isArray() ? EOpIndexDirect
|
||||
@@ -9911,8 +9962,8 @@ void HlslParseContext::addPatchConstantInvocation()
|
||||
TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType);
|
||||
pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut;
|
||||
|
||||
if (pcfOutput->getType().containsBuiltIn())
|
||||
split(*pcfOutput);
|
||||
if (pcfOutput->getType().isStruct())
|
||||
flatten(*pcfOutput, false);
|
||||
|
||||
assignToInterface(*pcfOutput);
|
||||
|
||||
|
||||
2
3rdparty/glslang/hlsl/hlslParseHelper.h
vendored
2
3rdparty/glslang/hlsl/hlslParseHelper.h
vendored
@@ -276,7 +276,7 @@ protected:
|
||||
|
||||
void fixBuiltInIoType(TType&);
|
||||
|
||||
void flatten(const TVariable& variable, bool linkage);
|
||||
void flatten(const TVariable& variable, bool linkage, bool arrayed = false);
|
||||
int flatten(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage,
|
||||
const TQualifier& outerQualifier, const TArraySizes* builtInArraySizes);
|
||||
int flattenStruct(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage,
|
||||
|
||||
Reference in New Issue
Block a user