mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 20:10:06 +00:00
Merge pull request #1644 from jeffbolznv/buffer_reference
GL_EXT_buffer_reference
This commit is contained in:
commit
344a03c034
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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).
|
||||
|
104
Test/baseResults/spv.bufferhandle1.frag.out
Normal file
104
Test/baseResults/spv.bufferhandle1.frag.out
Normal 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
|
73
Test/baseResults/spv.bufferhandle10.frag.out
Normal file
73
Test/baseResults/spv.bufferhandle10.frag.out
Normal 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
|
118
Test/baseResults/spv.bufferhandle11.frag.out
Normal file
118
Test/baseResults/spv.bufferhandle11.frag.out
Normal 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
|
306
Test/baseResults/spv.bufferhandle12.frag.out
Normal file
306
Test/baseResults/spv.bufferhandle12.frag.out
Normal 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
|
118
Test/baseResults/spv.bufferhandle13.frag.out
Normal file
118
Test/baseResults/spv.bufferhandle13.frag.out
Normal 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
|
109
Test/baseResults/spv.bufferhandle14.frag.out
Normal file
109
Test/baseResults/spv.bufferhandle14.frag.out
Normal 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
|
130
Test/baseResults/spv.bufferhandle15.frag.out
Normal file
130
Test/baseResults/spv.bufferhandle15.frag.out
Normal 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
|
94
Test/baseResults/spv.bufferhandle2.frag.out
Normal file
94
Test/baseResults/spv.bufferhandle2.frag.out
Normal 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
|
105
Test/baseResults/spv.bufferhandle3.frag.out
Normal file
105
Test/baseResults/spv.bufferhandle3.frag.out
Normal 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
|
118
Test/baseResults/spv.bufferhandle4.frag.out
Normal file
118
Test/baseResults/spv.bufferhandle4.frag.out
Normal 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
|
52
Test/baseResults/spv.bufferhandle5.frag.out
Normal file
52
Test/baseResults/spv.bufferhandle5.frag.out
Normal 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
|
238
Test/baseResults/spv.bufferhandle6.frag.out
Normal file
238
Test/baseResults/spv.bufferhandle6.frag.out
Normal 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
|
77
Test/baseResults/spv.bufferhandle7.frag.out
Normal file
77
Test/baseResults/spv.bufferhandle7.frag.out
Normal 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
|
89
Test/baseResults/spv.bufferhandle8.frag.out
Normal file
89
Test/baseResults/spv.bufferhandle8.frag.out
Normal 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
|
114
Test/baseResults/spv.bufferhandle9.frag.out
Normal file
114
Test/baseResults/spv.bufferhandle9.frag.out
Normal 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
|
25
Test/baseResults/spv.bufferhandle_Error.frag.out
Normal file
25
Test/baseResults/spv.bufferhandle_Error.frag.out
Normal 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
|
28
Test/spv.bufferhandle1.frag
Normal file
28
Test/spv.bufferhandle1.frag
Normal 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;
|
||||
}
|
23
Test/spv.bufferhandle10.frag
Normal file
23
Test/spv.bufferhandle10.frag
Normal 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;
|
||||
|
||||
}
|
26
Test/spv.bufferhandle11.frag
Normal file
26
Test/spv.bufferhandle11.frag
Normal 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);
|
||||
}
|
42
Test/spv.bufferhandle12.frag
Normal file
42
Test/spv.bufferhandle12.frag
Normal 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));
|
||||
}
|
30
Test/spv.bufferhandle13.frag
Normal file
30
Test/spv.bufferhandle13.frag
Normal 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);
|
||||
}
|
40
Test/spv.bufferhandle14.frag
Normal file
40
Test/spv.bufferhandle14.frag
Normal 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;
|
||||
}
|
38
Test/spv.bufferhandle15.frag
Normal file
38
Test/spv.bufferhandle15.frag
Normal 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];
|
||||
}
|
25
Test/spv.bufferhandle2.frag
Normal file
25
Test/spv.bufferhandle2.frag
Normal 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;
|
||||
}
|
25
Test/spv.bufferhandle3.frag
Normal file
25
Test/spv.bufferhandle3.frag
Normal 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;
|
||||
}
|
26
Test/spv.bufferhandle4.frag
Normal file
26
Test/spv.bufferhandle4.frag
Normal 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;
|
||||
}
|
16
Test/spv.bufferhandle5.frag
Normal file
16
Test/spv.bufferhandle5.frag
Normal 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;
|
||||
}
|
30
Test/spv.bufferhandle6.frag
Normal file
30
Test/spv.bufferhandle6.frag
Normal 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);
|
||||
}
|
24
Test/spv.bufferhandle7.frag
Normal file
24
Test/spv.bufferhandle7.frag
Normal 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);
|
||||
}
|
32
Test/spv.bufferhandle8.frag
Normal file
32
Test/spv.bufferhandle8.frag
Normal 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];
|
||||
}
|
30
Test/spv.bufferhandle9.frag
Normal file
30
Test/spv.bufferhandle9.frag
Normal 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);
|
||||
}
|
45
Test/spv.bufferhandle_Error.frag
Normal file
45
Test/spv.bufferhandle_Error.frag
Normal 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; };
|
@ -66,6 +66,8 @@ enum TBasicType {
|
||||
EbtAccStructNV,
|
||||
#endif
|
||||
|
||||
EbtReference,
|
||||
|
||||
// HLSL types that live only temporarily.
|
||||
EbtString,
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
||||
//
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user