|
@@ -145,9 +145,9 @@ protected:
|
|
spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
|
|
spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
|
|
spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
|
|
spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
|
|
void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
|
|
void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
|
|
- spv::Id convertGlslangToSpvType(const glslang::TType& type);
|
|
|
|
|
|
+ spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
|
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
|
- bool lastBufferBlockMember);
|
|
|
|
|
|
+ bool lastBufferBlockMember, bool forwardReferenceOnly = false);
|
|
bool filterMember(const glslang::TType& member);
|
|
bool filterMember(const glslang::TType& member);
|
|
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
|
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
|
glslang::TLayoutPacking, const glslang::TQualifier&);
|
|
glslang::TLayoutPacking, const glslang::TQualifier&);
|
|
@@ -211,6 +211,15 @@ protected:
|
|
builder.addExtension(ext);
|
|
builder.addExtension(ext);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ unsigned int getBufferReferenceAlignment(const glslang::TType &type) const {
|
|
|
|
+ if (type.getBasicType() == glslang::EbtReference) {
|
|
|
|
+ return type.getReferentType()->getQualifier().hasBufferReferenceAlign() ?
|
|
|
|
+ (1u << type.getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u;
|
|
|
|
+ } else {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
glslang::SpvOptions& options;
|
|
glslang::SpvOptions& options;
|
|
spv::Function* shaderEntry;
|
|
spv::Function* shaderEntry;
|
|
spv::Function* currentFunction;
|
|
spv::Function* currentFunction;
|
|
@@ -237,6 +246,8 @@ protected:
|
|
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
|
|
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
|
|
std::stack<bool> breakForLoop; // false means break for switch
|
|
std::stack<bool> breakForLoop; // false means break for switch
|
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
|
|
|
+ // Map pointee types for EbtReference to their forward pointers
|
|
|
|
+ std::map<const glslang::TType *, spv::Id> forwardPointers;
|
|
};
|
|
};
|
|
|
|
|
|
//
|
|
//
|
|
@@ -1303,12 +1314,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
|
|
builder.addInclude(iItr->first, iItr->second);
|
|
builder.addInclude(iItr->first, iItr->second);
|
|
}
|
|
}
|
|
stdBuiltins = builder.import("GLSL.std.450");
|
|
stdBuiltins = builder.import("GLSL.std.450");
|
|
|
|
+
|
|
|
|
+ spv::AddressingModel addressingModel = spv::AddressingModelLogical;
|
|
|
|
+ spv::MemoryModel memoryModel = spv::MemoryModelGLSL450;
|
|
|
|
+
|
|
|
|
+ if (glslangIntermediate->usingPhysicalStorageBuffer()) {
|
|
|
|
+ addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
|
|
|
|
+ builder.addExtension(spv::E_SPV_EXT_physical_storage_buffer);
|
|
|
|
+ builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
|
|
|
|
+ };
|
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
|
- builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelVulkanKHR);
|
|
|
|
|
|
+ memoryModel = spv::MemoryModelVulkanKHR;
|
|
|
|
+ builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
|
builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
|
|
builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
|
|
- } else {
|
|
|
|
- builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
|
|
|
}
|
|
}
|
|
|
|
+ builder.setMemoryModel(addressingModel, memoryModel);
|
|
|
|
+
|
|
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
|
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
|
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
|
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
|
|
|
|
|
@@ -1681,8 +1702,24 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
// so short circuit the access-chain stuff with a swizzle.
|
|
// so short circuit the access-chain stuff with a swizzle.
|
|
std::vector<unsigned> swizzle;
|
|
std::vector<unsigned> swizzle;
|
|
swizzle.push_back(glslangIndex);
|
|
swizzle.push_back(glslangIndex);
|
|
- builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
|
|
|
|
|
+ int dummySize;
|
|
|
|
+ builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
|
|
|
+ TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
|
} else {
|
|
} else {
|
|
|
|
+
|
|
|
|
+ // Load through a block reference is performed with a dot operator that
|
|
|
|
+ // is mapped to EOpIndexDirectStruct. When we get to the actual reference,
|
|
|
|
+ // do a load and reset the access chain.
|
|
|
|
+ if (node->getLeft()->getBasicType() == glslang::EbtReference &&
|
|
|
|
+ !node->getLeft()->getType().isArray() &&
|
|
|
|
+ node->getOp() == glslang::EOpIndexDirectStruct)
|
|
|
|
+ {
|
|
|
|
+ spv::Id left = accessChainLoad(node->getLeft()->getType());
|
|
|
|
+ builder.clearAccessChain();
|
|
|
|
+ builder.setAccessChainLValue(left);
|
|
|
|
+ }
|
|
|
|
+
|
|
int spvIndex = glslangIndex;
|
|
int spvIndex = glslangIndex;
|
|
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
|
|
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
|
|
node->getOp() == glslang::EOpIndexDirectStruct)
|
|
node->getOp() == glslang::EOpIndexDirectStruct)
|
|
@@ -1695,7 +1732,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
}
|
|
}
|
|
|
|
|
|
// normal case for indexing array or structure or block
|
|
// normal case for indexing array or structure or block
|
|
- builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()));
|
|
|
|
|
|
+ builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType()));
|
|
|
|
|
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
|
// We have deferred generation of associated capabilities until now.
|
|
// We have deferred generation of associated capabilities until now.
|
|
@@ -1728,10 +1765,13 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
// restore the saved access chain
|
|
// restore the saved access chain
|
|
builder.setAccessChain(partial);
|
|
builder.setAccessChain(partial);
|
|
|
|
|
|
- if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
|
|
|
|
- builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
|
|
|
|
- else
|
|
|
|
- builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()));
|
|
|
|
|
|
+ if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) {
|
|
|
|
+ int dummySize;
|
|
|
|
+ builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()),
|
|
|
|
+ TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
|
|
|
+ } else
|
|
|
|
+ builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType()));
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
case glslang::EOpVectorSwizzle:
|
|
case glslang::EOpVectorSwizzle:
|
|
@@ -1739,7 +1779,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|
node->getLeft()->traverse(this);
|
|
node->getLeft()->traverse(this);
|
|
std::vector<unsigned> swizzle;
|
|
std::vector<unsigned> swizzle;
|
|
convertSwizzle(*node->getRight()->getAsAggregate(), swizzle);
|
|
convertSwizzle(*node->getRight()->getAsAggregate(), swizzle);
|
|
- builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
|
|
|
|
|
+ int dummySize;
|
|
|
|
+ builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
|
|
|
+ TranslateCoherent(node->getLeft()->getType()),
|
|
|
|
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
case glslang::EOpMatrixSwizzle:
|
|
case glslang::EOpMatrixSwizzle:
|
|
@@ -2178,6 +2221,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
case glslang::EOpConstructU64Vec4:
|
|
case glslang::EOpConstructU64Vec4:
|
|
case glslang::EOpConstructStruct:
|
|
case glslang::EOpConstructStruct:
|
|
case glslang::EOpConstructTextureSampler:
|
|
case glslang::EOpConstructTextureSampler:
|
|
|
|
+ case glslang::EOpConstructReference:
|
|
{
|
|
{
|
|
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
|
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
|
std::vector<spv::Id> arguments;
|
|
std::vector<spv::Id> arguments;
|
|
@@ -2829,6 +2873,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|
builder.addCapability(spv::CapabilityStorageUniform16);
|
|
builder.addCapability(spv::CapabilityStorageUniform16);
|
|
break;
|
|
break;
|
|
case spv::StorageClassStorageBuffer:
|
|
case spv::StorageClassStorageBuffer:
|
|
|
|
+ case spv::StorageClassPhysicalStorageBufferEXT:
|
|
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
|
|
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
|
|
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
|
|
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
|
|
break;
|
|
break;
|
|
@@ -2910,16 +2955,17 @@ void TGlslangToSpvTraverser::convertSwizzle(const glslang::TIntermAggregate& nod
|
|
// Convert from a glslang type to an SPV type, by calling into a
|
|
// Convert from a glslang type to an SPV type, by calling into a
|
|
// recursive version of this function. This establishes the inherited
|
|
// recursive version of this function. This establishes the inherited
|
|
// layout state rooted from the top-level type.
|
|
// layout state rooted from the top-level type.
|
|
-spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
|
|
|
|
|
|
+spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly)
|
|
{
|
|
{
|
|
- return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false);
|
|
|
|
|
|
+ return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false, forwardReferenceOnly);
|
|
}
|
|
}
|
|
|
|
|
|
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
|
|
// Do full recursive conversion of an arbitrary glslang 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 convertGlslangStructToSpvType().
|
|
// Mutually recursive with convertGlslangStructToSpvType().
|
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
|
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
|
|
- glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, bool lastBufferBlockMember)
|
|
|
|
|
|
+ glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier,
|
|
|
|
+ bool lastBufferBlockMember, bool forwardReferenceOnly)
|
|
{
|
|
{
|
|
spv::Id spvType = spv::NoResult;
|
|
spv::Id spvType = spv::NoResult;
|
|
|
|
|
|
@@ -3014,6 +3060,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
|
|
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case glslang::EbtReference:
|
|
|
|
+ {
|
|
|
|
+ // Make the forward pointer, then recurse to convert the structure type, then
|
|
|
|
+ // patch up the forward pointer with a real pointer type.
|
|
|
|
+ if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) {
|
|
|
|
+ spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT);
|
|
|
|
+ forwardPointers[type.getReferentType()] = forwardId;
|
|
|
|
+ }
|
|
|
|
+ spvType = forwardPointers[type.getReferentType()];
|
|
|
|
+ if (!forwardReferenceOnly) {
|
|
|
|
+ spv::Id referentType = convertGlslangToSpvType(*type.getReferentType());
|
|
|
|
+ builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT,
|
|
|
|
+ forwardPointers[type.getReferentType()],
|
|
|
|
+ referentType);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
assert(0);
|
|
assert(0);
|
|
break;
|
|
break;
|
|
@@ -3121,6 +3184,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|
// Create a vector of struct types for SPIR-V to consume
|
|
// Create a vector of struct types for SPIR-V to consume
|
|
std::vector<spv::Id> spvMembers;
|
|
std::vector<spv::Id> spvMembers;
|
|
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
|
|
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
|
|
|
|
+ std::vector<std::pair<glslang::TType*, glslang::TQualifier> > deferredForwardPointers;
|
|
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
|
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
|
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
|
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
|
if (glslangMember.hiddenMember()) {
|
|
if (glslangMember.hiddenMember()) {
|
|
@@ -3144,8 +3208,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|
// recurse
|
|
// recurse
|
|
bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
|
|
bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
|
|
i == (int)glslangMembers->size() - 1;
|
|
i == (int)glslangMembers->size() - 1;
|
|
- spvMembers.push_back(
|
|
|
|
- convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember));
|
|
|
|
|
|
+
|
|
|
|
+ // Make forward pointers for any pointer members, and create a list of members to
|
|
|
|
+ // convert to spirv types after creating the struct.
|
|
|
|
+ if (glslangMember.getBasicType() == glslang::EbtReference) {
|
|
|
|
+ if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) {
|
|
|
|
+ deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier));
|
|
|
|
+ }
|
|
|
|
+ spvMembers.push_back(
|
|
|
|
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true));
|
|
|
|
+ } else {
|
|
|
|
+ spvMembers.push_back(
|
|
|
|
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3157,6 +3232,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|
// Decorate it
|
|
// Decorate it
|
|
decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType);
|
|
decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType);
|
|
|
|
|
|
|
|
+ for (int i = 0; i < deferredForwardPointers.size(); ++i) {
|
|
|
|
+ auto it = deferredForwardPointers[i];
|
|
|
|
+ convertGlslangToSpvType(*it.first, explicitLayout, it.second, false);
|
|
|
|
+ }
|
|
|
|
+
|
|
return spvType;
|
|
return spvType;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3320,11 +3400,15 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
|
coherentFlags |= TranslateCoherent(type);
|
|
coherentFlags |= TranslateCoherent(type);
|
|
|
|
|
|
|
|
+ unsigned int alignment = builder.getAccessChain().alignment;
|
|
|
|
+ alignment |= getBufferReferenceAlignment(type);
|
|
|
|
+
|
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
|
TranslateNonUniformDecoration(type.getQualifier()),
|
|
TranslateNonUniformDecoration(type.getQualifier()),
|
|
nominalTypeId,
|
|
nominalTypeId,
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
|
- TranslateMemoryScope(coherentFlags));
|
|
|
|
|
|
+ TranslateMemoryScope(coherentFlags),
|
|
|
|
+ alignment);
|
|
|
|
|
|
// Need to convert to abstract types when necessary
|
|
// Need to convert to abstract types when necessary
|
|
if (type.getBasicType() == glslang::EbtBool) {
|
|
if (type.getBasicType() == glslang::EbtBool) {
|
|
@@ -3383,9 +3467,12 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
|
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
|
coherentFlags |= TranslateCoherent(type);
|
|
coherentFlags |= TranslateCoherent(type);
|
|
|
|
|
|
|
|
+ unsigned int alignment = builder.getAccessChain().alignment;
|
|
|
|
+ alignment |= getBufferReferenceAlignment(type);
|
|
|
|
+
|
|
builder.accessChainStore(rvalue,
|
|
builder.accessChainStore(rvalue,
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
|
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
|
|
- TranslateMemoryScope(coherentFlags));
|
|
|
|
|
|
+ TranslateMemoryScope(coherentFlags), alignment);
|
|
}
|
|
}
|
|
|
|
|
|
// For storing when types match at the glslang level, but not might match at the
|
|
// For storing when types match at the glslang level, but not might match at the
|
|
@@ -3431,7 +3518,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|
// set up the target storage
|
|
// set up the target storage
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
builder.setAccessChainLValue(lValue);
|
|
builder.setAccessChainLValue(lValue);
|
|
- builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type));
|
|
|
|
|
|
+ builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), getBufferReferenceAlignment(type));
|
|
|
|
|
|
// store the member
|
|
// store the member
|
|
multiTypeStore(glslangElementType, elementRValue);
|
|
multiTypeStore(glslangElementType, elementRValue);
|
|
@@ -3451,7 +3538,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|
// set up the target storage
|
|
// set up the target storage
|
|
builder.clearAccessChain();
|
|
builder.clearAccessChain();
|
|
builder.setAccessChainLValue(lValue);
|
|
builder.setAccessChainLValue(lValue);
|
|
- builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type));
|
|
|
|
|
|
+ builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), getBufferReferenceAlignment(type));
|
|
|
|
|
|
// store the member
|
|
// store the member
|
|
multiTypeStore(glslangMemberType, memberRValue);
|
|
multiTypeStore(glslangMemberType, memberRValue);
|
|
@@ -3638,11 +3725,22 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
|
// Make all the functions, skeletally, without actually visiting their bodies.
|
|
// Make all the functions, skeletally, without actually visiting their bodies.
|
|
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
|
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
|
{
|
|
{
|
|
- const auto getParamDecorations = [](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
|
|
|
|
|
|
+ const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
|
|
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
|
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
|
if (paramPrecision != spv::NoPrecision)
|
|
if (paramPrecision != spv::NoPrecision)
|
|
decorations.push_back(paramPrecision);
|
|
decorations.push_back(paramPrecision);
|
|
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
|
|
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
|
|
|
|
+ if (type.getBasicType() == glslang::EbtReference) {
|
|
|
|
+ // Original and non-writable params pass the pointer directly and
|
|
|
|
+ // use restrict/aliased, others are stored to a pointer in Function
|
|
|
|
+ // memory and use RestrictPointer/AliasedPointer.
|
|
|
|
+ if (originalParam(type.getQualifier().storage, type, false) ||
|
|
|
|
+ !writableParam(type.getQualifier().storage)) {
|
|
|
|
+ decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrict : spv::DecorationAliased);
|
|
|
|
+ } else {
|
|
|
|
+ decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
};
|
|
};
|
|
|
|
|
|
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
|
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
|
@@ -4459,7 +4557,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|
spv::Builder::AccessChain::CoherentFlags flags;
|
|
spv::Builder::AccessChain::CoherentFlags flags;
|
|
flags.clear();
|
|
flags.clear();
|
|
|
|
|
|
- builder.accessChainPush(builder.makeIntConstant(i), flags);
|
|
|
|
|
|
+ builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
|
|
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
|
|
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
|
|
}
|
|
}
|
|
return builder.createCompositeExtract(res, resultType(), 0);
|
|
return builder.createCompositeExtract(res, resultType(), 0);
|
|
@@ -5330,6 +5428,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
|
|
unaryOp = spv::OpGroupNonUniformPartitionNV;
|
|
unaryOp = spv::OpGroupNonUniformPartitionNV;
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
|
|
+ case glslang::EOpConstructReference:
|
|
|
|
+ unaryOp = spv::OpBitcast;
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -5782,6 +5883,12 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
|
|
// For normal run-time conversion instruction, use OpBitcast.
|
|
// For normal run-time conversion instruction, use OpBitcast.
|
|
convOp = spv::OpBitcast;
|
|
convOp = spv::OpBitcast;
|
|
break;
|
|
break;
|
|
|
|
+ case glslang::EOpConvUint64ToPtr:
|
|
|
|
+ convOp = spv::OpConvertUToPtr;
|
|
|
|
+ break;
|
|
|
|
+ case glslang::EOpConvPtrToUint64:
|
|
|
|
+ convOp = spv::OpConvertPtrToU;
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -7247,6 +7354,10 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|
symbol->getType().getQualifier().semanticName);
|
|
symbol->getType().getQualifier().semanticName);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (symbol->getBasicType() == glslang::EbtReference) {
|
|
|
|
+ builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
|
|
|
+ }
|
|
|
|
+
|
|
return id;
|
|
return id;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7375,7 +7486,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
|
glslang::TType vectorType(glslangType, 0);
|
|
glslang::TType vectorType(glslangType, 0);
|
|
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
|
|
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
|
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
|
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
|
|
- } else if (glslangType.getStruct()) {
|
|
|
|
|
|
+ } else if (glslangType.isStruct()) {
|
|
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
|
|
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
|
|
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
|
|
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
|
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));
|
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));
|