GL_EXT_buffer_reference

This commit is contained in:
Jeff Bolz 2019-01-06 17:58:04 -06:00
parent 6eab476e5a
commit 9f2aec49e9
55 changed files with 3093 additions and 103 deletions

View File

@ -40,5 +40,6 @@ static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer";
#endif // #ifndef GLSLextKHR_H

View File

@ -145,9 +145,9 @@ protected:
spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
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&,
bool lastBufferBlockMember);
bool lastBufferBlockMember, bool forwardReferenceOnly = false);
bool filterMember(const glslang::TType& member);
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
glslang::TLayoutPacking, const glslang::TQualifier&);
@ -211,6 +211,15 @@ protected:
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;
spv::Function* shaderEntry;
spv::Function* currentFunction;
@ -237,6 +246,8 @@ protected:
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
std::stack<bool> breakForLoop; // false means break for switch
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);
}
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()) {
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelVulkanKHR);
memoryModel = spv::MemoryModelVulkanKHR;
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
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());
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.
std::vector<unsigned> swizzle;
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 {
// 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;
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
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
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.
// 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
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;
case glslang::EOpVectorSwizzle:
@ -1739,7 +1779,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
node->getLeft()->traverse(this);
std::vector<unsigned> 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;
case glslang::EOpMatrixSwizzle:
@ -2178,6 +2221,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpConstructU64Vec4:
case glslang::EOpConstructStruct:
case glslang::EOpConstructTextureSampler:
case glslang::EOpConstructReference:
{
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
std::vector<spv::Id> arguments;
@ -2829,6 +2873,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
builder.addCapability(spv::CapabilityStorageUniform16);
break;
case spv::StorageClassStorageBuffer:
case spv::StorageClassPhysicalStorageBufferEXT:
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
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
// recursive version of this function. This establishes the inherited
// 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.
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
// Mutually recursive with convertGlslangStructToSpvType().
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;
@ -3014,6 +3060,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
}
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:
assert(0);
break;
@ -3121,6 +3184,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
// Create a vector of struct types for SPIR-V to consume
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
std::vector<std::pair<glslang::TType*, glslang::TQualifier> > deferredForwardPointers;
for (int i = 0; i < (int)glslangMembers->size(); i++) {
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
if (glslangMember.hiddenMember()) {
@ -3144,8 +3208,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
// recurse
bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
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
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;
}
@ -3320,11 +3400,15 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
coherentFlags |= TranslateCoherent(type);
unsigned int alignment = builder.getAccessChain().alignment;
alignment |= getBufferReferenceAlignment(type);
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
TranslateNonUniformDecoration(type.getQualifier()),
nominalTypeId,
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
TranslateMemoryScope(coherentFlags));
TranslateMemoryScope(coherentFlags),
alignment);
// Need to convert to abstract types when necessary
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;
coherentFlags |= TranslateCoherent(type);
unsigned int alignment = builder.getAccessChain().alignment;
alignment |= getBufferReferenceAlignment(type);
builder.accessChainStore(rvalue,
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
@ -3431,7 +3518,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type));
builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), getBufferReferenceAlignment(type));
// store the member
multiTypeStore(glslangElementType, elementRValue);
@ -3451,7 +3538,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type));
builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), getBufferReferenceAlignment(type));
// store the member
multiTypeStore(glslangMemberType, memberRValue);
@ -3638,11 +3725,22 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
// Make all the functions, skeletally, without actually visiting their bodies.
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);
if (paramPrecision != spv::NoPrecision)
decorations.push_back(paramPrecision);
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) {
@ -4459,7 +4557,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
spv::Builder::AccessChain::CoherentFlags flags;
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));
}
return builder.createCompositeExtract(res, resultType(), 0);
@ -5330,6 +5428,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
unaryOp = spv::OpGroupNonUniformPartitionNV;
break;
#endif
case glslang::EOpConstructReference:
unaryOp = spv::OpBitcast;
break;
default:
return 0;
}
@ -5782,6 +5883,12 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
// For normal run-time conversion instruction, use OpBitcast.
convOp = spv::OpBitcast;
break;
case glslang::EOpConvUint64ToPtr:
convOp = spv::OpConvertUToPtr;
break;
case glslang::EOpConvPtrToUint64:
convOp = spv::OpConvertPtrToU;
break;
default:
break;
}
@ -7247,6 +7354,10 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
symbol->getType().getQualifier().semanticName);
}
if (symbol->getBasicType() == glslang::EbtReference) {
builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
}
return id;
}
@ -7375,7 +7486,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
glslang::TType vectorType(glslangType, 0);
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
} else if (glslangType.getStruct()) {
} else if (glslangType.isStruct()) {
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));

View File

@ -194,6 +194,40 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
return type->getResultId();
}
Id Builder::makeForwardPointer(StorageClass storageClass)
{
// Caching/uniquifying doesn't work here, because we don't know the
// pointee type and there can be multiple forward pointers of the same
// storage type. Somebody higher up in the stack must keep track.
Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeForwardPointer);
type->addImmediateOperand(storageClass);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
return type->getResultId();
}
Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardPointerType, Id pointee)
{
// try to find it
Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)storageClass &&
type->getIdOperand(1) == pointee)
return type->getResultId();
}
type = new Instruction(forwardPointerType, NoType, OpTypePointer);
type->addImmediateOperand(storageClass);
type->addIdOperand(pointee);
groupedTypes[OpTypePointer].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
return type->getResultId();
}
Id Builder::makeIntegerType(int width, bool hasSign)
{
// try to find it
@ -576,6 +610,7 @@ int Builder::getNumTypeConstituents(Id typeId) const
case OpTypeBool:
case OpTypeInt:
case OpTypeFloat:
case OpTypePointer:
return 1;
case OpTypeVector:
case OpTypeMatrix:
@ -669,17 +704,36 @@ bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const
return true;
}
return false;
case OpTypePointer:
return false;
case OpTypeVector:
case OpTypeMatrix:
case OpTypeArray:
case OpTypeRuntimeArray:
case OpTypePointer:
return containsType(getContainedTypeId(typeId), typeOp, width);
default:
return typeClass == typeOp;
}
}
// return true if the type is a pointer to PhysicalStorageBufferEXT or an
// array of such pointers. These require restrict/aliased decorations.
bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const
{
const Instruction& instr = *module.getInstruction(typeId);
Op typeClass = instr.getOpCode();
switch (typeClass)
{
case OpTypePointer:
return getTypeStorageClass(typeId) == StorageClassPhysicalStorageBufferEXT;
case OpTypeArray:
return containsPhysicalStorageBufferOrArray(getContainedTypeId(typeId));
default:
return false;
}
}
// See if a scalar constant of this type has already been created, so it
// can be reused rather than duplicated. (Required by the specification).
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
@ -1252,15 +1306,39 @@ Id Builder::createUndefined(Id type)
return inst->getResultId();
}
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const
{
switch (sc) {
case spv::StorageClassUniform:
case spv::StorageClassWorkgroup:
case spv::StorageClassStorageBuffer:
case spv::StorageClassPhysicalStorageBufferEXT:
break;
default:
memoryAccess = spv::MemoryAccessMask(memoryAccess &
~(spv::MemoryAccessMakePointerAvailableKHRMask |
spv::MemoryAccessMakePointerVisibleKHRMask |
spv::MemoryAccessNonPrivatePointerKHRMask));
break;
}
return memoryAccess;
}
// Comments in header
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
Instruction* store = new Instruction(OpStore);
store->addIdOperand(lValue);
store->addIdOperand(rValue);
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
if (memoryAccess != MemoryAccessMaskNone) {
store->addImmediateOperand(memoryAccess);
if (memoryAccess & spv::MemoryAccessAlignedMask) {
store->addImmediateOperand(alignment);
}
if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
store->addIdOperand(makeUintConstant(scope));
}
@ -1270,13 +1348,18 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
}
// Comments in header
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
load->addIdOperand(lValue);
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
if (memoryAccess != MemoryAccessMaskNone) {
load->addImmediateOperand(memoryAccess);
if (memoryAccess & spv::MemoryAccessAlignedMask) {
load->addImmediateOperand(alignment);
}
if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
load->addIdOperand(makeUintConstant(scope));
}
@ -2118,7 +2201,8 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
// Go through the source arguments, each one could have either
// a single or multiple components to contribute.
for (unsigned int i = 0; i < sources.size(); ++i) {
if (isScalar(sources[i]))
if (isScalar(sources[i]) || isPointer(sources[i]))
latchResult(sources[i]);
else if (isVector(sources[i]))
accumulateVectorConstituents(sources[i]);
@ -2433,11 +2517,15 @@ void Builder::clearAccessChain()
accessChain.preSwizzleBaseType = NoType;
accessChain.isRValue = false;
accessChain.coherentFlags.clear();
accessChain.alignment = 0;
}
// Comments in header
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType)
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
{
accessChain.coherentFlags |= coherentFlags;
accessChain.alignment |= alignment;
// swizzles can be stacked in GLSL, but simplified to a single
// one here; the base type doesn't change
if (accessChain.preSwizzleBaseType == NoType)
@ -2459,7 +2547,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
}
// Comments in header
void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
assert(accessChain.isRValue == false);
@ -2477,11 +2565,17 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
}
createStore(source, base, memoryAccess, scope);
// take LSB of alignment
alignment = alignment & ~(alignment & (alignment-1));
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
createStore(source, base, memoryAccess, scope, alignment);
}
// Comments in header
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
Id id;
@ -2524,8 +2618,15 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
id = accessChain.base; // no precision, it was set when this was defined
} else {
transferAccessChainSwizzle(true);
// take LSB of alignment
alignment = alignment & ~(alignment & (alignment-1));
if (getStorageClass(accessChain.base) == StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
// load through the access chain
id = createLoad(collapseAccessChain(), memoryAccess, scope);
id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
setPrecision(id, precision);
addDecoration(id, nonUniform);
}

View File

@ -138,7 +138,9 @@ public:
// For creating new types (will return old type if the requested one was already made).
Id makeVoidType();
Id makeBoolType();
Id makePointer(StorageClass, Id type);
Id makePointer(StorageClass, Id pointee);
Id makeForwardPointer(StorageClass);
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
Id makeIntegerType(int width, bool hasSign); // generic
Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); }
@ -194,6 +196,7 @@ public:
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
bool isConstantOpCode(Op opcode) const;
bool isSpecConstantOpCode(Op opcode) const;
@ -300,10 +303,10 @@ public:
Id createUndefined(Id type);
// Store into an Id and return the l-value
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// Load from an Id and return it
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// Create an OpAccessChain instruction
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
@ -535,6 +538,7 @@ public:
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment.
// Accumulate whether anything in the chain of structures has coherent decorations.
struct CoherentFlags {
@ -601,31 +605,34 @@ public:
}
// push offset onto the end of the chain
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags)
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
{
accessChain.indexChain.push_back(offset);
accessChain.coherentFlags |= coherentFlags;
accessChain.alignment |= alignment;
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
// push a dynamic component selection onto the access chain, only applicable with a
// non-trivial swizzle or no swizzle
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
{
if (accessChain.swizzle.size() != 1) {
accessChain.component = component;
if (accessChain.preSwizzleBaseType == NoType)
accessChain.preSwizzleBaseType = preSwizzleBaseType;
}
accessChain.coherentFlags |= coherentFlags;
accessChain.alignment |= alignment;
}
// use accessChain and swizzle to store value
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// get the direct pointer for an l-value
Id accessChainGetLValue();
@ -639,7 +646,7 @@ public:
void postProcess();
// Hook to visit each instruction in a block in a function
void postProcess(const Instruction&);
void postProcess(Instruction&);
// Hook to visit each instruction in a reachable block in a function.
void postProcessReachable(const Instruction&);
// Hook to visit each non-32-bit sized float/int operation in a block.
@ -675,6 +682,7 @@ public:
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
void dumpModuleProcesses(std::vector<unsigned int>&) const;
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const;
unsigned int spvVersion; // the version of SPIR-V to emit in the header
SourceLanguage source;

View File

@ -87,6 +87,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
if (width == 8) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
@ -97,6 +98,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
}
} else if (width == 16) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
@ -151,7 +153,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
}
// Called for each instruction that resides in a block.
void Builder::postProcess(const Instruction& inst)
void Builder::postProcess(Instruction& inst)
{
// Add capabilities based simply on the opcode.
switch (inst.getOpCode()) {
@ -190,6 +192,88 @@ void Builder::postProcess(const Instruction& inst)
break;
#endif
case OpLoad:
case OpStore:
{
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
// index list to compute the misalignment. The pre-existing alignment value
// (set via Builder::AccessChain::alignment) only accounts for the base of
// the reference type and any scalar component selection in the accesschain,
// and this function computes the rest from the SPIR-V Offset decorations.
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
if (accessChain->getOpCode() == OpAccessChain) {
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
// Get the type of the base of the access chain. It must be a pointer type.
Id typeId = base->getTypeId();
Instruction *type = module.getInstruction(typeId);
assert(type->getOpCode() == OpTypePointer);
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
break;
}
// Get the pointee type.
typeId = type->getIdOperand(1);
type = module.getInstruction(typeId);
// Walk the index list for the access chain. For each index, find any
// misalignment that can apply when accessing the member/element via
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
// together.
int alignment = 0;
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
if (type->getOpCode() == OpTypeStruct) {
assert(idx->getOpCode() == OpConstant);
int c = idx->getImmediateOperand(0);
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpMemberDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == c &&
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
alignment |= decoration.get()->getImmediateOperand(3);
}
};
std::for_each(decorations.begin(), decorations.end(), function);
// get the next member type
typeId = type->getIdOperand(c);
type = module.getInstruction(typeId);
} else if (type->getOpCode() == OpTypeArray ||
type->getOpCode() == OpTypeRuntimeArray) {
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
alignment |= decoration.get()->getImmediateOperand(2);
}
};
std::for_each(decorations.begin(), decorations.end(), function);
// Get the element type
typeId = type->getIdOperand(0);
type = module.getInstruction(typeId);
} else {
// Once we get to any non-aggregate type, we're done.
break;
}
}
assert(inst.getNumOperands() >= 3);
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
assert(memoryAccess & MemoryAccessAlignedMask);
// Compute the index of the alignment operand.
int alignmentIdx = 2;
if (memoryAccess & MemoryAccessVolatileMask)
alignmentIdx++;
if (inst.getOpCode() == OpStore)
alignmentIdx++;
// Merge new and old (mis)alignment
alignment |= inst.getImmediateOperand(alignmentIdx);
// Pick the LSB
alignment = alignment & ~(alignment & (alignment-1));
// update the Aligned operand
inst.setImmediateOperand(alignmentIdx, alignment);
}
break;
}
default:
break;
}
@ -258,6 +342,47 @@ void Builder::postProcess()
Block* b = *bi;
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
postProcess(*ii->get());
// For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether
// there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the
// default.
for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) {
const Instruction& inst = *vi->get();
Id resultId = inst.getResultId();
if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) {
bool foundDecoration = false;
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getIdOperand(0) == resultId &&
decoration.get()->getOpCode() == OpDecorate &&
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
foundDecoration = true;
}
};
std::for_each(decorations.begin(), decorations.end(), function);
if (!foundDecoration) {
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
}
}
}
}
}
// Look for any 8/16 bit type in physical storage buffer class, and set the
// appropriate capability. This happens in createSpvVariable for other storage
// classes, but there isn't always a variable for physical storage buffer.
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
Instruction* type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
addExtension(spv::E_SPV_KHR_8bit_storage);
addCapability(spv::CapabilityStorageBuffer8BitAccess);
}
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
addExtension(spv::E_SPV_KHR_16bit_storage);
addCapability(spv::CapabilityStorageBuffer16BitAccess);
}
}
}
}

View File

@ -540,6 +540,14 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case OperandMemoryAccess:
outputMask(OperandMemoryAccess, stream[word++]);
--numOperands;
// Aligned is the only memory access operand that uses an immediate
// value, and it is also the first operand that uses a value at all.
if (stream[word-1] & MemoryAccessAlignedMask) {
disassembleImmediates(1);
numOperands--;
if (numOperands)
out << " ";
}
disassembleIds(numOperands);
return;
default:

View File

@ -124,6 +124,8 @@ const char* AddressingString(int addr)
case 1: return "Physical32";
case 2: return "Physical64";
case AddressingModelPhysicalStorageBuffer64EXT: return "PhysicalStorageBuffer64EXT";
default: return "Bad";
}
}
@ -220,6 +222,8 @@ const char* StorageClassString(int StorageClass)
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
#endif
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
default: return "Bad";
}
}
@ -295,6 +299,8 @@ const char* DecorationString(int decoration)
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
case DecorationRestrictPointerEXT: return "DecorationRestrictPointerEXT";
case DecorationAliasedPointerEXT: return "DecorationAliasedPointerEXT";
}
}
@ -922,6 +928,8 @@ const char* CapabilityString(int info)
case CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR";
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT";
default: return "Bad";
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 The Khronos Group Inc.
// Copyright (c) 2014-2019 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@ -26,14 +26,16 @@
// the Binary Section of the SPIR-V specification.
// Enumeration tokens for SPIR-V, in various styles:
// C, C++, C++11, JSON, Lua, Python, C#
// C, C++, C++11, JSON, Lua, Python, C#, D
//
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
// e.g.: Spv.Specification.SourceLanguage.GLSL
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
//
// Some tokens act like mask values, which can be OR'd together,
// while others are mutually exclusive. The mask-like ones have
@ -48,11 +50,11 @@ namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10300
#define SPV_REVISION 1
#define SPV_REVISION 6
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010300;
static const unsigned int Revision = 1;
static const unsigned int Revision = 6;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@ -89,6 +91,7 @@ enum AddressingModel {
AddressingModelLogical = 0,
AddressingModelPhysical32 = 1,
AddressingModelPhysical64 = 2,
AddressingModelPhysicalStorageBuffer64EXT = 5348,
AddressingModelMax = 0x7fffffff,
};
@ -140,6 +143,11 @@ enum ExecutionMode {
ExecutionModeLocalSizeId = 38,
ExecutionModeLocalSizeHintId = 39,
ExecutionModePostDepthCoverage = 4446,
ExecutionModeDenormPreserve = 4459,
ExecutionModeDenormFlushToZero = 4460,
ExecutionModeSignedZeroInfNanPreserve = 4461,
ExecutionModeRoundingModeRTE = 4462,
ExecutionModeRoundingModeRTZ = 4463,
ExecutionModeStencilRefReplacingEXT = 5027,
ExecutionModeOutputLinesNV = 5269,
ExecutionModeOutputPrimitivesNV = 5270,
@ -169,6 +177,7 @@ enum StorageClass {
StorageClassHitAttributeNV = 5339,
StorageClassIncomingRayPayloadNV = 5342,
StorageClassShaderRecordBufferNV = 5343,
StorageClassPhysicalStorageBufferEXT = 5349,
StorageClassMax = 0x7fffffff,
};
@ -417,6 +426,8 @@ enum Decoration {
DecorationMaxByteOffset = 45,
DecorationAlignmentId = 46,
DecorationMaxByteOffsetId = 47,
DecorationNoSignedWrap = 4469,
DecorationNoUnsignedWrap = 4470,
DecorationExplicitInterpAMD = 4999,
DecorationOverrideCoverageNV = 5248,
DecorationPassthroughNV = 5250,
@ -427,6 +438,8 @@ enum Decoration {
DecorationPerTaskNV = 5273,
DecorationPerVertexNV = 5285,
DecorationNonUniformEXT = 5300,
DecorationRestrictPointerEXT = 5355,
DecorationAliasedPointerEXT = 5356,
DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635,
DecorationMax = 0x7fffffff,
@ -756,6 +769,11 @@ enum Capability {
CapabilityStorageBuffer8BitAccess = 4448,
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
CapabilityStoragePushConstant8 = 4450,
CapabilityDenormPreserve = 4464,
CapabilityDenormFlushToZero = 4465,
CapabilitySignedZeroInfNanPreserve = 4466,
CapabilityRoundingModeRTE = 4467,
CapabilityRoundingModeRTZ = 4468,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
@ -791,6 +809,7 @@ enum Capability {
CapabilityRayTracingNV = 5340,
CapabilityVulkanMemoryModelKHR = 5345,
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
CapabilityComputeDerivativeGroupLinearNV = 5350,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,

View File

@ -102,6 +102,11 @@ public:
operands.push_back(immediate);
idOperand.push_back(false);
}
void setImmediateOperand(unsigned idx, unsigned int immediate) {
assert(!idOperand[idx]);
operands[idx] = immediate;
}
void addStringOperand(const char* str)
{
unsigned int word;
@ -203,6 +208,7 @@ public:
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
return instructions;
}
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
void setUnreachable() { unreachable = true; }
bool isUnreachable() const { return unreachable; }
// Returns the block's merge instruction, if one exists (otherwise null).

View File

@ -0,0 +1,104 @@
spv.bufferhandle1.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 52
Capability Shader
Capability CapabilityVulkanMemoryModelKHR
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
Extension "SPV_KHR_vulkan_memory_model"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT VulkanKHR
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 7 "t2"
MemberName 7(t2) 0 "f"
MemberName 7(t2) 1 "g"
Name 13 "blockType"
MemberName 13(blockType) 0 "a"
MemberName 13(blockType) 1 "b"
MemberName 13(blockType) 2 "c"
MemberName 13(blockType) 3 "d"
MemberName 13(blockType) 4 "e"
MemberName 13(blockType) 5 "f"
MemberName 13(blockType) 6 "g"
Name 15 "t"
Name 28 "j"
MemberDecorate 7(t2) 0 Offset 0
MemberDecorate 7(t2) 1 Offset 8
Decorate 7(t2) Block
Decorate 11 ArrayStride 4
MemberDecorate 13(blockType) 0 Offset 0
MemberDecorate 13(blockType) 1 Offset 4
MemberDecorate 13(blockType) 2 Offset 8
MemberDecorate 13(blockType) 3 Offset 12
MemberDecorate 13(blockType) 4 Offset 16
MemberDecorate 13(blockType) 5 Offset 32
MemberDecorate 13(blockType) 6 Offset 48
Decorate 13(blockType) Block
Decorate 15(t) DescriptorSet 0
Decorate 15(t) Binding 0
Decorate 28(j) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7(t2): TypeStruct 6 6
8: TypeInt 32 1
9: TypeInt 32 0
10: 9(int) Constant 2
11: TypeArray 8(int) 10
12: TypeVector 8(int) 4
13(blockType): TypeStruct 8(int) 8(int) 8(int) 8(int) 8(int) 11 12(ivec4)
6: TypePointer PhysicalStorageBufferEXT 13(blockType)
14: TypePointer StorageBuffer 7(t2)
15(t): 14(ptr) Variable StorageBuffer
16: 8(int) Constant 0
17: TypePointer StorageBuffer 6(ptr)
20: 8(int) Constant 1
23: TypePointer PhysicalStorageBufferEXT 8(int)
27: TypePointer Function 6(ptr)
32: 8(int) Constant 3
34: 8(int) Constant 2
40: 8(int) Constant 5
46: 8(int) Constant 6
47: 9(int) Constant 1
50: 9(int) Constant 5
4(main): 2 Function None 3
5: Label
28(j): 27(ptr) Variable Function
18: 17(ptr) AccessChain 15(t) 16
19: 6(ptr) Load 18
21: 17(ptr) AccessChain 15(t) 20
22: 6(ptr) Load 21
24: 23(ptr) AccessChain 22 16
25: 8(int) Load 24 Aligned 16
26: 23(ptr) AccessChain 19 20
Store 26 25 Aligned 4
29: 17(ptr) AccessChain 15(t) 16
30: 6(ptr) Load 29
Store 28(j) 30
31: 6(ptr) Load 28(j)
33: 6(ptr) Load 28(j)
35: 23(ptr) AccessChain 33 34
36: 8(int) Load 35 Aligned 8
37: 23(ptr) AccessChain 31 32
Store 37 36 Aligned 4
38: 6(ptr) Load 28(j)
39: 6(ptr) Load 28(j)
41: 23(ptr) AccessChain 39 40 20
42: 8(int) Load 41 Aligned 4
43: 23(ptr) AccessChain 38 32
Store 43 42 Aligned 4
44: 6(ptr) Load 28(j)
45: 6(ptr) Load 28(j)
48: 23(ptr) AccessChain 45 46 47
49: 8(int) Load 48 Aligned MakePointerVisibleKHR NonPrivatePointerKHR 4 50
51: 23(ptr) AccessChain 44 32
Store 51 49 Aligned 4
Return
FunctionEnd

View File

@ -0,0 +1,73 @@
spv.bufferhandle10.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 34
Capability Shader
Capability CapabilityVulkanMemoryModelKHR
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
Extension "SPV_KHR_vulkan_memory_model"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT VulkanKHR
EntryPoint Fragment 4 "main" 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_ARB_gpu_shader_int64"
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 7 "t2"
MemberName 7(t2) 0 "f"
Name 10 "blockType"
MemberName 10(blockType) 0 "x"
Name 12 "t"
Name 19 "i"
Name 28 "b"
MemberDecorate 7(t2) 0 Offset 0
Decorate 7(t2) Block
Decorate 9 ArrayStride 4
MemberDecorate 10(blockType) 0 Offset 0
Decorate 10(blockType) Block
Decorate 12(t) DescriptorSet 0
Decorate 12(t) Binding 0
Decorate 19(i) Flat
Decorate 19(i) Location 0
Decorate 28(b) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7(t2): TypeStruct 6
8: TypeInt 32 0
9: TypeRuntimeArray 8(int)
10(blockType): TypeStruct 9
6: TypePointer PhysicalStorageBufferEXT 10(blockType)
11: TypePointer StorageBuffer 7(t2)
12(t): 11(ptr) Variable StorageBuffer
13: TypeInt 32 1
14: 13(int) Constant 0
15: TypePointer StorageBuffer 6(ptr)
18: TypePointer Input 8(int)
19(i): 18(ptr) Variable Input
21: TypePointer PhysicalStorageBufferEXT 8(int)
23: 8(int) Constant 1
24: 8(int) Constant 5
25: 8(int) Constant 0
27: TypePointer Function 6(ptr)
32: 8(int) Constant 2
4(main): 2 Function None 3
5: Label
28(b): 27(ptr) Variable Function
16: 15(ptr) AccessChain 12(t) 14
17: 6(ptr) Load 16
20: 8(int) Load 19(i)
22: 21(ptr) AccessChain 17 14 20
26: 8(int) AtomicIAdd 22 24 25 23
29: 15(ptr) AccessChain 12(t) 14
30: 6(ptr) Load 29
Store 28(b) 30
31: 6(ptr) Load 28(b)
33: 21(ptr) AccessChain 31 14 14
Store 33 32 Aligned MakePointerAvailableKHR NonPrivatePointerKHR 4 24
Return
FunctionEnd

View File

@ -0,0 +1,118 @@
spv.bufferhandle11.frag
WARNING: 0:6: '' : all default precisions are highp; use precision statements to quiet warning, e.g.:
"precision mediump int; precision highp float;"
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 60
Capability Shader
Capability CapabilityStorageBuffer8BitAccess
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_8bit_storage"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
SourceExtension "GL_EXT_shader_16bit_storage"
SourceExtension "GL_EXT_shader_8bit_storage"
Name 4 "main"
Name 12 "compare_uint8_t(u1;u1;"
Name 10 "a"
Name 11 "b"
Name 20 "allOk"
Name 26 "PC"
MemberName 26(PC) 0 "block"
Name 28 "Block"
MemberName 28(Block) 0 "var"
Name 30 ""
Name 41 "param"
Name 42 "param"
Name 48 "AcBlock"
MemberName 48(AcBlock) 0 "ac_numPassed"
Name 50 ""
MemberDecorate 26(PC) 0 Offset 0
Decorate 26(PC) Block
MemberDecorate 28(Block) 0 Offset 0
Decorate 28(Block) Block
MemberDecorate 48(AcBlock) 0 Offset 0
Decorate 48(AcBlock) Block
Decorate 50 DescriptorSet 0
Decorate 50 Binding 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
7: TypePointer Function 6(int)
8: TypeBool
9: TypeFunction 8(bool) 7(ptr) 7(ptr)
19: TypePointer Function 8(bool)
21: 8(bool) ConstantTrue
TypeForwardPointer 25 PhysicalStorageBufferEXT
26(PC): TypeStruct 25
27: TypeInt 8 0
28(Block): TypeStruct 27(int8_t)
25: TypePointer PhysicalStorageBufferEXT 28(Block)
29: TypePointer PushConstant 26(PC)
30: 29(ptr) Variable PushConstant
31: TypeInt 32 1
32: 31(int) Constant 0
33: TypePointer PushConstant 25(ptr)
36: TypePointer PhysicalStorageBufferEXT 27(int8_t)
40: 6(int) Constant 7
48(AcBlock): TypeStruct 6(int)
49: TypePointer StorageBuffer 48(AcBlock)
50: 49(ptr) Variable StorageBuffer
51: TypePointer StorageBuffer 6(int)
54: 31(int) Constant 1
58: 27(int8_t) Constant 9
4(main): 2 Function None 3
5: Label
20(allOk): 19(ptr) Variable Function
41(param): 7(ptr) Variable Function
42(param): 7(ptr) Variable Function
Store 20(allOk) 21
22: 8(bool) Load 20(allOk)
SelectionMerge 24 None
BranchConditional 22 23 24
23: Label
34: 33(ptr) AccessChain 30 32
35: 25(ptr) Load 34
37: 36(ptr) AccessChain 35 32
38: 27(int8_t) Load 37 Aligned 16
39: 6(int) UConvert 38
Store 41(param) 39
Store 42(param) 40
43: 8(bool) FunctionCall 12(compare_uint8_t(u1;u1;) 41(param) 42(param)
Branch 24
24: Label
44: 8(bool) Phi 22 5 43 23
Store 20(allOk) 44
45: 8(bool) Load 20(allOk)
SelectionMerge 47 None
BranchConditional 45 46 47
46: Label
52: 51(ptr) AccessChain 50 32
53: 6(int) Load 52
55: 6(int) IAdd 53 54
Store 52 55
Branch 47
47: Label
56: 33(ptr) AccessChain 30 32
57: 25(ptr) Load 56
59: 36(ptr) AccessChain 57 32
Store 59 58 Aligned 16
Return
FunctionEnd
12(compare_uint8_t(u1;u1;): 8(bool) Function None 9
10(a): 7(ptr) FunctionParameter
11(b): 7(ptr) FunctionParameter
13: Label
14: 6(int) Load 10(a)
15: 6(int) Load 11(b)
16: 8(bool) IEqual 14 15
ReturnValue 16
FunctionEnd

View File

@ -0,0 +1,306 @@
spv.bufferhandle12.frag
WARNING: 0:6: '' : all default precisions are highp; use precision statements to quiet warning, e.g.:
"precision mediump int; precision highp float;"
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 183
Capability Shader
Capability StorageUniformBufferBlock16
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_16bit_storage"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
SourceExtension "GL_EXT_shader_16bit_storage"
SourceExtension "GL_EXT_shader_8bit_storage"
Name 4 "main"
Name 12 "compare_float(f1;f1;"
Name 10 "a"
Name 11 "b"
Name 19 "compare_vec3(vf3;vf3;"
Name 17 "a"
Name 18 "b"
Name 26 "compare_mat2x3(mf23;mf23;"
Name 24 "a"
Name 25 "b"
Name 34 "compare_ivec2(vi2;vi2;"
Name 32 "a"
Name 33 "b"
Name 42 "compare_uvec3(vu3;vu3;"
Name 40 "a"
Name 41 "b"
Name 46 "compare_float16_t(f1;f1;"
Name 44 "a"
Name 45 "b"
Name 56 "param"
Name 60 "param"
Name 66 "param"
Name 70 "param"
Name 77 "param"
Name 81 "param"
Name 89 "param"
Name 92 "param"
Name 99 "param"
Name 102 "param"
Name 131 "allOk"
Name 139 "PC"
MemberName 139(PC) 0 "blockB"
MemberName 139(PC) 1 "blockC"
MemberName 139(PC) 2 "blockD"
Name 141 "BlockB"
MemberName 141(BlockB) 0 "a"
MemberName 141(BlockB) 1 "b"
Name 142 "BlockC"
MemberName 142(BlockC) 0 "c"
Name 143 "BlockD"
MemberName 143(BlockD) 0 "d"
Name 145 ""
Name 157 "param"
Name 161 "param"
Name 167 "AcBlock"
MemberName 167(AcBlock) 0 "ac_numPassed"
Name 169 ""
MemberDecorate 139(PC) 0 Offset 0
MemberDecorate 139(PC) 1 Offset 8
MemberDecorate 139(PC) 2 Offset 16
Decorate 139(PC) Block
MemberDecorate 141(BlockB) 0 Offset 0
MemberDecorate 141(BlockB) 1 Offset 8
Decorate 141(BlockB) Block
MemberDecorate 142(BlockC) 0 ColMajor
MemberDecorate 142(BlockC) 0 RelaxedPrecision
MemberDecorate 142(BlockC) 0 Offset 0
MemberDecorate 142(BlockC) 0 MatrixStride 16
Decorate 142(BlockC) Block
MemberDecorate 143(BlockD) 0 RelaxedPrecision
MemberDecorate 143(BlockD) 0 Offset 0
Decorate 143(BlockD) Block
Decorate 160 RelaxedPrecision
MemberDecorate 167(AcBlock) 0 Offset 0
Decorate 167(AcBlock) Block
Decorate 169 DescriptorSet 0
Decorate 169 Binding 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypePointer Function 6(float)
8: TypeBool
9: TypeFunction 8(bool) 7(ptr) 7(ptr)
14: TypeVector 6(float) 3
15: TypePointer Function 14(fvec3)
16: TypeFunction 8(bool) 15(ptr) 15(ptr)
21: TypeMatrix 14(fvec3) 2
22: TypePointer Function 21
23: TypeFunction 8(bool) 22(ptr) 22(ptr)
28: TypeInt 32 1
29: TypeVector 28(int) 2
30: TypePointer Function 29(ivec2)
31: TypeFunction 8(bool) 30(ptr) 30(ptr)
36: TypeInt 32 0
37: TypeVector 36(int) 3
38: TypePointer Function 37(ivec3)
39: TypeFunction 8(bool) 38(ptr) 38(ptr)
52: 6(float) Constant 1028443341
57: 36(int) Constant 0
67: 36(int) Constant 1
78: 36(int) Constant 2
88: 28(int) Constant 0
98: 28(int) Constant 1
111: TypeVector 8(bool) 2
118: TypeVector 8(bool) 3
130: TypePointer Function 8(bool)
132: 8(bool) ConstantTrue
TypeForwardPointer 136 PhysicalStorageBufferEXT
TypeForwardPointer 137 PhysicalStorageBufferEXT
TypeForwardPointer 138 PhysicalStorageBufferEXT
139(PC): TypeStruct 136 137 138
140: TypeFloat 16
141(BlockB): TypeStruct 140(float16_t) 29(ivec2)
136: TypePointer PhysicalStorageBufferEXT 141(BlockB)
142(BlockC): TypeStruct 21
137: TypePointer PhysicalStorageBufferEXT 142(BlockC)
143(BlockD): TypeStruct 37(ivec3)
138: TypePointer PhysicalStorageBufferEXT 143(BlockD)
144: TypePointer PushConstant 139(PC)
145: 144(ptr) Variable PushConstant
146: TypePointer PushConstant 137(ptr)
149: 6(float) Constant 3231711232
150: 6(float) Constant 1065353216
151: 6(float) Constant 3235905536
152: 14(fvec3) ConstantComposite 149 150 151
153: 6(float) Constant 1073741824
154: 6(float) Constant 1090519040
155: 14(fvec3) ConstantComposite 150 153 154
156: 21 ConstantComposite 152 155
158: TypePointer PhysicalStorageBufferEXT 21
167(AcBlock): TypeStruct 36(int)
168: TypePointer StorageBuffer 167(AcBlock)
169: 168(ptr) Variable StorageBuffer
170: TypePointer StorageBuffer 36(int)
174: 28(int) Constant 2
175: TypePointer PushConstant 138(ptr)
178: 36(int) Constant 8
179: 36(int) Constant 5
180: 37(ivec3) ConstantComposite 178 67 179
181: TypePointer PhysicalStorageBufferEXT 37(ivec3)
4(main): 2 Function None 3
5: Label
131(allOk): 130(ptr) Variable Function
157(param): 22(ptr) Variable Function
161(param): 22(ptr) Variable Function
Store 131(allOk) 132
133: 8(bool) Load 131(allOk)
SelectionMerge 135 None
BranchConditional 133 134 135
134: Label
147: 146(ptr) AccessChain 145 98
148: 137(ptr) Load 147
159: 158(ptr) AccessChain 148 88
160: 21 Load 159 Aligned 16
Store 157(param) 160
Store 161(param) 156
162: 8(bool) FunctionCall 26(compare_mat2x3(mf23;mf23;) 157(param) 161(param)
Branch 135
135: Label
163: 8(bool) Phi 133 5 162 134
Store 131(allOk) 163
164: 8(bool) Load 131(allOk)
SelectionMerge 166 None
BranchConditional 164 165 166
165: Label
171: 170(ptr) AccessChain 169 88
172: 36(int) Load 171
173: 36(int) IAdd 172 98
Store 171 173
Branch 166
166: Label
176: 175(ptr) AccessChain 145 174
177: 138(ptr) Load 176
182: 181(ptr) AccessChain 177 88
Store 182 180 Aligned 16
Return
FunctionEnd
12(compare_float(f1;f1;): 8(bool) Function None 9
10(a): 7(ptr) FunctionParameter
11(b): 7(ptr) FunctionParameter
13: Label
48: 6(float) Load 10(a)
49: 6(float) Load 11(b)
50: 6(float) FSub 48 49
51: 6(float) ExtInst 1(GLSL.std.450) 4(FAbs) 50
53: 8(bool) FOrdLessThan 51 52
ReturnValue 53
FunctionEnd
19(compare_vec3(vf3;vf3;): 8(bool) Function None 16
17(a): 15(ptr) FunctionParameter
18(b): 15(ptr) FunctionParameter
20: Label
56(param): 7(ptr) Variable Function
60(param): 7(ptr) Variable Function
66(param): 7(ptr) Variable Function
70(param): 7(ptr) Variable Function
77(param): 7(ptr) Variable Function
81(param): 7(ptr) Variable Function
58: 7(ptr) AccessChain 17(a) 57
59: 6(float) Load 58
Store 56(param) 59
61: 7(ptr) AccessChain 18(b) 57
62: 6(float) Load 61
Store 60(param) 62
63: 8(bool) FunctionCall 12(compare_float(f1;f1;) 56(param) 60(param)
SelectionMerge 65 None
BranchConditional 63 64 65
64: Label
68: 7(ptr) AccessChain 17(a) 67
69: 6(float) Load 68
Store 66(param) 69
71: 7(ptr) AccessChain 18(b) 67
72: 6(float) Load 71
Store 70(param) 72
73: 8(bool) FunctionCall 12(compare_float(f1;f1;) 66(param) 70(param)
Branch 65
65: Label
74: 8(bool) Phi 63 20 73 64
SelectionMerge 76 None
BranchConditional 74 75 76
75: Label
79: 7(ptr) AccessChain 17(a) 78
80: 6(float) Load 79
Store 77(param) 80
82: 7(ptr) AccessChain 18(b) 78
83: 6(float) Load 82
Store 81(param) 83
84: 8(bool) FunctionCall 12(compare_float(f1;f1;) 77(param) 81(param)
Branch 76
76: Label
85: 8(bool) Phi 74 65 84 75
ReturnValue 85
FunctionEnd
26(compare_mat2x3(mf23;mf23;): 8(bool) Function None 23
24(a): 22(ptr) FunctionParameter
25(b): 22(ptr) FunctionParameter
27: Label
89(param): 15(ptr) Variable Function
92(param): 15(ptr) Variable Function
99(param): 15(ptr) Variable Function
102(param): 15(ptr) Variable Function
90: 15(ptr) AccessChain 24(a) 88
91: 14(fvec3) Load 90
Store 89(param) 91
93: 15(ptr) AccessChain 25(b) 88
94: 14(fvec3) Load 93
Store 92(param) 94
95: 8(bool) FunctionCall 19(compare_vec3(vf3;vf3;) 89(param) 92(param)
SelectionMerge 97 None
BranchConditional 95 96 97
96: Label
100: 15(ptr) AccessChain 24(a) 98
101: 14(fvec3) Load 100
Store 99(param) 101
103: 15(ptr) AccessChain 25(b) 98
104: 14(fvec3) Load 103
Store 102(param) 104
105: 8(bool) FunctionCall 19(compare_vec3(vf3;vf3;) 99(param) 102(param)
Branch 97
97: Label
106: 8(bool) Phi 95 27 105 96
ReturnValue 106
FunctionEnd
34(compare_ivec2(vi2;vi2;): 8(bool) Function None 31
32(a): 30(ptr) FunctionParameter
33(b): 30(ptr) FunctionParameter
35: Label
109: 29(ivec2) Load 32(a)
110: 29(ivec2) Load 33(b)
112: 111(bvec2) IEqual 109 110
113: 8(bool) All 112
ReturnValue 113
FunctionEnd
42(compare_uvec3(vu3;vu3;): 8(bool) Function None 39
40(a): 38(ptr) FunctionParameter
41(b): 38(ptr) FunctionParameter
43: Label
116: 37(ivec3) Load 40(a)
117: 37(ivec3) Load 41(b)
119: 118(bvec3) IEqual 116 117
120: 8(bool) All 119
ReturnValue 120
FunctionEnd
46(compare_float16_t(f1;f1;): 8(bool) Function None 9
44(a): 7(ptr) FunctionParameter
45(b): 7(ptr) FunctionParameter
47: Label
123: 6(float) Load 44(a)
124: 6(float) Load 45(b)
125: 6(float) FSub 123 124
126: 6(float) ExtInst 1(GLSL.std.450) 4(FAbs) 125
127: 8(bool) FOrdLessThan 126 52
ReturnValue 127
FunctionEnd

View File

@ -0,0 +1,118 @@
spv.bufferhandle13.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 58
Capability Shader
Capability CapabilityVulkanMemoryModelKHR
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
Extension "SPV_KHR_vulkan_memory_model"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT VulkanKHR
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "t4"
MemberName 8(t4) 0 "j"
Name 11 "f1(1;"
Name 10 "y"
Name 16 "f2(1;"
Name 15 "y"
Name 19 "f3(1;"
Name 18 "y"
Name 22 "f4(1;"
Name 21 "y"
Name 34 "a"
Name 35 "t5"
MemberName 35(t5) 0 "m"
Name 37 "s5"
Name 42 "b"
Name 47 "param"
Name 52 "param"
Name 56 "g1"
Name 57 "g2"
MemberDecorate 8(t4) 0 Offset 0
Decorate 8(t4) Block
Decorate 10(y) Aliased
Decorate 15(y) DecorationAliasedPointerEXT
Decorate 18(y) Restrict
Decorate 18(y) Restrict
Decorate 21(y) Restrict
Decorate 21(y) DecorationRestrictPointerEXT
Decorate 34(a) DecorationAliasedPointerEXT
MemberDecorate 35(t5) 0 Offset 0
Decorate 35(t5) Block
Decorate 37(s5) DescriptorSet 0
Decorate 37(s5) Binding 0
Decorate 42(b) DecorationRestrictPointerEXT
Decorate 56(g1) DecorationAliasedPointerEXT
Decorate 57(g2) DecorationRestrictPointerEXT
Decorate 47(param) DecorationAliasedPointerEXT
Decorate 52(param) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7: TypeInt 32 1
8(t4): TypeStruct 7(int)
6: TypePointer PhysicalStorageBufferEXT 8(t4)
9: TypeFunction 6(ptr) 6(ptr)
13: TypePointer Function 6(ptr)
14: TypeFunction 6(ptr) 13(ptr)
35(t5): TypeStruct 6(ptr)
36: TypePointer StorageBuffer 35(t5)
37(s5): 36(ptr) Variable StorageBuffer
38: 7(int) Constant 0
39: TypePointer StorageBuffer 6(ptr)
55: TypePointer Private 6(ptr)
56(g1): 55(ptr) Variable Private
4(main): 2 Function None 3
5: Label
34(a): 13(ptr) Variable Function
42(b): 13(ptr) Variable Function
47(param): 13(ptr) Variable Function
52(param): 13(ptr) Variable Function
57(g2): 13(ptr) Variable Function
40: 39(ptr) AccessChain 37(s5) 38
41: 6(ptr) Load 40
Store 34(a) 41
43: 39(ptr) AccessChain 37(s5) 38
44: 6(ptr) Load 43
Store 42(b) 44
45: 6(ptr) Load 34(a)
46: 6(ptr) FunctionCall 11(f1(1;) 45
48: 6(ptr) Load 34(a)
Store 47(param) 48
49: 6(ptr) FunctionCall 16(f2(1;) 47(param)
50: 6(ptr) Load 34(a)
51: 6(ptr) FunctionCall 19(f3(1;) 50
53: 6(ptr) Load 34(a)
Store 52(param) 53
54: 6(ptr) FunctionCall 22(f4(1;) 52(param)
Return
FunctionEnd
11(f1(1;): 6(ptr) Function None 9
10(y): 6(ptr) FunctionParameter
12: Label
ReturnValue 10(y)
FunctionEnd
16(f2(1;): 6(ptr) Function None 14
15(y): 13(ptr) FunctionParameter
17: Label
26: 6(ptr) Load 15(y)
ReturnValue 26
FunctionEnd
19(f3(1;): 6(ptr) Function None 9
18(y): 6(ptr) FunctionParameter
20: Label
ReturnValue 18(y)
FunctionEnd
22(f4(1;): 6(ptr) Function None 14
21(y): 13(ptr) FunctionParameter
23: Label
31: 6(ptr) Load 21(y)
ReturnValue 31
FunctionEnd

View File

@ -0,0 +1,109 @@
spv.bufferhandle14.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 46
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "T1"
MemberName 8(T1) 0 "i"
MemberName 8(T1) 1 "j"
MemberName 8(T1) 2 "k"
Name 10 "t1"
Name 20 "T2"
MemberName 20(T2) 0 "i"
MemberName 20(T2) 1 "j"
MemberName 20(T2) 2 "k"
Name 22 "t2"
Name 29 "T3"
MemberName 29(T3) 0 "i"
MemberName 29(T3) 1 "j"
MemberName 29(T3) 2 "k"
Name 31 "t3"
Name 38 "T4"
MemberName 38(T4) 0 "i"
MemberName 38(T4) 1 "j"
MemberName 38(T4) 2 "k"
Name 40 "t4"
MemberDecorate 8(T1) 0 Offset 0
MemberDecorate 8(T1) 1 Offset 4
MemberDecorate 8(T1) 2 Offset 8
Decorate 8(T1) Block
Decorate 10(t1) DecorationAliasedPointerEXT
MemberDecorate 20(T2) 0 Offset 0
MemberDecorate 20(T2) 1 Offset 4
MemberDecorate 20(T2) 2 Offset 8
Decorate 20(T2) Block
Decorate 22(t2) DecorationAliasedPointerEXT
MemberDecorate 29(T3) 0 Offset 0
MemberDecorate 29(T3) 1 Offset 4
MemberDecorate 29(T3) 2 Offset 8
Decorate 29(T3) Block
Decorate 31(t3) DecorationAliasedPointerEXT
MemberDecorate 38(T4) 0 Offset 0
MemberDecorate 38(T4) 1 Offset 4
MemberDecorate 38(T4) 2 Offset 8
Decorate 38(T4) Block
Decorate 40(t4) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7: TypeInt 32 1
8(T1): TypeStruct 7(int) 7(int) 7(int)
6: TypePointer PhysicalStorageBufferEXT 8(T1)
9: TypePointer Function 6(ptr)
12: 7(int) Constant 0
14: 7(int) Constant 2
15: TypePointer PhysicalStorageBufferEXT 7(int)
TypeForwardPointer 19 PhysicalStorageBufferEXT
20(T2): TypeStruct 7(int) 7(int) 7(int)
19: TypePointer PhysicalStorageBufferEXT 20(T2)
21: TypePointer Function 19(ptr)
TypeForwardPointer 28 PhysicalStorageBufferEXT
29(T3): TypeStruct 7(int) 7(int) 7(int)
28: TypePointer PhysicalStorageBufferEXT 29(T3)
30: TypePointer Function 28(ptr)
TypeForwardPointer 37 PhysicalStorageBufferEXT
38(T4): TypeStruct 7(int) 7(int) 7(int)
37: TypePointer PhysicalStorageBufferEXT 38(T4)
39: TypePointer Function 37(ptr)
4(main): 2 Function None 3
5: Label
10(t1): 9(ptr) Variable Function
22(t2): 21(ptr) Variable Function
31(t3): 30(ptr) Variable Function
40(t4): 39(ptr) Variable Function
11: 6(ptr) Load 10(t1)
13: 6(ptr) Load 10(t1)
16: 15(ptr) AccessChain 13 14
17: 7(int) Load 16 Aligned 4
18: 15(ptr) AccessChain 11 12
Store 18 17 Aligned 4
23: 19(ptr) Load 22(t2)
24: 19(ptr) Load 22(t2)
25: 15(ptr) AccessChain 24 14
26: 7(int) Load 25 Aligned 8
27: 15(ptr) AccessChain 23 12
Store 27 26 Aligned 8
32: 28(ptr) Load 31(t3)
33: 28(ptr) Load 31(t3)
34: 15(ptr) AccessChain 33 14
35: 7(int) Load 34 Aligned 8
36: 15(ptr) AccessChain 32 12
Store 36 35 Aligned 16
41: 37(ptr) Load 40(t4)
42: 37(ptr) Load 40(t4)
43: 15(ptr) AccessChain 42 14
44: 7(int) Load 43 Aligned 8
45: 15(ptr) AccessChain 41 12
Store 45 44 Aligned 32
Return
FunctionEnd

View File

@ -0,0 +1,130 @@
spv.bufferhandle15.frag
WARNING: 0:16: '' : all default precisions are highp; use precision statements to quiet warning, e.g.:
"precision mediump int; precision highp float;"
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 60
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main" 37
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
SourceExtension "GL_EXT_scalar_block_layout"
Name 4 "main"
Name 9 "y"
Name 13 "T4"
MemberName 13(T4) 0 "t1"
MemberName 13(T4) 1 "t2"
MemberName 13(T4) 2 "t3"
Name 15 "T1"
MemberName 15(T1) 0 "x"
Name 22 "T2"
MemberName 22(T2) 0 "x"
Name 28 "S"
MemberName 28(S) 0 "a"
MemberName 28(S) 1 "b"
MemberName 28(S) 2 "c"
Name 29 "T3"
MemberName 29(T3) 0 "s"
Name 31 "t4"
Name 37 "i"
Name 52 "z"
MemberDecorate 13(T4) 0 Offset 0
MemberDecorate 13(T4) 1 Offset 8
MemberDecorate 13(T4) 2 Offset 16
Decorate 13(T4) Block
Decorate 14 ArrayStride 12
MemberDecorate 15(T1) 0 Offset 0
Decorate 15(T1) Block
Decorate 18 ArrayStride 12
Decorate 20 ArrayStride 24
Decorate 21 ArrayStride 96
MemberDecorate 22(T2) 0 Offset 0
Decorate 22(T2) Block
Decorate 26 ArrayStride 36
MemberDecorate 28(S) 0 Offset 0
MemberDecorate 28(S) 1 ColMajor
MemberDecorate 28(S) 1 RelaxedPrecision
MemberDecorate 28(S) 1 Offset 12
MemberDecorate 28(S) 1 MatrixStride 12
MemberDecorate 28(S) 2 Offset 156
MemberDecorate 29(T3) 0 Offset 0
Decorate 29(T3) Block
Decorate 31(t4) DescriptorSet 0
Decorate 31(t4) Binding 0
Decorate 37(i) Flat
Decorate 37(i) Location 0
Decorate 59 RelaxedPrecision
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8: TypePointer Function 7(fvec3)
TypeForwardPointer 10 PhysicalStorageBufferEXT
TypeForwardPointer 11 PhysicalStorageBufferEXT
TypeForwardPointer 12 PhysicalStorageBufferEXT
13(T4): TypeStruct 10 11 12
14: TypeRuntimeArray 7(fvec3)
15(T1): TypeStruct 14
10: TypePointer PhysicalStorageBufferEXT 15(T1)
16: TypeInt 32 0
17: 16(int) Constant 2
18: TypeArray 7(fvec3) 17
19: 16(int) Constant 4
20: TypeArray 18 19
21: TypeRuntimeArray 20
22(T2): TypeStruct 21
11: TypePointer PhysicalStorageBufferEXT 22(T2)
23: TypeInt 32 1
24: TypeVector 23(int) 3
25: TypeMatrix 7(fvec3) 3
26: TypeArray 25 19
27: TypeVector 6(float) 4
28(S): TypeStruct 24(ivec3) 26 27(fvec4)
29(T3): TypeStruct 28(S)
12: TypePointer PhysicalStorageBufferEXT 29(T3)
30: TypePointer StorageBuffer 13(T4)
31(t4): 30(ptr) Variable StorageBuffer
32: 23(int) Constant 0
33: TypePointer StorageBuffer 10(ptr)
36: TypePointer Input 23(int)
37(i): 36(ptr) Variable Input
39: TypePointer PhysicalStorageBufferEXT 7(fvec3)
42: 23(int) Constant 1
43: TypePointer StorageBuffer 11(ptr)
51: TypePointer Function 25
53: 23(int) Constant 2
54: TypePointer StorageBuffer 12(ptr)
57: TypePointer PhysicalStorageBufferEXT 25
4(main): 2 Function None 3
5: Label
9(y): 8(ptr) Variable Function
52(z): 51(ptr) Variable Function
34: 33(ptr) AccessChain 31(t4) 32
35: 10(ptr) Load 34
38: 23(int) Load 37(i)
40: 39(ptr) AccessChain 35 32 38
41: 7(fvec3) Load 40 Aligned 4
Store 9(y) 41
44: 43(ptr) AccessChain 31(t4) 42
45: 11(ptr) Load 44
46: 23(int) Load 37(i)
47: 23(int) Load 37(i)
48: 23(int) Load 37(i)
49: 39(ptr) AccessChain 45 32 46 47 48
50: 7(fvec3) Load 49 Aligned 4
Store 9(y) 50
55: 54(ptr) AccessChain 31(t4) 53
56: 12(ptr) Load 55
58: 57(ptr) AccessChain 56 32 42 32
59: 25 Load 58 Aligned 4
Store 52(z) 59
Return
FunctionEnd

View File

@ -0,0 +1,94 @@
spv.bufferhandle2.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 45
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "blockType"
MemberName 8(blockType) 0 "a"
MemberName 8(blockType) 1 "b"
MemberName 8(blockType) 2 "c"
MemberName 8(blockType) 3 "d"
MemberName 8(blockType) 4 "e"
Name 13 "b1"
Name 14 "t2"
MemberName 14(t2) 0 "f"
MemberName 14(t2) 1 "g"
Name 16 "t"
Name 34 "b2"
Name 37 "b3"
MemberDecorate 8(blockType) 0 Offset 0
MemberDecorate 8(blockType) 1 Offset 4
MemberDecorate 8(blockType) 2 Offset 8
MemberDecorate 8(blockType) 3 Offset 12
MemberDecorate 8(blockType) 4 Offset 16
Decorate 8(blockType) Block
Decorate 13(b1) DecorationAliasedPointerEXT
MemberDecorate 14(t2) 0 Offset 0
MemberDecorate 14(t2) 1 Offset 8
Decorate 14(t2) Block
Decorate 16(t) DescriptorSet 0
Decorate 16(t) Binding 0
Decorate 34(b2) DecorationAliasedPointerEXT
Decorate 37(b3) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7: TypeInt 32 1
8(blockType): TypeStruct 7(int) 7(int) 7(int) 7(int) 7(int)
6: TypePointer PhysicalStorageBufferEXT 8(blockType)
9: TypeInt 32 0
10: 9(int) Constant 2
11: TypeArray 6(ptr) 10
12: TypePointer Function 11
14(t2): TypeStruct 6(ptr) 6(ptr)
15: TypePointer StorageBuffer 14(t2)
16(t): 15(ptr) Variable StorageBuffer
17: 7(int) Constant 0
18: TypePointer StorageBuffer 6(ptr)
21: 7(int) Constant 1
25: TypePointer Function 6(ptr)
30: TypePointer PhysicalStorageBufferEXT 7(int)
4(main): 2 Function None 3
5: Label
13(b1): 12(ptr) Variable Function
34(b2): 25(ptr) Variable Function
37(b3): 25(ptr) Variable Function
19: 18(ptr) AccessChain 16(t) 17
20: 6(ptr) Load 19
22: 18(ptr) AccessChain 16(t) 21
23: 6(ptr) Load 22
24: 11 CompositeConstruct 20 23
Store 13(b1) 24
26: 25(ptr) AccessChain 13(b1) 17
27: 6(ptr) Load 26
28: 25(ptr) AccessChain 13(b1) 21
29: 6(ptr) Load 28
31: 30(ptr) AccessChain 29 21
32: 7(int) Load 31 Aligned 4
33: 30(ptr) AccessChain 27 17
Store 33 32 Aligned 16
35: 18(ptr) AccessChain 16(t) 17
36: 6(ptr) Load 35
Store 34(b2) 36
38: 18(ptr) AccessChain 16(t) 21
39: 6(ptr) Load 38
Store 37(b3) 39
40: 6(ptr) Load 34(b2)
41: 6(ptr) Load 37(b3)
42: 30(ptr) AccessChain 41 21
43: 7(int) Load 42 Aligned 4
44: 30(ptr) AccessChain 40 17
Store 44 43 Aligned 16
Return
FunctionEnd

View File

@ -0,0 +1,105 @@
spv.bufferhandle3.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 50
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main" 42
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 9 "t4"
MemberName 9(t4) 0 "j"
MemberName 9(t4) 1 "k"
Name 10 "t3"
MemberName 10(t3) 0 "h"
Name 14 "foo(1;"
Name 13 "y"
Name 19 "t5"
MemberName 19(t5) 0 "m"
Name 21 "s5"
Name 23 "param"
Name 38 "t4"
MemberName 38(t4) 0 "j"
MemberName 38(t4) 1 "k"
Name 40 "x"
Name 42 "k"
MemberDecorate 9(t4) 0 Offset 0
MemberDecorate 9(t4) 1 Offset 8
Decorate 9(t4) Block
MemberDecorate 10(t3) 0 Offset 0
Decorate 10(t3) Block
Decorate 13(y) DecorationAliasedPointerEXT
MemberDecorate 19(t5) 0 Offset 0
Decorate 19(t5) Block
Decorate 21(s5) DescriptorSet 0
Decorate 21(s5) Binding 0
MemberDecorate 38(t4) 0 Offset 0
MemberDecorate 38(t4) 1 Offset 8
Decorate 38(t4) Block
Decorate 40(x) DescriptorSet 1
Decorate 40(x) Binding 2
Decorate 42(k) Flat
Decorate 42(k) DecorationAliasedPointerEXT
Decorate 23(param) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7: TypeInt 32 1
TypeForwardPointer 8 PhysicalStorageBufferEXT
9(t4): TypeStruct 7(int) 8
10(t3): TypeStruct 7(int)
8: TypePointer PhysicalStorageBufferEXT 10(t3)
6: TypePointer PhysicalStorageBufferEXT 9(t4)
11: TypePointer Function 6(ptr)
12: TypeFunction 6(ptr) 11(ptr)
19(t5): TypeStruct 6(ptr)
20: TypePointer StorageBuffer 19(t5)
21(s5): 20(ptr) Variable StorageBuffer
22: 7(int) Constant 0
24: TypePointer StorageBuffer 6(ptr)
30: 7(int) Constant 1
31: TypePointer PhysicalStorageBufferEXT 8(ptr)
34: TypePointer PhysicalStorageBufferEXT 7(int)
38(t4): TypeStruct 7(int) 8(ptr)
39: TypePointer StorageBuffer 38(t4)
40(x): 39(ptr) Variable StorageBuffer
41: TypePointer Input 6(ptr)
42(k): 41(ptr) Variable Input
48: TypePointer StorageBuffer 7(int)
4(main): 2 Function None 3
5: Label
23(param): 11(ptr) Variable Function
25: 24(ptr) AccessChain 21(s5) 22
26: 6(ptr) Load 25
Store 23(param) 26
27: 6(ptr) FunctionCall 14(foo(1;) 23(param)
28: 24(ptr) AccessChain 21(s5) 22
29: 6(ptr) Load 28
32: 31(ptr) AccessChain 29 30
33: 8(ptr) Load 32 Aligned 8
35: 34(ptr) AccessChain 33 22
36: 7(int) Load 35 Aligned 16
37: 34(ptr) AccessChain 27 22
Store 37 36 Aligned 16
43: 6(ptr) Load 42(k)
44: 31(ptr) AccessChain 43 30
45: 8(ptr) Load 44 Aligned 8
46: 34(ptr) AccessChain 45 22
47: 7(int) Load 46 Aligned 16
49: 48(ptr) AccessChain 40(x) 22
Store 49 47
Return
FunctionEnd
14(foo(1;): 6(ptr) Function None 12
13(y): 11(ptr) FunctionParameter
15: Label
16: 6(ptr) Load 13(y)
ReturnValue 16
FunctionEnd

View File

@ -0,0 +1,118 @@
spv.bufferhandle4.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 61
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "t4"
MemberName 8(t4) 0 "j"
MemberName 8(t4) 1 "k"
Name 10 "t3"
MemberName 10(t3) 0 "h"
MemberName 10(t3) 1 "i"
Name 11 "t4"
MemberName 11(t4) 0 "j"
MemberName 11(t4) 1 "k"
Name 13 "x"
Name 19 "t5"
MemberName 19(t5) 0 "m"
Name 21 "s5"
Name 43 "b"
MemberDecorate 8(t4) 0 Offset 0
MemberDecorate 8(t4) 1 Offset 8
Decorate 8(t4) Block
MemberDecorate 10(t3) 0 Offset 0
MemberDecorate 10(t3) 1 Offset 8
Decorate 10(t3) Block
MemberDecorate 11(t4) 0 Offset 0
MemberDecorate 11(t4) 1 Offset 8
Decorate 11(t4) Block
Decorate 13(x) DescriptorSet 1
Decorate 13(x) Binding 2
MemberDecorate 19(t5) 0 Offset 0
Decorate 19(t5) Block
Decorate 21(s5) DescriptorSet 0
Decorate 21(s5) Binding 0
Decorate 47 DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
TypeForwardPointer 7 PhysicalStorageBufferEXT
8(t4): TypeStruct 6(int) 7
TypeForwardPointer 9 PhysicalStorageBufferEXT
10(t3): TypeStruct 6(int) 9
11(t4): TypeStruct 6(int) 7
9: TypePointer PhysicalStorageBufferEXT 11(t4)
7: TypePointer PhysicalStorageBufferEXT 10(t3)
12: TypePointer StorageBuffer 8(t4)
13(x): 12(ptr) Variable StorageBuffer
14: 6(int) Constant 1
15: TypePointer StorageBuffer 7(ptr)
18: 6(int) Constant 0
19(t5): TypeStruct 9(ptr)
20: TypePointer StorageBuffer 19(t5)
21(s5): 20(ptr) Variable StorageBuffer
22: TypePointer StorageBuffer 9(ptr)
25: TypePointer PhysicalStorageBufferEXT 7(ptr)
28: TypePointer PhysicalStorageBufferEXT 9(ptr)
37: TypePointer PhysicalStorageBufferEXT 6(int)
41: TypeBool
42: TypePointer Function 41(bool)
44: 41(bool) ConstantTrue
46: TypePointer Function 9(ptr)
4(main): 2 Function None 3
5: Label
43(b): 42(ptr) Variable Function
47: 46(ptr) Variable Function
16: 15(ptr) AccessChain 13(x) 14
17: 7(ptr) Load 16
23: 22(ptr) AccessChain 21(s5) 18
24: 9(ptr) Load 23
26: 25(ptr) AccessChain 24 14
27: 7(ptr) Load 26 Aligned 8
29: 28(ptr) AccessChain 27 14
30: 9(ptr) Load 29 Aligned 8
31: 25(ptr) AccessChain 30 14
32: 7(ptr) Load 31 Aligned 8
33: 28(ptr) AccessChain 32 14
34: 9(ptr) Load 33 Aligned 8
35: 25(ptr) AccessChain 34 14
36: 7(ptr) Load 35 Aligned 8
38: 37(ptr) AccessChain 36 18
39: 6(int) Load 38 Aligned 16
40: 37(ptr) AccessChain 17 18
Store 40 39 Aligned 16
Store 43(b) 44
45: 41(bool) Load 43(b)
SelectionMerge 49 None
BranchConditional 45 48 52
48: Label
50: 22(ptr) AccessChain 21(s5) 18
51: 9(ptr) Load 50
Store 47 51
Branch 49
52: Label
53: 22(ptr) AccessChain 21(s5) 18
54: 9(ptr) Load 53
55: 25(ptr) AccessChain 54 14
56: 7(ptr) Load 55 Aligned 8
57: 28(ptr) AccessChain 56 14
58: 9(ptr) Load 57 Aligned 8
Store 47 58
Branch 49
49: Label
59: 9(ptr) Load 47
60: 22(ptr) AccessChain 21(s5) 18
Store 60 59
Return
FunctionEnd

View File

@ -0,0 +1,52 @@
spv.bufferhandle5.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 22
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "t4"
MemberName 8(t4) 0 "j"
MemberName 8(t4) 1 "k"
Name 9 "t3"
MemberName 9(t3) 0 "h"
Name 11 "x"
MemberDecorate 8(t4) 0 Offset 0
MemberDecorate 8(t4) 1 Offset 8
Decorate 8(t4) Block
MemberDecorate 9(t3) 0 Offset 0
Decorate 9(t3) Block
Decorate 11(x) DescriptorSet 1
Decorate 11(x) Binding 2
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
TypeForwardPointer 7 PhysicalStorageBufferEXT
8(t4): TypeStruct 6(int) 7
9(t3): TypeStruct 6(int)
7: TypePointer PhysicalStorageBufferEXT 9(t3)
10: TypePointer Uniform 8(t4)
11(x): 10(ptr) Variable Uniform
12: 6(int) Constant 1
13: TypePointer Uniform 7(ptr)
16: 6(int) Constant 0
17: TypePointer Uniform 6(int)
20: TypePointer PhysicalStorageBufferEXT 6(int)
4(main): 2 Function None 3
5: Label
14: 13(ptr) AccessChain 11(x) 12
15: 7(ptr) Load 14
18: 17(ptr) AccessChain 11(x) 16
19: 6(int) Load 18
21: 20(ptr) AccessChain 15 16
Store 21 19 Aligned 16
Return
FunctionEnd

View File

@ -0,0 +1,238 @@
spv.bufferhandle6.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 165
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main" 154
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "accum"
Name 15 "T1"
MemberName 15(T1) 0 "a"
MemberName 15(T1) 1 "b"
MemberName 15(T1) 2 "c"
MemberName 15(T1) 3 "d"
Name 18 "T1"
MemberName 18(T1) 0 "a"
MemberName 18(T1) 1 "b"
MemberName 18(T1) 2 "c"
MemberName 18(T1) 3 "d"
Name 21 "x"
Name 30 "Block"
MemberName 30(Block) 0 "identity"
Name 32 "pc"
Name 136 "color"
Name 149 "image0_0"
Name 154 "gl_FragCoord"
Decorate 12 ArrayStride 4
Decorate 14 ArrayStride 8
MemberDecorate 15(T1) 0 Offset 0
MemberDecorate 15(T1) 1 Offset 32
MemberDecorate 15(T1) 2 Offset 48
MemberDecorate 15(T1) 3 Offset 80
Decorate 15(T1) Block
Decorate 16 ArrayStride 4
Decorate 17 ArrayStride 8
MemberDecorate 18(T1) 0 Offset 0
MemberDecorate 18(T1) 1 Offset 32
MemberDecorate 18(T1) 2 Offset 48
MemberDecorate 18(T1) 3 Offset 80
Decorate 18(T1) Block
Decorate 19 ArrayStride 8
Decorate 21(x) DescriptorSet 3
Decorate 21(x) Binding 1
Decorate 29 ArrayStride 4
MemberDecorate 30(Block) 0 Offset 0
Decorate 30(Block) Block
Decorate 149(image0_0) DescriptorSet 3
Decorate 149(image0_0) Binding 0
Decorate 154(gl_FragCoord) BuiltIn FragCoord
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
10: TypeInt 32 0
11: 10(int) Constant 2
12: TypeArray 6(int) 11
TypeForwardPointer 13 PhysicalStorageBufferEXT
14: TypeArray 13 11
15(T1): TypeStruct 12 6(int) 14 13
16: TypeArray 6(int) 11
17: TypeArray 13 11
18(T1): TypeStruct 16 6(int) 17 13
13: TypePointer PhysicalStorageBufferEXT 18(T1)
19: TypeArray 13(ptr) 11
20: TypePointer StorageBuffer 15(T1)
21(x): 20(ptr) Variable StorageBuffer
22: TypePointer StorageBuffer 6(int)
28: 10(int) Constant 32
29: TypeArray 6(int) 28
30(Block): TypeStruct 29
31: TypePointer PushConstant 30(Block)
32(pc): 31(ptr) Variable PushConstant
33: 6(int) Constant 1
34: TypePointer PushConstant 6(int)
44: 6(int) Constant 2
48: TypePointer StorageBuffer 13(ptr)
51: TypePointer PhysicalStorageBufferEXT 6(int)
54: 6(int) Constant 3
64: 6(int) Constant 4
72: 6(int) Constant 5
82: 6(int) Constant 6
94: 6(int) Constant 7
104: 6(int) Constant 8
112: 6(int) Constant 9
122: 6(int) Constant 10
130: 6(int) Constant 11
134: TypeVector 10(int) 4
135: TypePointer Function 134(ivec4)
138: TypeBool
140: 10(int) Constant 0
141: 134(ivec4) ConstantComposite 140 140 140 140
142: 10(int) Constant 1
143: 134(ivec4) ConstantComposite 142 140 140 142
144: TypeVector 138(bool) 4
147: TypeImage 10(int) 2D nonsampled format:R32ui
148: TypePointer UniformConstant 147
149(image0_0): 148(ptr) Variable UniformConstant
151: TypeFloat 32
152: TypeVector 151(float) 4
153: TypePointer Input 152(fvec4)
154(gl_FragCoord): 153(ptr) Variable Input
155: TypePointer Input 151(float)
162: TypeVector 6(int) 2
4(main): 2 Function None 3
5: Label
8(accum): 7(ptr) Variable Function
136(color): 135(ptr) Variable Function
Store 8(accum) 9
23: 22(ptr) AccessChain 21(x) 9 9
24: 6(int) Load 23
25: 6(int) ISub 24 9
26: 6(int) Load 8(accum)
27: 6(int) BitwiseOr 26 25
Store 8(accum) 27
35: 34(ptr) AccessChain 32(pc) 9 33
36: 6(int) Load 35
37: 22(ptr) AccessChain 21(x) 9 36
38: 6(int) Load 37
39: 6(int) ISub 38 33
40: 6(int) Load 8(accum)
41: 6(int) BitwiseOr 40 39
Store 8(accum) 41
42: 22(ptr) AccessChain 21(x) 33
43: 6(int) Load 42
45: 6(int) ISub 43 44
46: 6(int) Load 8(accum)
47: 6(int) BitwiseOr 46 45
Store 8(accum) 47
49: 48(ptr) AccessChain 21(x) 44 9
50: 13(ptr) Load 49
52: 51(ptr) AccessChain 50 9 9
53: 6(int) Load 52 Aligned 4
55: 6(int) ISub 53 54
56: 6(int) Load 8(accum)
57: 6(int) BitwiseOr 56 55
Store 8(accum) 57
58: 48(ptr) AccessChain 21(x) 44 9
59: 13(ptr) Load 58
60: 34(ptr) AccessChain 32(pc) 9 33
61: 6(int) Load 60
62: 51(ptr) AccessChain 59 9 61
63: 6(int) Load 62 Aligned 4
65: 6(int) ISub 63 64
66: 6(int) Load 8(accum)
67: 6(int) BitwiseOr 66 65
Store 8(accum) 67
68: 48(ptr) AccessChain 21(x) 44 9
69: 13(ptr) Load 68
70: 51(ptr) AccessChain 69 33
71: 6(int) Load 70 Aligned 16
73: 6(int) ISub 71 72
74: 6(int) Load 8(accum)
75: 6(int) BitwiseOr 74 73
Store 8(accum) 75
76: 34(ptr) AccessChain 32(pc) 9 33
77: 6(int) Load 76
78: 48(ptr) AccessChain 21(x) 44 77
79: 13(ptr) Load 78
80: 51(ptr) AccessChain 79 9 9
81: 6(int) Load 80 Aligned 4
83: 6(int) ISub 81 82
84: 6(int) Load 8(accum)
85: 6(int) BitwiseOr 84 83
Store 8(accum) 85
86: 34(ptr) AccessChain 32(pc) 9 33
87: 6(int) Load 86
88: 48(ptr) AccessChain 21(x) 44 87
89: 13(ptr) Load 88
90: 34(ptr) AccessChain 32(pc) 9 33
91: 6(int) Load 90
92: 51(ptr) AccessChain 89 9 91
93: 6(int) Load 92 Aligned 4
95: 6(int) ISub 93 94
96: 6(int) Load 8(accum)
97: 6(int) BitwiseOr 96 95
Store 8(accum) 97
98: 34(ptr) AccessChain 32(pc) 9 33
99: 6(int) Load 98
100: 48(ptr) AccessChain 21(x) 44 99
101: 13(ptr) Load 100
102: 51(ptr) AccessChain 101 33
103: 6(int) Load 102 Aligned 16
105: 6(int) ISub 103 104
106: 6(int) Load 8(accum)
107: 6(int) BitwiseOr 106 105
Store 8(accum) 107
108: 48(ptr) AccessChain 21(x) 54
109: 13(ptr) Load 108
110: 51(ptr) AccessChain 109 9 9
111: 6(int) Load 110 Aligned 4
113: 6(int) ISub 111 112
114: 6(int) Load 8(accum)
115: 6(int) BitwiseOr 114 113
Store 8(accum) 115
116: 48(ptr) AccessChain 21(x) 54
117: 13(ptr) Load 116
118: 34(ptr) AccessChain 32(pc) 9 33
119: 6(int) Load 118
120: 51(ptr) AccessChain 117 9 119
121: 6(int) Load 120 Aligned 4
123: 6(int) ISub 121 122
124: 6(int) Load 8(accum)
125: 6(int) BitwiseOr 124 123
Store 8(accum) 125
126: 48(ptr) AccessChain 21(x) 54
127: 13(ptr) Load 126
128: 51(ptr) AccessChain 127 33
129: 6(int) Load 128 Aligned 16
131: 6(int) ISub 129 130
132: 6(int) Load 8(accum)
133: 6(int) BitwiseOr 132 131
Store 8(accum) 133
137: 6(int) Load 8(accum)
139: 138(bool) INotEqual 137 9
145: 144(bvec4) CompositeConstruct 139 139 139 139
146: 134(ivec4) Select 145 141 143
Store 136(color) 146
150: 147 Load 149(image0_0)
156: 155(ptr) AccessChain 154(gl_FragCoord) 140
157: 151(float) Load 156
158: 6(int) ConvertFToS 157
159: 155(ptr) AccessChain 154(gl_FragCoord) 142
160: 151(float) Load 159
161: 6(int) ConvertFToS 160
163: 162(ivec2) CompositeConstruct 158 161
164: 134(ivec4) Load 136(color)
ImageWrite 150 163 164
Return
FunctionEnd

View File

@ -0,0 +1,77 @@
spv.bufferhandle7.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 24
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 7 "t2"
MemberName 7(t2) 0 "f"
MemberName 7(t2) 1 "g"
Name 9 "blockType"
MemberName 9(blockType) 0 "a"
MemberName 9(blockType) 1 "b"
MemberName 9(blockType) 2 "c"
MemberName 9(blockType) 3 "d"
MemberName 9(blockType) 4 "e"
Name 11 "t"
Name 14 "t3"
MemberName 14(t3) 0 "f"
Name 15 "t2"
MemberName 15(t2) 0 "f"
MemberName 15(t2) 1 "g"
Name 17 "u"
MemberDecorate 7(t2) 0 Offset 0
MemberDecorate 7(t2) 1 Offset 8
Decorate 7(t2) Block
MemberDecorate 9(blockType) 0 Offset 0
MemberDecorate 9(blockType) 1 Offset 4
MemberDecorate 9(blockType) 2 Offset 8
MemberDecorate 9(blockType) 3 Offset 12
MemberDecorate 9(blockType) 4 Offset 16
Decorate 9(blockType) Block
Decorate 11(t) DescriptorSet 0
Decorate 11(t) Binding 0
MemberDecorate 14(t3) 0 Offset 0
Decorate 14(t3) Block
MemberDecorate 15(t2) 0 Offset 0
MemberDecorate 15(t2) 1 Offset 8
Decorate 15(t2) Block
Decorate 17(u) DescriptorSet 0
Decorate 17(u) Binding 0
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7(t2): TypeStruct 6 6
8: TypeInt 32 1
9(blockType): TypeStruct 8(int) 8(int) 8(int) 8(int) 8(int)
6: TypePointer PhysicalStorageBufferEXT 9(blockType)
10: TypePointer StorageBuffer 7(t2)
11(t): 10(ptr) Variable StorageBuffer
12: 8(int) Constant 0
TypeForwardPointer 13 PhysicalStorageBufferEXT
14(t3): TypeStruct 13
15(t2): TypeStruct 6(ptr) 6(ptr)
13: TypePointer PhysicalStorageBufferEXT 15(t2)
16: TypePointer StorageBuffer 14(t3)
17(u): 16(ptr) Variable StorageBuffer
18: TypePointer StorageBuffer 13(ptr)
22: TypePointer StorageBuffer 6(ptr)
4(main): 2 Function None 3
5: Label
19: 18(ptr) AccessChain 17(u) 12
20: 13(ptr) Load 19
21: 6(ptr) Bitcast 20
23: 22(ptr) AccessChain 11(t) 12
Store 23 21
Return
FunctionEnd

View File

@ -0,0 +1,89 @@
spv.bufferhandle8.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 27
Capability Shader
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "Blah"
MemberName 8(Blah) 0 "t1"
MemberName 8(Blah) 1 "t2"
Name 10 "T1"
MemberName 10(T1) 0 "x"
Name 11 "T2"
MemberName 11(T2) 0 "x"
Name 13 "T3"
MemberName 13(T3) 0 "Bindings"
Name 15 "t3"
Name 23 "t2"
MemberName 23(t2) 0 "f"
MemberName 23(t2) 1 "g"
Name 24 "blockType"
MemberName 24(blockType) 0 "a"
MemberName 24(blockType) 1 "b"
MemberName 24(blockType) 2 "c"
MemberName 24(blockType) 3 "d"
MemberName 24(blockType) 4 "e"
Name 26 "t"
MemberDecorate 8(Blah) 0 Offset 0
MemberDecorate 8(Blah) 1 Offset 8
MemberDecorate 10(T1) 0 Offset 0
Decorate 10(T1) Block
MemberDecorate 11(T2) 0 Offset 0
Decorate 11(T2) Block
Decorate 12 ArrayStride 16
MemberDecorate 13(T3) 0 Offset 0
Decorate 13(T3) Block
Decorate 15(t3) DescriptorSet 0
Decorate 15(t3) Binding 0
MemberDecorate 23(t2) 0 Offset 0
MemberDecorate 23(t2) 1 Offset 8
Decorate 23(t2) Block
MemberDecorate 24(blockType) 0 Offset 0
MemberDecorate 24(blockType) 1 Offset 4
MemberDecorate 24(blockType) 2 Offset 8
MemberDecorate 24(blockType) 3 Offset 12
MemberDecorate 24(blockType) 4 Offset 16
Decorate 24(blockType) Block
Decorate 26(t) DescriptorSet 0
Decorate 26(t) Binding 0
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
TypeForwardPointer 7 PhysicalStorageBufferEXT
8(Blah): TypeStruct 6 7
9: TypeInt 32 1
10(T1): TypeStruct 9(int)
6: TypePointer PhysicalStorageBufferEXT 10(T1)
11(T2): TypeStruct 9(int)
7: TypePointer PhysicalStorageBufferEXT 11(T2)
12: TypeRuntimeArray 8(Blah)
13(T3): TypeStruct 12
14: TypePointer StorageBuffer 13(T3)
15(t3): 14(ptr) Variable StorageBuffer
16: 9(int) Constant 0
17: 9(int) Constant 1
18: TypePointer StorageBuffer 8(Blah)
TypeForwardPointer 22 PhysicalStorageBufferEXT
23(t2): TypeStruct 22 22
24(blockType): TypeStruct 9(int) 9(int) 9(int) 9(int) 9(int)
22: TypePointer PhysicalStorageBufferEXT 24(blockType)
25: TypePointer StorageBuffer 23(t2)
26(t): 25(ptr) Variable StorageBuffer
4(main): 2 Function None 3
5: Label
19: 18(ptr) AccessChain 15(t3) 16 17
20: 8(Blah) Load 19
21: 18(ptr) AccessChain 15(t3) 16 16
Store 21 20
Return
FunctionEnd

View File

@ -0,0 +1,114 @@
spv.bufferhandle9.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 56
Capability Shader
Capability Int64
Capability CapabilityPhysicalStorageBufferAddressesEXT
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_storage_buffer_storage_class"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT GLSL450
EntryPoint Fragment 4 "main" 16 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_ARB_gpu_shader_int64"
SourceExtension "GL_EXT_buffer_reference"
Name 4 "main"
Name 8 "blockType"
MemberName 8(blockType) 0 "a"
MemberName 8(blockType) 1 "b"
MemberName 8(blockType) 2 "c"
MemberName 8(blockType) 3 "d"
MemberName 8(blockType) 4 "e"
Name 13 "b1"
Name 16 "h"
Name 19 "i"
Name 34 "b2"
Name 37 "b3"
Name 46 "j"
Name 53 "t2"
MemberName 53(t2) 0 "f"
MemberName 53(t2) 1 "g"
Name 55 "t"
MemberDecorate 8(blockType) 0 Offset 0
MemberDecorate 8(blockType) 1 Offset 4
MemberDecorate 8(blockType) 2 Offset 8
MemberDecorate 8(blockType) 3 Offset 12
MemberDecorate 8(blockType) 4 Offset 16
Decorate 8(blockType) Block
Decorate 13(b1) DecorationAliasedPointerEXT
Decorate 16(h) Flat
Decorate 19(i) Flat
Decorate 34(b2) DecorationAliasedPointerEXT
Decorate 37(b3) DecorationAliasedPointerEXT
MemberDecorate 53(t2) 0 Offset 0
MemberDecorate 53(t2) 1 Offset 8
Decorate 53(t2) Block
Decorate 55(t) DescriptorSet 0
Decorate 55(t) Binding 0
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
7: TypeInt 32 1
8(blockType): TypeStruct 7(int) 7(int) 7(int) 7(int) 7(int)
6: TypePointer PhysicalStorageBufferEXT 8(blockType)
9: TypeInt 32 0
10: 9(int) Constant 2
11: TypeArray 6(ptr) 10
12: TypePointer Function 11
14: TypeInt 64 0
15: TypePointer Input 14(int64_t)
16(h): 15(ptr) Variable Input
19(i): 15(ptr) Variable Input
23: 7(int) Constant 0
24: TypePointer Function 6(ptr)
27: 7(int) Constant 1
30: TypePointer PhysicalStorageBufferEXT 7(int)
45: TypePointer Function 14(int64_t)
50: 14(int64_t) Constant 256 0
53(t2): TypeStruct 6(ptr) 6(ptr)
54: TypePointer StorageBuffer 53(t2)
55(t): 54(ptr) Variable StorageBuffer
4(main): 2 Function None 3
5: Label
13(b1): 12(ptr) Variable Function
34(b2): 24(ptr) Variable Function
37(b3): 24(ptr) Variable Function
46(j): 45(ptr) Variable Function
17: 14(int64_t) Load 16(h)
18: 6(ptr) ConvertUToPtr 17
20: 14(int64_t) Load 19(i)
21: 6(ptr) ConvertUToPtr 20
22: 11 CompositeConstruct 18 21
Store 13(b1) 22
25: 24(ptr) AccessChain 13(b1) 23
26: 6(ptr) Load 25
28: 24(ptr) AccessChain 13(b1) 27
29: 6(ptr) Load 28
31: 30(ptr) AccessChain 29 27
32: 7(int) Load 31 Aligned 4
33: 30(ptr) AccessChain 26 23
Store 33 32 Aligned 16
35: 14(int64_t) Load 16(h)
36: 6(ptr) ConvertUToPtr 35
Store 34(b2) 36
38: 14(int64_t) Load 19(i)
39: 6(ptr) ConvertUToPtr 38
Store 37(b3) 39
40: 6(ptr) Load 34(b2)
41: 6(ptr) Load 37(b3)
42: 30(ptr) AccessChain 41 27
43: 7(int) Load 42 Aligned 4
44: 30(ptr) AccessChain 40 23
Store 44 43 Aligned 16
47: 6(ptr) Load 34(b2)
48: 14(int64_t) ConvertPtrToU 47
Store 46(j) 48
49: 14(int64_t) Load 46(j)
51: 14(int64_t) IAdd 49 50
52: 6(ptr) ConvertUToPtr 51
Store 34(b2) 52
Return
FunctionEnd

View File

@ -0,0 +1,25 @@
spv.bufferhandle_Error.frag
ERROR: 0:7: 'buffer_reference' : can only be used with buffer
ERROR: 0:9: 'buffer_reference' : cannot declare a default, can only be used on a block
ERROR: 0:10: 'buffer_reference' : can only be used with buffer
ERROR: 0:10: 'buffer_reference' : cannot declare a default, can only be used on a block
ERROR: 0:11: 'buffer_reference' : can only be used with buffer
ERROR: 0:11: 'buffer_reference' : cannot declare a default, can only be used on a block
ERROR: 0:12: 'buffer_reference' : can only be used with buffer
ERROR: 0:12: 'buffer_reference' : cannot declare a default, can only be used on a block
ERROR: 0:13: 'buffer_reference' : can only be used with buffer
ERROR: 0:13: 'buffer_reference' : can only be used with buffer
ERROR: 0:14: 'output block' : not supported in this stage: fragment
ERROR: 0:14: 'buffer_reference' : can only be used with buffer
ERROR: 0:14: 'buffer_reference' : can only be used with buffer
ERROR: 0:30: 'length' : array must be declared with a size before using this method
ERROR: 0:31: 'length' : array must be declared with a size before using this method
ERROR: 0:35: '=' : cannot convert from 'layout( column_major std430) buffer reference' to ' temp reference'
ERROR: 0:40: 'assign' : cannot convert from 'layout( column_major std430) buffer reference' to 'layout( column_major std430) buffer reference'
ERROR: 0:41: 'assign' : cannot convert from 'layout( column_major std430) buffer reference' to 'layout( column_major std430) buffer reference'
ERROR: 0:42: 'assign' : cannot convert from 'layout( column_major std430) buffer reference' to 'layout( column_major std430) buffer reference'
ERROR: 0:45: '' : syntax error, unexpected LEFT_BRACE, expecting COMMA or SEMICOLON
ERROR: 20 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,28 @@
#version 450
#extension GL_EXT_buffer_reference : enable
#pragma use_vulkan_memory_model
layout(buffer_reference, std430) buffer blockType {
layout(offset = 0) int a;
layout(offset = 4) int b;
layout(offset = 8) int c;
layout(offset = 12) int d;
layout(offset = 16) int e;
layout(offset = 32) int f[2];
coherent layout(offset = 48) ivec4 g;
};
layout(std430) buffer t2 {
blockType f;
blockType g;
} t;
void main() {
t.f.b = t.g.a;
blockType j = t.f;
j.d = j.c;
j.d = j.f[1];
j.d = j.g.y;
}

View File

@ -0,0 +1,23 @@
#version 450
#extension GL_ARB_gpu_shader_int64 : enable
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer blockType {
uint x[];
};
layout(std430) buffer t2 {
blockType f;
} t;
layout(location = 0) flat in uint i;
void main() {
atomicAdd(t.f.x[i], 1);
coherent blockType b = t.f;
b.x[0] = 2;
}

View File

@ -0,0 +1,26 @@
#version 450
#extension GL_EXT_shader_16bit_storage : enable
#extension GL_EXT_shader_8bit_storage : enable
#extension GL_EXT_buffer_reference : enable
layout(std140, binding = 0) buffer AcBlock { highp uint ac_numPassed; };
layout(std140, buffer_reference) buffer Block
{
uint8_t var;
};
layout (push_constant, std430) uniform PC {
Block block;
};
bool compare_uint8_t (highp uint a, highp uint b) { return a == b; }
void main (void)
{
bool allOk = true;
allOk = allOk && compare_uint8_t(uint(block.var), 7u);
if (allOk)
ac_numPassed++;
block.var = uint8_t(9u);
}

View File

@ -0,0 +1,42 @@
#version 450
#extension GL_EXT_shader_16bit_storage : enable
#extension GL_EXT_shader_8bit_storage : enable
#extension GL_EXT_buffer_reference : enable
layout(std140, binding = 0) buffer AcBlock { highp uint ac_numPassed; };
layout(std430, column_major, buffer_reference) buffer BlockB
{
float16_t a;
highp ivec2 b;
};
layout(std430, buffer_reference) buffer BlockC
{
mediump mat2x3 c;
};
layout(std430, row_major, buffer_reference) buffer BlockD
{
lowp uvec3 d;
};
layout (push_constant, std430) uniform PC {
BlockB blockB;
BlockC blockC;
BlockD blockD;
};
bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }
bool compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z); }
bool compare_mat2x3 (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1]); }
bool compare_ivec2 (highp ivec2 a, highp ivec2 b) { return a == b; }
bool compare_uvec3 (highp uvec3 a, highp uvec3 b) { return a == b; }
bool compare_float16_t(highp float a, highp float b) { return abs(a - b) < 0.05; }
void main (void)
{
bool allOk = true;
allOk = allOk && compare_mat2x3(blockC.c, mat2x3(-5.0, 1.0, -7.0, 1.0, 2.0, 8.0));
if (allOk)
ac_numPassed++;
blockD.d = (uvec3(8u, 1u, 5u));
}

View File

@ -0,0 +1,30 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(set = 1, binding = 2, buffer_reference, std430) buffer t4 {
layout(offset = 0) int j;
};
layout(std430) buffer t5 {
t4 m;
} s5;
t4 f1(const t4 y) { return y; }
t4 f2(t4 y) { return y; }
t4 f3(const restrict t4 y) { return y; }
t4 f4(restrict t4 y) { return y; }
t4 g1;
restrict t4 g2;
void main()
{
t4 a = s5.m;
restrict t4 b = s5.m;
f1(a);
f2(a);
f3(a);
f4(a);
}

View File

@ -0,0 +1,40 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430, buffer_reference_align = 4) buffer T1 {
int i;
int j;
int k;
};
layout(buffer_reference, std430, buffer_reference_align = 8) buffer T2 {
int i;
int j;
int k;
};
layout(buffer_reference, std430) buffer T3 {
int i;
int j;
int k;
};
layout(buffer_reference, std430, buffer_reference_align = 32) buffer T4 {
int i;
int j;
int k;
};
void main()
{
T1 t1;
T2 t2;
T3 t3;
T4 t4;
t1.i = t1.k;
t2.i = t2.k;
t3.i = t3.k;
t4.i = t4.k;
}

View File

@ -0,0 +1,38 @@
#version 450
#extension GL_EXT_buffer_reference : enable
#extension GL_EXT_scalar_block_layout : enable
layout(buffer_reference, scalar) buffer T1 {
vec3 x[];
};
layout(buffer_reference, scalar) buffer T2 {
vec3 x[][4][2];
};
struct S
{
highp ivec3 a;
mediump mat3 b[4];
highp vec4 c;
};
layout(buffer_reference, scalar) buffer T3 {
S s;
};
layout(std430) buffer T4 {
T1 t1;
T2 t2;
T3 t3;
} t4;
layout(location = 0) flat in int i;
void main()
{
vec3 y;
y = t4.t1.x[i];
y = t4.t2.x[i][i][i];
mat3 z = t4.t3.s.b[0];
}

View File

@ -0,0 +1,25 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer blockType {
layout(offset = 0) int a;
layout(offset = 4) int b;
layout(offset = 8) int c;
layout(offset = 12) int d;
layout(offset = 16) int e;
};
layout(std430) buffer t2 {
blockType f;
blockType g;
} t;
void main() {
blockType b1[2] = blockType[2](t.f, t.g);
b1[0].a = b1[1].b;
blockType b2 = t.f;
blockType b3 = t.g;
b2.a = b3.b;
}

View File

@ -0,0 +1,25 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer t3 {
int h;
};
layout(set = 1, binding = 2, buffer_reference, std430) buffer t4 {
layout(offset = 0) int j;
t3 k;
} x;
layout(std430) buffer t5 {
t4 m;
} s5;
flat in t4 k;
t4 foo(t4 y) { return y; }
void main() {
foo(s5.m).j = s5.m.k.h;
x.j = k.k.h;
}

View File

@ -0,0 +1,26 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference) buffer t4;
layout(buffer_reference, std430) buffer t3 {
int h;
t4 i;
};
layout(set = 1, binding = 2, buffer_reference, std430) buffer t4 {
layout(offset = 0) int j;
t3 k;
} x;
layout(std430) buffer t5 {
t4 m;
} s5;
void main() {
x.k.h = s5.m.k.i.k.i.k.h;
bool b = true;
s5.m = b ? s5.m : s5.m.k.i;
}

View File

@ -0,0 +1,16 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std140) buffer t3 {
int h;
};
layout(set = 1, binding = 2, std140) uniform t4 {
layout(offset = 0) int j;
t3 k;
} x;
void main() {
x.k.h = x.j;
}

View File

@ -0,0 +1,30 @@
#version 450 core
#extension GL_EXT_buffer_reference : enable
layout (push_constant, std430) uniform Block { int identity[32]; } pc;
layout(r32ui, set = 3, binding = 0) uniform uimage2D image0_0;
layout(buffer_reference) buffer T1;
layout(set = 3, binding = 1, buffer_reference) buffer T1 {
layout(offset = 0) int a[2]; // stride = 4 for std430, 16 for std140
layout(offset = 32) int b;
layout(offset = 48) T1 c[2]; // stride = 8 for std430, 16 for std140
layout(offset = 80) T1 d;
} x;
void main()
{
int accum = 0, temp;
accum |= x.a[0] - 0;
accum |= x.a[pc.identity[1]] - 1;
accum |= x.b - 2;
accum |= x.c[0].a[0] - 3;
accum |= x.c[0].a[pc.identity[1]] - 4;
accum |= x.c[0].b - 5;
accum |= x.c[pc.identity[1]].a[0] - 6;
accum |= x.c[pc.identity[1]].a[pc.identity[1]] - 7;
accum |= x.c[pc.identity[1]].b - 8;
accum |= x.d.a[0] - 9;
accum |= x.d.a[pc.identity[1]] - 10;
accum |= x.d.b - 11;
uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);
imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);
}

View File

@ -0,0 +1,24 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer blockType {
layout(offset = 0) int a;
layout(offset = 4) int b;
layout(offset = 8) int c;
layout(offset = 12) int d;
layout(offset = 16) int e;
};
layout(std430, buffer_reference) buffer t2 {
blockType f;
blockType g;
} t;
layout(std430) buffer t3 {
t2 f;
} u;
void main() {
t.f = blockType(u.f);
}

View File

@ -0,0 +1,32 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer blockType {
layout(offset = 0) int a;
layout(offset = 4) int b;
layout(offset = 8) int c;
layout(offset = 12) int d;
layout(offset = 16) int e;
};
layout(std430) buffer t2 {
blockType f;
blockType g;
} t;
layout(std430, buffer_reference) buffer T2 { int x; };
layout(std430, buffer_reference) buffer T1 { int x; };
struct Blah {
T1 t1;
T2 t2;
};
layout(set=0, binding=0) buffer T3 {
Blah Bindings[];
} t3;
void main() {
t3.Bindings[0] = t3.Bindings[1];
}

View File

@ -0,0 +1,30 @@
#version 450
#extension GL_ARB_gpu_shader_int64 : enable
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference, std430) buffer blockType {
layout(offset = 0) int a;
layout(offset = 4) int b;
layout(offset = 8) int c;
layout(offset = 12) int d;
layout(offset = 16) int e;
};
layout(std430) buffer t2 {
blockType f;
blockType g;
} t;
flat in uint64_t h, i;
void main() {
blockType b1[2] = blockType[2](blockType(h), blockType(i));
b1[0].a = b1[1].b;
blockType b2 = blockType(h);
blockType b3 = blockType(i);
b2.a = b3.b;
uint64_t j = uint64_t(b2);
b2 = blockType(j+256);
}

View File

@ -0,0 +1,45 @@
#version 450
#extension GL_EXT_buffer_reference : enable
layout(buffer_reference) buffer bufType1 { int x; };
layout(buffer_reference) buffer bufType2 { int x; };
layout(buffer_reference) uniform bufType3 { int x; };
layout(buffer_reference) buffer;
layout(buffer_reference) uniform;
layout(buffer_reference) in;
layout(buffer_reference) out;
layout(buffer_reference) in badin { float x; } badin2;
layout(buffer_reference) out badout { float x; } badout2;
layout(buffer_reference) buffer bufType5;
layout(buffer_reference) buffer bufType6 { int x[]; };
buffer bufType4 {
bufType1 b1;
bufType2 b2;
bufType3 b3;
bufType6 b6;
} b4;
void f()
{
bufType6 b;
b.x.length();
b4.b6.x.length();
}
void main() {
bufType2 x1 = b4.b1;
bufType2 x2 = bufType2(b4.b1);
bufType2 x3 = bufType2(b4.b2);
bufType2 x4 = bufType2(b4.b3);
b4.b1 = b4.b2;
b4.b1 = b4.b3;
b4.b3 = b4.b2;
}
layout(buffer_reference) uniform bufType5 { int x; };

View File

@ -66,6 +66,8 @@ enum TBasicType {
EbtAccStructNV,
#endif
EbtReference,
// HLSL types that live only temporarily.
EbtString,

View File

@ -721,6 +721,7 @@ public:
clearUniformLayout();
layoutPushConstant = false;
layoutBufferReference = false;
#ifdef NV_EXTENSIONS
layoutPassthrough = false;
layoutViewportRelative = false;
@ -729,6 +730,8 @@ public:
layoutShaderRecordNV = false;
#endif
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
clearInterstageLayout();
layoutSpecConstantId = layoutSpecConstantIdEnd;
@ -763,7 +766,8 @@ public:
#ifdef NV_EXTENSIONS
layoutShaderRecordNV ||
#endif
layoutPushConstant;
layoutPushConstant ||
layoutBufferReference;
}
bool hasLayout() const
{
@ -808,9 +812,14 @@ public:
unsigned int layoutSpecConstantId : 11;
static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
// stored as log2 of the actual alignment value
unsigned int layoutBufferReferenceAlign : 6;
static const unsigned int layoutBufferReferenceAlignEnd = 0x3F;
TLayoutFormat layoutFormat : 8;
bool layoutPushConstant;
bool layoutBufferReference;
#ifdef NV_EXTENSIONS
bool layoutPassthrough;
@ -918,6 +927,10 @@ public:
// is just whether or not it was declared with an ID.
return layoutSpecConstantId != layoutSpecConstantIdEnd;
}
bool hasBufferReferenceAlign() const
{
return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd;
}
bool isSpecConstant() const
{
// True if type is a specialization constant, whether or not it
@ -1308,7 +1321,12 @@ public:
sampler.clear();
qualifier = p.qualifier;
if (p.userDef) {
structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
if (p.userDef->basicType == EbtReference) {
basicType = EbtReference;
referentType = p.userDef->referentType;
} else {
structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
}
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
}
@ -1377,6 +1395,17 @@ public:
sampler.clear();
typeName = NewPoolTString(n.c_str());
}
// for block reference (first parameter must be EbtReference)
explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
{
assert(t == EbtReference);
typeName = NewPoolTString(n.c_str());
qualifier.clear();
qualifier.storage = p.qualifier.storage;
referentType = p.clone();
}
virtual ~TType() {}
// Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
@ -1392,9 +1421,13 @@ public:
matrixRows = copyOf.matrixRows;
vector1 = copyOf.vector1;
arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
structure = copyOf.structure;
fieldName = copyOf.fieldName;
typeName = copyOf.typeName;
if (isStruct()) {
structure = copyOf.structure;
} else {
referentType = copyOf.referentType;
}
}
// Make complete copy of the whole type graph rooted at 'copyOf'.
@ -1457,6 +1490,7 @@ public:
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
virtual TArraySizes* getArraySizes() { return arraySizes; }
virtual TType* getReferentType() const { return referentType; }
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
@ -1468,7 +1502,7 @@ public:
virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
virtual bool isStruct() const { return structure != nullptr; }
virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; }
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
virtual bool isIntegerDomain() const
{
@ -1509,7 +1543,7 @@ public:
const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
return structure && std::any_of(structure->begin(), structure->end(), hasa);
return isStruct() && std::any_of(structure->begin(), structure->end(), hasa);
}
// Recursively checks if the type contains the given basic type
@ -1688,6 +1722,7 @@ public:
#ifdef NV_EXTENSIONS
case EbtAccStructNV: return "accelerationStructureNV";
#endif
case EbtReference: return "reference";
default: return "unknown type";
}
}
@ -1773,6 +1808,12 @@ public:
}
if (qualifier.layoutPushConstant)
appendStr(" push_constant");
if (qualifier.layoutBufferReference)
appendStr(" buffer_reference");
if (qualifier.hasBufferReferenceAlign()) {
appendStr(" buffer_reference_align=");
appendUint(1u << qualifier.layoutBufferReferenceAlign);
}
#ifdef NV_EXTENSIONS
if (qualifier.layoutPassthrough)
@ -1892,7 +1933,7 @@ public:
}
// Add struct/block members
if (structure) {
if (isStruct()) {
appendStr("{");
for (size_t i = 0; i < structure->size(); ++i) {
if (! (*structure)[i].type->hiddenMember()) {
@ -1920,9 +1961,9 @@ public:
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
const TTypeList* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; }
TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads
const TTypeList* getStruct() const { assert(isStruct()); return structure; }
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
int computeNumComponents() const
{
@ -1961,11 +2002,12 @@ public:
bool sameStructType(const TType& right) const
{
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
if (structure == right.structure)
if ((!isStruct() && !right.isStruct()) ||
isStruct() && right.isStruct() && structure == right.structure)
return true;
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
if (structure == nullptr || right.structure == nullptr ||
if (!isStruct() || !right.isStruct() ||
structure->size() != right.structure->size())
return false;
@ -1985,6 +2027,23 @@ public:
return true;
}
bool sameReferenceType(const TType& right) const
{
if ((basicType == EbtReference) != (right.basicType == EbtReference))
return false;
if ((basicType != EbtReference) && (right.basicType != EbtReference))
return true;
assert(referentType != nullptr);
assert(right.referentType != nullptr);
if (referentType == right.referentType)
return true;
return *referentType == *right.referentType;
}
// See if two types match, in all aspects except arrayness
bool sameElementType(const TType& right) const
{
@ -2013,7 +2072,8 @@ public:
matrixCols == right.matrixCols &&
matrixRows == right.matrixRows &&
vector1 == right.vector1 &&
sameStructType(right);
sameStructType(right) &&
sameReferenceType(right);
}
// See if two types match in all ways (just the actual type, not qualification)
@ -2044,7 +2104,7 @@ protected:
*arraySizes = *copyOf.arraySizes;
}
if (copyOf.structure) {
if (copyOf.isStruct() && copyOf.structure) {
auto prevCopy = copiedMap.find(copyOf.structure);
if (prevCopy != copiedMap.end())
structure = prevCopy->second;
@ -2082,7 +2142,12 @@ protected:
TQualifier qualifier;
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
TTypeList* structure; // nullptr unless this is a struct; can be shared across types
// A type can't be both a structure (EbtStruct/EbtBlock) and a reference (EbtReference), so
// conserve space by making these a union
union {
TTypeList* structure; // invalid unless this is a struct; can be shared across types
TType *referentType; // invalid unless this is an EbtReference
};
TString *fieldName; // for structure field names
TString *typeName; // for structure type name
TSampler sampler;

View File

@ -269,6 +269,10 @@ enum TOperator {
EOpConvDoubleToFloat16,
EOpConvDoubleToFloat,
// uint64_t <-> pointer
EOpConvUint64ToPtr,
EOpConvPtrToUint64,
//
// binary operations
//
@ -732,6 +736,7 @@ enum TOperator {
EOpConstructStruct,
EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
EOpConstructReference,
EOpConstructGuardEnd,
//

View File

@ -984,6 +984,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpSequence:
case EOpConstructStruct:
if (type.getBasicType() == EbtReference || node->getType().getBasicType() == EbtReference) {
// types must match to assign a reference
if (type == node->getType())
return node;
else
return nullptr;
}
if (type.getBasicType() == node->getType().getBasicType())
return node;
@ -2131,6 +2139,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
}
}
break;
case EbtReference:
op = EOpConstructReference;
break;
default:
break;
}

View File

@ -354,6 +354,11 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
if (variable->getType().getQualifier().isIo())
intermediate.addIoAccessed(*string);
if (variable->getType().getBasicType() == EbtReference &&
variable->getType().getQualifier().isMemory()) {
intermediate.setUseVulkanMemoryModel();
}
return node;
}
@ -811,8 +816,12 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
if (base->getType().getQualifier().isSpecConstant())
result->getWritableType().getQualifier().makeSpecConstant();
}
} else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) {
const TTypeList* fields = base->getType().getStruct();
} else if (base->getBasicType() == EbtStruct ||
base->getBasicType() == EbtBlock ||
base->getBasicType() == EbtReference) {
const TTypeList* fields = base->getBasicType() == EbtReference ?
base->getType().getReferentType()->getStruct() :
base->getType().getStruct();
bool fieldFound = false;
int member;
for (member = 0; member < (int)fields->size(); ++member) {
@ -2386,6 +2395,10 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
}
}
if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct &&
binaryNode->getLeft()->getBasicType() == EbtReference)
return false;
// Let the base class check errors
if (TParseContextBase::lValueErrorCheck(loc, op, node))
return true;
@ -3096,13 +3109,17 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
if (! symbolTable.atGlobalLevel())
return;
if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
error(loc, "memory qualifiers cannot be used on this type", "", "");
} else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
error(loc, "memory qualifiers cannot be used on this type", "", "");
if (!(publicType.userDef && publicType.userDef->getBasicType() == EbtReference)) {
if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
error(loc, "memory qualifiers cannot be used on this type", "", "");
} else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
error(loc, "memory qualifiers cannot be used on this type", "", "");
}
}
if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock)
if (qualifier.storage == EvqBuffer &&
publicType.basicType != EbtBlock &&
!qualifier.layoutBufferReference)
error(loc, "buffers can be declared only as blocks", "buffer", "");
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
@ -3760,6 +3777,21 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType
if (isRuntimeLength(base))
return;
// Check for last member of a bufferreference type, which is runtime sizeable
// but doesn't support runtime length
if (base.getType().getQualifier().storage == EvqBuffer) {
const TIntermBinary* binary = base.getAsBinaryNode();
if (binary != nullptr &&
binary->getOp() == EOpIndexDirectStruct &&
binary->getLeft()->getBasicType() == EbtReference) {
const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size();
if (index == memberCount - 1)
return;
}
}
// check for additional things allowed by GL_EXT_nonuniform_qualifier
if (base.getBasicType() == EbtSampler ||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
@ -3777,6 +3809,10 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
// is it the last member?
const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
if (binary->getLeft()->getBasicType() == EbtReference)
return false;
const int memberCount = (int)binary->getLeft()->getType().getStruct()->size();
if (index == memberCount - 1)
return true;
@ -4655,6 +4691,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.qualifier.layoutPushConstant = true;
return;
}
if (id == "buffer_reference") {
requireVulkan(loc, "buffer_reference");
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference");
publicType.qualifier.layoutBufferReference = true;
intermediate.setUseStorageBuffer();
intermediate.setUsePhysicalStorageBuffer();
return;
}
if (language == EShLangGeometry || language == EShLangTessEvaluation
#ifdef NV_EXTENSIONS
|| language == EShLangMeshNV
@ -5013,6 +5057,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
#endif
if (id == "buffer_reference_align") {
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference_align");
if (! IsPow2(value))
error(loc, "must be a power of 2", "buffer_reference_align", "");
else
publicType.qualifier.layoutBufferReferenceAlign = std::log2(value);
return;
}
switch (language) {
case EShLangVertex:
break;
@ -5177,6 +5230,9 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
if (src.hasAlign())
dst.layoutAlign = src.layoutAlign;
if (src.hasBufferReferenceAlign())
dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign;
if (! inheritOnly) {
if (src.hasLocation())
dst.layoutLocation = src.layoutLocation;
@ -5205,6 +5261,9 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
if (src.layoutPushConstant)
dst.layoutPushConstant = true;
if (src.layoutBufferReference)
dst.layoutBufferReference = true;
#ifdef NV_EXTENSIONS
if (src.layoutPassthrough)
dst.layoutPassthrough = true;
@ -5452,7 +5511,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
#ifdef NV_EXTENSIONS
!qualifier.layoutShaderRecordNV &&
#endif
!qualifier.layoutAttachment)
!qualifier.layoutAttachment &&
!qualifier.layoutBufferReference)
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler)
error(loc, "sampler/texture/image requires layout(binding=X)", "binding", "");
@ -5504,6 +5564,9 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "push_constant", "");
if (qualifier.layoutBufferReference && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "buffer_reference", "");
#ifdef NV_EXTENSIONS
if (qualifier.layoutShaderRecordNV && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "shaderRecordNV", "");
@ -5644,6 +5707,10 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
if (qualifier.hasSet())
error(loc, "cannot be used with push_constant", "set", "");
}
if (qualifier.layoutBufferReference) {
if (qualifier.storage != EvqBuffer)
error(loc, "can only be used with buffer", "buffer_reference", "");
}
#ifdef NV_EXTENSIONS
if (qualifier.layoutShaderRecordNV) {
if (qualifier.storage != EvqBuffer)
@ -6051,7 +6118,7 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType
return;
}
if (publicType.qualifier.hasLayout())
if (publicType.qualifier.hasLayout() && !publicType.qualifier.layoutBufferReference)
warn(loc, "useless application of layout qualifier", "layout", "");
}
@ -6659,10 +6726,15 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
basicOp = EOpConstructInt64;
break;
case EOpConstructUint64:
if (type.isScalar() && node->getType().getBasicType() == EbtReference) {
TIntermUnary* newNode = intermediate.addUnaryNode(EOpConvPtrToUint64, node, node->getLoc(), type);
return newNode;
}
// fall through
case EOpConstructU64Vec2:
case EOpConstructU64Vec3:
case EOpConstructU64Vec4:
case EOpConstructUint64:
basicOp = EOpConstructUint64;
break;
@ -6678,6 +6750,19 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
return node;
break;
case EOpConstructReference:
// construct reference from reference
if (node->getType().getBasicType() == EbtReference) {
newNode = intermediate.addUnaryNode(EOpConstructReference, node, node->getLoc(), type);
return newNode;
// construct reference from uint64
} else if (node->getType().isScalar() && node->getType().getBasicType() == EbtUint64) {
TIntermUnary* newNode = intermediate.addUnaryNode(EOpConvUint64ToPtr, node, node->getLoc(), type);
return newNode;
} else {
return nullptr;
}
default:
error(loc, "unsupported construction", "", "");
@ -6922,31 +7007,57 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
else
ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
//
// Don't make a user-defined type out of block name; that will cause an error
// if the same block name gets reused in a different interface.
//
// "Block names have no other use within a shader
// beyond interface matching; it is a compile-time error to use a block name at global scope for anything
// other than as a block name (e.g., use of a block name for a global variable name or function name is
// currently reserved)."
//
// Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
// whose type is EbtBlock, but without all the structure; that will come from the type
// the instances point to.
//
TType blockNameType(EbtBlock, blockType.getQualifier().storage);
TVariable* blockNameVar = new TVariable(blockName, blockNameType);
if (! symbolTable.insert(*blockNameVar)) {
TSymbol* existingName = symbolTable.find(*blockName);
if (existingName->getType().getBasicType() == EbtBlock) {
if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
if (currentBlockQualifier.layoutBufferReference) {
if (currentBlockQualifier.storage != EvqBuffer)
error(loc, "can only be used with buffer", "buffer_reference", "");
// Create the block reference type. If it was forward-declared, detect that
// as a referent struct type with no members. Replace the referent type with
// blockType.
TType blockNameType(EbtReference, blockType, *blockName);
TVariable* blockNameVar = new TVariable(blockName, blockNameType, true);
if (! symbolTable.insert(*blockNameVar)) {
TSymbol* existingName = symbolTable.find(*blockName);
if (existingName->getType().getBasicType() == EbtReference &&
existingName->getType().getReferentType()->getStruct() &&
existingName->getType().getReferentType()->getStruct()->size() == 0 &&
existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
existingName->getType().getReferentType()->deepCopy(blockType);
} else {
error(loc, "block name cannot be redefined", blockName->c_str(), "");
}
}
if (!instanceName) {
return;
}
} else {
//
// Don't make a user-defined type out of block name; that will cause an error
// if the same block name gets reused in a different interface.
//
// "Block names have no other use within a shader
// beyond interface matching; it is a compile-time error to use a block name at global scope for anything
// other than as a block name (e.g., use of a block name for a global variable name or function name is
// currently reserved)."
//
// Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
// whose type is EbtBlock, but without all the structure; that will come from the type
// the instances point to.
//
TType blockNameType(EbtBlock, blockType.getQualifier().storage);
TVariable* blockNameVar = new TVariable(blockName, blockNameType);
if (! symbolTable.insert(*blockNameVar)) {
TSymbol* existingName = symbolTable.find(*blockName);
if (existingName->getType().getBasicType() == EbtBlock) {
if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
return;
}
} else {
error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
return;
}
} else {
error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
return;
}
}
@ -7246,6 +7357,22 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
{
TSymbol* symbol = symbolTable.find(identifier);
// A forward declaration of a block reference looks to the grammar like adding
// a qualifier to an existing symbol. Detect this and create the block reference
// type with an empty type list, which will be filled in later in
// TParseContext::declareBlock.
if (!symbol && qualifier.layoutBufferReference) {
TTypeList typeList;
TType blockType(&typeList, identifier, qualifier);;
TType blockNameType(EbtReference, blockType, identifier);
TVariable* blockNameVar = new TVariable(&identifier, blockNameType, true);
if (! symbolTable.insert(*blockNameVar)) {
error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
}
return;
}
if (! symbol) {
error(loc, "identifier not previously declared", identifier.c_str(), "");
return;
@ -7580,6 +7707,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
if (qualifier.layoutPushConstant)
error(loc, "cannot declare a default, can only be used on a block", "push_constant", "");
if (qualifier.layoutBufferReference)
error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
if (qualifier.hasSpecConstantId())
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
#ifdef NV_EXTENSIONS

View File

@ -776,7 +776,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
loc = ppToken.loc;
parserToken->sType.lex.loc = loc;
switch (token) {
case ';': afterType = false; return SEMICOLON;
case ';': afterType = false; afterBuffer = false; return SEMICOLON;
case ',': afterType = false; return COMMA;
case ':': return COLON;
case '=': afterType = false; return EQUAL;
@ -798,7 +798,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
case '?': return QUESTION;
case '[': return LEFT_BRACKET;
case ']': return RIGHT_BRACKET;
case '{': afterStruct = false; return LEFT_BRACE;
case '{': afterStruct = false; afterBuffer = false; return LEFT_BRACE;
case '}': return RIGHT_BRACE;
case '\\':
parseContext.error(loc, "illegal use of escape character", "\\", "");
@ -945,6 +945,7 @@ int TScanContext::tokenizeIdentifier()
return keyword;
case BUFFER:
afterBuffer = true;
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
(parseContext.profile != EEsProfile && parseContext.version < 430))
return identifierOrType();
@ -1617,7 +1618,9 @@ int TScanContext::identifierOrType()
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
if (variable->isUserType()) {
if (variable->isUserType() &&
// treat redeclaration of forward-declared buffer/uniform reference as an identifier
!(variable->getType().getBasicType() == EbtReference && afterBuffer)) {
afterType = true;
return TYPE_NAME;

View File

@ -53,7 +53,7 @@ public:
explicit TScanContext(TParseContextBase& pc) :
parseContext(pc),
afterType(false), afterStruct(false),
field(false) { }
field(false), afterBuffer(false) { }
virtual ~TScanContext() { }
static void fillInKeywordMap();
@ -81,6 +81,7 @@ protected:
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
bool field; // true if we're on a field, right after a '.'
bool afterBuffer; // true if we've recognized the BUFFER keyword
TSourceLoc loc;
TParserToken* parserToken;
TPpToken* ppToken;

View File

@ -207,6 +207,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
@ -383,6 +384,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_samplerless_texture_functions 1\n"
"#define GL_EXT_scalar_block_layout 1\n"
"#define GL_EXT_fragment_invocation_density 1\n"
"#define GL_EXT_buffer_reference 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"

View File

@ -169,6 +169,7 @@ const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
// Arrays of extensions for the above viewportEXTs duplications

View File

@ -172,8 +172,12 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
case EOpIndexDirect: out.debug << "direct index"; break;
case EOpIndexIndirect: out.debug << "indirect index"; break;
case EOpIndexDirectStruct:
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
out.debug << ": direct index for structure"; break;
{
bool reference = node->getLeft()->getType().getBasicType() == EbtReference;
const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct();
out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
out.debug << ": direct index for structure"; break;
}
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
@ -419,6 +423,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
case EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break;
case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; break;
case EOpRadians: out.debug << "radians"; break;
case EOpDegrees: out.debug << "degrees"; break;
@ -674,6 +680,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
case EOpConstructReference: out.debug << "Construct reference type"; break;
default: out.debug.message(EPrefixError, "Bad unary op");
}
@ -808,6 +816,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break;
case EOpConstructStruct: out.debug << "Construct structure"; break;
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
case EOpConstructReference: out.debug << "Construct reference"; break;
case EOpLessThan: out.debug << "Compare Less Than"; break;
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;

View File

@ -261,6 +261,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(needToLegalize);
MERGE_TRUE(binaryDoubleOutput);
MERGE_TRUE(usePhysicalStorageBuffer);
}
//
@ -1355,6 +1356,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
case EbtUint8: size = 1; return 1;
case EbtInt16:
case EbtUint16: size = 2; return 2;
case EbtReference: size = 8; return 8;
default: size = 4; return 4;
}
}

View File

@ -255,6 +255,7 @@ public:
textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false),
binaryDoubleOutput(false),
usePhysicalStorageBuffer(false),
uniformLocationBase(0)
{
localSize[0] = 1;
@ -390,6 +391,11 @@ public:
processes.addProcess("use-vulkan-memory-model");
}
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
void setUsePhysicalStorageBuffer()
{
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
bool hasCounterBufferName(const TString& name) const {
@ -825,6 +831,7 @@ protected:
bool needToLegalize;
bool binaryDoubleOutput;
bool usePhysicalStorageBuffer;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;

View File

@ -265,6 +265,22 @@ INSTANTIATE_TEST_CASE_P(
"spv.bool.vert",
"spv.boolInBlock.frag",
"spv.branch-return.vert",
"spv.bufferhandle1.frag",
"spv.bufferhandle10.frag",
"spv.bufferhandle11.frag",
"spv.bufferhandle12.frag",
"spv.bufferhandle13.frag",
"spv.bufferhandle14.frag",
"spv.bufferhandle15.frag",
"spv.bufferhandle2.frag",
"spv.bufferhandle3.frag",
"spv.bufferhandle4.frag",
"spv.bufferhandle5.frag",
"spv.bufferhandle6.frag",
"spv.bufferhandle7.frag",
"spv.bufferhandle8.frag",
"spv.bufferhandle9.frag",
"spv.bufferhandle_Error.frag",
"spv.builtInXFB.vert",
"spv.conditionalDiscard.frag",
"spv.constStruct.vert",

View File

@ -5,14 +5,14 @@
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools",
"commit" : "a87d3ce48e88a653e855c3245a6b68deeae58efc"
"commit" : "5eab6df648eace6eab69c44ccd17bd0f5e57406d"
},
{
"name" : "spirv-tools/external/spirv-headers",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "4618b86e9e4b027a22040732dfee35e399cd2c47"
"commit" : "79b6681aadcb53c27d1052e5f8a0e82a981dbf2f"
}
]
}