GL_EXT_buffer_reference
This commit is contained in:
parent
6eab476e5a
commit
9f2aec49e9
@ -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_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_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_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
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
@ -145,9 +145,9 @@ protected:
|
|||||||
spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
|
spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&);
|
||||||
spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
|
spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult);
|
||||||
void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
|
void convertSwizzle(const glslang::TIntermAggregate&, std::vector<unsigned>& swizzle);
|
||||||
spv::Id convertGlslangToSpvType(const glslang::TType& type);
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
|
||||||
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
|
||||||
bool lastBufferBlockMember);
|
bool lastBufferBlockMember, bool forwardReferenceOnly = false);
|
||||||
bool filterMember(const glslang::TType& member);
|
bool filterMember(const glslang::TType& member);
|
||||||
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
||||||
glslang::TLayoutPacking, const glslang::TQualifier&);
|
glslang::TLayoutPacking, const glslang::TQualifier&);
|
||||||
@ -211,6 +211,15 @@ protected:
|
|||||||
builder.addExtension(ext);
|
builder.addExtension(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int getBufferReferenceAlignment(const glslang::TType &type) const {
|
||||||
|
if (type.getBasicType() == glslang::EbtReference) {
|
||||||
|
return type.getReferentType()->getQualifier().hasBufferReferenceAlign() ?
|
||||||
|
(1u << type.getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glslang::SpvOptions& options;
|
glslang::SpvOptions& options;
|
||||||
spv::Function* shaderEntry;
|
spv::Function* shaderEntry;
|
||||||
spv::Function* currentFunction;
|
spv::Function* currentFunction;
|
||||||
@ -237,6 +246,8 @@ protected:
|
|||||||
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
|
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
|
||||||
std::stack<bool> breakForLoop; // false means break for switch
|
std::stack<bool> breakForLoop; // false means break for switch
|
||||||
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
||||||
|
// Map pointee types for EbtReference to their forward pointers
|
||||||
|
std::map<const glslang::TType *, spv::Id> forwardPointers;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1303,12 +1314,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
|
|||||||
builder.addInclude(iItr->first, iItr->second);
|
builder.addInclude(iItr->first, iItr->second);
|
||||||
}
|
}
|
||||||
stdBuiltins = builder.import("GLSL.std.450");
|
stdBuiltins = builder.import("GLSL.std.450");
|
||||||
|
|
||||||
|
spv::AddressingModel addressingModel = spv::AddressingModelLogical;
|
||||||
|
spv::MemoryModel memoryModel = spv::MemoryModelGLSL450;
|
||||||
|
|
||||||
|
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
|
||||||
|
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
|
||||||
|
builder.addExtension(spv::E_SPV_EXT_physical_storage_buffer);
|
||||||
|
builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
|
||||||
|
};
|
||||||
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
||||||
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelVulkanKHR);
|
memoryModel = spv::MemoryModelVulkanKHR;
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
|
builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
|
||||||
} else {
|
|
||||||
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
|
||||||
}
|
}
|
||||||
|
builder.setMemoryModel(addressingModel, memoryModel);
|
||||||
|
|
||||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||||
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
||||||
|
|
||||||
@ -1681,8 +1702,24 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
// so short circuit the access-chain stuff with a swizzle.
|
// so short circuit the access-chain stuff with a swizzle.
|
||||||
std::vector<unsigned> swizzle;
|
std::vector<unsigned> swizzle;
|
||||||
swizzle.push_back(glslangIndex);
|
swizzle.push_back(glslangIndex);
|
||||||
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
int dummySize;
|
||||||
|
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
||||||
|
TranslateCoherent(node->getLeft()->getType()),
|
||||||
|
glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Load through a block reference is performed with a dot operator that
|
||||||
|
// is mapped to EOpIndexDirectStruct. When we get to the actual reference,
|
||||||
|
// do a load and reset the access chain.
|
||||||
|
if (node->getLeft()->getBasicType() == glslang::EbtReference &&
|
||||||
|
!node->getLeft()->getType().isArray() &&
|
||||||
|
node->getOp() == glslang::EOpIndexDirectStruct)
|
||||||
|
{
|
||||||
|
spv::Id left = accessChainLoad(node->getLeft()->getType());
|
||||||
|
builder.clearAccessChain();
|
||||||
|
builder.setAccessChainLValue(left);
|
||||||
|
}
|
||||||
|
|
||||||
int spvIndex = glslangIndex;
|
int spvIndex = glslangIndex;
|
||||||
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
|
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
|
||||||
node->getOp() == glslang::EOpIndexDirectStruct)
|
node->getOp() == glslang::EOpIndexDirectStruct)
|
||||||
@ -1695,7 +1732,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// normal case for indexing array or structure or block
|
// normal case for indexing array or structure or block
|
||||||
builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()));
|
builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType()));
|
||||||
|
|
||||||
// Add capabilities here for accessing PointSize and clip/cull distance.
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
||||||
// We have deferred generation of associated capabilities until now.
|
// We have deferred generation of associated capabilities until now.
|
||||||
@ -1728,10 +1765,13 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
// restore the saved access chain
|
// restore the saved access chain
|
||||||
builder.setAccessChain(partial);
|
builder.setAccessChain(partial);
|
||||||
|
|
||||||
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
|
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) {
|
||||||
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
|
int dummySize;
|
||||||
else
|
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()),
|
||||||
builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()));
|
TranslateCoherent(node->getLeft()->getType()),
|
||||||
|
glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
||||||
|
} else
|
||||||
|
builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), getBufferReferenceAlignment(node->getLeft()->getType()));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case glslang::EOpVectorSwizzle:
|
case glslang::EOpVectorSwizzle:
|
||||||
@ -1739,7 +1779,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
node->getLeft()->traverse(this);
|
node->getLeft()->traverse(this);
|
||||||
std::vector<unsigned> swizzle;
|
std::vector<unsigned> swizzle;
|
||||||
convertSwizzle(*node->getRight()->getAsAggregate(), swizzle);
|
convertSwizzle(*node->getRight()->getAsAggregate(), swizzle);
|
||||||
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
int dummySize;
|
||||||
|
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
|
||||||
|
TranslateCoherent(node->getLeft()->getType()),
|
||||||
|
glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case glslang::EOpMatrixSwizzle:
|
case glslang::EOpMatrixSwizzle:
|
||||||
@ -2178,6 +2221,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
case glslang::EOpConstructU64Vec4:
|
case glslang::EOpConstructU64Vec4:
|
||||||
case glslang::EOpConstructStruct:
|
case glslang::EOpConstructStruct:
|
||||||
case glslang::EOpConstructTextureSampler:
|
case glslang::EOpConstructTextureSampler:
|
||||||
|
case glslang::EOpConstructReference:
|
||||||
{
|
{
|
||||||
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
||||||
std::vector<spv::Id> arguments;
|
std::vector<spv::Id> arguments;
|
||||||
@ -2829,6 +2873,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|||||||
builder.addCapability(spv::CapabilityStorageUniform16);
|
builder.addCapability(spv::CapabilityStorageUniform16);
|
||||||
break;
|
break;
|
||||||
case spv::StorageClassStorageBuffer:
|
case spv::StorageClassStorageBuffer:
|
||||||
|
case spv::StorageClassPhysicalStorageBufferEXT:
|
||||||
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
|
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
|
||||||
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
|
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
|
||||||
break;
|
break;
|
||||||
@ -2910,16 +2955,17 @@ void TGlslangToSpvTraverser::convertSwizzle(const glslang::TIntermAggregate& nod
|
|||||||
// Convert from a glslang type to an SPV type, by calling into a
|
// Convert from a glslang type to an SPV type, by calling into a
|
||||||
// recursive version of this function. This establishes the inherited
|
// recursive version of this function. This establishes the inherited
|
||||||
// layout state rooted from the top-level type.
|
// layout state rooted from the top-level type.
|
||||||
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly)
|
||||||
{
|
{
|
||||||
return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false);
|
return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false, forwardReferenceOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
|
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
|
||||||
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
|
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
|
||||||
// Mutually recursive with convertGlslangStructToSpvType().
|
// Mutually recursive with convertGlslangStructToSpvType().
|
||||||
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
|
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type,
|
||||||
glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, bool lastBufferBlockMember)
|
glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier,
|
||||||
|
bool lastBufferBlockMember, bool forwardReferenceOnly)
|
||||||
{
|
{
|
||||||
spv::Id spvType = spv::NoResult;
|
spv::Id spvType = spv::NoResult;
|
||||||
|
|
||||||
@ -3014,6 +3060,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||||||
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
|
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case glslang::EbtReference:
|
||||||
|
{
|
||||||
|
// Make the forward pointer, then recurse to convert the structure type, then
|
||||||
|
// patch up the forward pointer with a real pointer type.
|
||||||
|
if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) {
|
||||||
|
spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT);
|
||||||
|
forwardPointers[type.getReferentType()] = forwardId;
|
||||||
|
}
|
||||||
|
spvType = forwardPointers[type.getReferentType()];
|
||||||
|
if (!forwardReferenceOnly) {
|
||||||
|
spv::Id referentType = convertGlslangToSpvType(*type.getReferentType());
|
||||||
|
builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT,
|
||||||
|
forwardPointers[type.getReferentType()],
|
||||||
|
referentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
@ -3121,6 +3184,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|||||||
// Create a vector of struct types for SPIR-V to consume
|
// Create a vector of struct types for SPIR-V to consume
|
||||||
std::vector<spv::Id> spvMembers;
|
std::vector<spv::Id> spvMembers;
|
||||||
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
|
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
|
||||||
|
std::vector<std::pair<glslang::TType*, glslang::TQualifier> > deferredForwardPointers;
|
||||||
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
||||||
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
glslang::TType& glslangMember = *(*glslangMembers)[i].type;
|
||||||
if (glslangMember.hiddenMember()) {
|
if (glslangMember.hiddenMember()) {
|
||||||
@ -3144,8 +3208,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|||||||
// recurse
|
// recurse
|
||||||
bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
|
bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer &&
|
||||||
i == (int)glslangMembers->size() - 1;
|
i == (int)glslangMembers->size() - 1;
|
||||||
spvMembers.push_back(
|
|
||||||
convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember));
|
// Make forward pointers for any pointer members, and create a list of members to
|
||||||
|
// convert to spirv types after creating the struct.
|
||||||
|
if (glslangMember.getBasicType() == glslang::EbtReference) {
|
||||||
|
if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) {
|
||||||
|
deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier));
|
||||||
|
}
|
||||||
|
spvMembers.push_back(
|
||||||
|
convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true));
|
||||||
|
} else {
|
||||||
|
spvMembers.push_back(
|
||||||
|
convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3157,6 +3232,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
|
|||||||
// Decorate it
|
// Decorate it
|
||||||
decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType);
|
decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType);
|
||||||
|
|
||||||
|
for (int i = 0; i < deferredForwardPointers.size(); ++i) {
|
||||||
|
auto it = deferredForwardPointers[i];
|
||||||
|
convertGlslangToSpvType(*it.first, explicitLayout, it.second, false);
|
||||||
|
}
|
||||||
|
|
||||||
return spvType;
|
return spvType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3320,11 +3400,15 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
|||||||
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
||||||
coherentFlags |= TranslateCoherent(type);
|
coherentFlags |= TranslateCoherent(type);
|
||||||
|
|
||||||
|
unsigned int alignment = builder.getAccessChain().alignment;
|
||||||
|
alignment |= getBufferReferenceAlignment(type);
|
||||||
|
|
||||||
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
||||||
TranslateNonUniformDecoration(type.getQualifier()),
|
TranslateNonUniformDecoration(type.getQualifier()),
|
||||||
nominalTypeId,
|
nominalTypeId,
|
||||||
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
||||||
TranslateMemoryScope(coherentFlags));
|
TranslateMemoryScope(coherentFlags),
|
||||||
|
alignment);
|
||||||
|
|
||||||
// Need to convert to abstract types when necessary
|
// Need to convert to abstract types when necessary
|
||||||
if (type.getBasicType() == glslang::EbtBool) {
|
if (type.getBasicType() == glslang::EbtBool) {
|
||||||
@ -3383,9 +3467,12 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
|
|||||||
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
||||||
coherentFlags |= TranslateCoherent(type);
|
coherentFlags |= TranslateCoherent(type);
|
||||||
|
|
||||||
|
unsigned int alignment = builder.getAccessChain().alignment;
|
||||||
|
alignment |= getBufferReferenceAlignment(type);
|
||||||
|
|
||||||
builder.accessChainStore(rvalue,
|
builder.accessChainStore(rvalue,
|
||||||
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
|
||||||
TranslateMemoryScope(coherentFlags));
|
TranslateMemoryScope(coherentFlags), alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For storing when types match at the glslang level, but not might match at the
|
// For storing when types match at the glslang level, but not might match at the
|
||||||
@ -3431,7 +3518,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|||||||
// set up the target storage
|
// set up the target storage
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
builder.setAccessChainLValue(lValue);
|
builder.setAccessChainLValue(lValue);
|
||||||
builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type));
|
builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), getBufferReferenceAlignment(type));
|
||||||
|
|
||||||
// store the member
|
// store the member
|
||||||
multiTypeStore(glslangElementType, elementRValue);
|
multiTypeStore(glslangElementType, elementRValue);
|
||||||
@ -3451,7 +3538,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|||||||
// set up the target storage
|
// set up the target storage
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
builder.setAccessChainLValue(lValue);
|
builder.setAccessChainLValue(lValue);
|
||||||
builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type));
|
builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), getBufferReferenceAlignment(type));
|
||||||
|
|
||||||
// store the member
|
// store the member
|
||||||
multiTypeStore(glslangMemberType, memberRValue);
|
multiTypeStore(glslangMemberType, memberRValue);
|
||||||
@ -3638,11 +3725,22 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
|||||||
// Make all the functions, skeletally, without actually visiting their bodies.
|
// Make all the functions, skeletally, without actually visiting their bodies.
|
||||||
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
||||||
{
|
{
|
||||||
const auto getParamDecorations = [](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
|
const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
|
||||||
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
||||||
if (paramPrecision != spv::NoPrecision)
|
if (paramPrecision != spv::NoPrecision)
|
||||||
decorations.push_back(paramPrecision);
|
decorations.push_back(paramPrecision);
|
||||||
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
|
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
|
||||||
|
if (type.getBasicType() == glslang::EbtReference) {
|
||||||
|
// Original and non-writable params pass the pointer directly and
|
||||||
|
// use restrict/aliased, others are stored to a pointer in Function
|
||||||
|
// memory and use RestrictPointer/AliasedPointer.
|
||||||
|
if (originalParam(type.getQualifier().storage, type, false) ||
|
||||||
|
!writableParam(type.getQualifier().storage)) {
|
||||||
|
decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrict : spv::DecorationAliased);
|
||||||
|
} else {
|
||||||
|
decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
||||||
@ -4459,7 +4557,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
spv::Builder::AccessChain::CoherentFlags flags;
|
spv::Builder::AccessChain::CoherentFlags flags;
|
||||||
flags.clear();
|
flags.clear();
|
||||||
|
|
||||||
builder.accessChainPush(builder.makeIntConstant(i), flags);
|
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
|
||||||
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
|
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
|
||||||
}
|
}
|
||||||
return builder.createCompositeExtract(res, resultType(), 0);
|
return builder.createCompositeExtract(res, resultType(), 0);
|
||||||
@ -5330,6 +5428,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
|
|||||||
unaryOp = spv::OpGroupNonUniformPartitionNV;
|
unaryOp = spv::OpGroupNonUniformPartitionNV;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case glslang::EOpConstructReference:
|
||||||
|
unaryOp = spv::OpBitcast;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -5782,6 +5883,12 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
|
|||||||
// For normal run-time conversion instruction, use OpBitcast.
|
// For normal run-time conversion instruction, use OpBitcast.
|
||||||
convOp = spv::OpBitcast;
|
convOp = spv::OpBitcast;
|
||||||
break;
|
break;
|
||||||
|
case glslang::EOpConvUint64ToPtr:
|
||||||
|
convOp = spv::OpConvertUToPtr;
|
||||||
|
break;
|
||||||
|
case glslang::EOpConvPtrToUint64:
|
||||||
|
convOp = spv::OpConvertPtrToU;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -7247,6 +7354,10 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
symbol->getType().getQualifier().semanticName);
|
symbol->getType().getQualifier().semanticName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol->getBasicType() == glslang::EbtReference) {
|
||||||
|
builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7375,7 +7486,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
|||||||
glslang::TType vectorType(glslangType, 0);
|
glslang::TType vectorType(glslangType, 0);
|
||||||
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
|
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
|
||||||
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
|
||||||
} else if (glslangType.getStruct()) {
|
} else if (glslangType.isStruct()) {
|
||||||
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
|
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
|
||||||
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
|
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
|
||||||
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));
|
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));
|
||||||
|
@ -194,6 +194,40 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
|
|||||||
return type->getResultId();
|
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)
|
Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
@ -576,6 +610,7 @@ int Builder::getNumTypeConstituents(Id typeId) const
|
|||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
|
case OpTypePointer:
|
||||||
return 1;
|
return 1;
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
@ -669,17 +704,36 @@ bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
case OpTypePointer:
|
||||||
|
return false;
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
case OpTypeRuntimeArray:
|
case OpTypeRuntimeArray:
|
||||||
case OpTypePointer:
|
|
||||||
return containsType(getContainedTypeId(typeId), typeOp, width);
|
return containsType(getContainedTypeId(typeId), typeOp, width);
|
||||||
default:
|
default:
|
||||||
return typeClass == typeOp;
|
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
|
// See if a scalar constant of this type has already been created, so it
|
||||||
// can be reused rather than duplicated. (Required by the specification).
|
// can be reused rather than duplicated. (Required by the specification).
|
||||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
|
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
|
||||||
@ -1252,15 +1306,39 @@ Id Builder::createUndefined(Id type)
|
|||||||
return inst->getResultId();
|
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
|
// 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);
|
Instruction* store = new Instruction(OpStore);
|
||||||
store->addIdOperand(lValue);
|
store->addIdOperand(lValue);
|
||||||
store->addIdOperand(rValue);
|
store->addIdOperand(rValue);
|
||||||
|
|
||||||
|
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
|
||||||
|
|
||||||
if (memoryAccess != MemoryAccessMaskNone) {
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
store->addImmediateOperand(memoryAccess);
|
store->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessAlignedMask) {
|
||||||
|
store->addImmediateOperand(alignment);
|
||||||
|
}
|
||||||
if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
|
if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
|
||||||
store->addIdOperand(makeUintConstant(scope));
|
store->addIdOperand(makeUintConstant(scope));
|
||||||
}
|
}
|
||||||
@ -1270,13 +1348,18 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||||
load->addIdOperand(lValue);
|
load->addIdOperand(lValue);
|
||||||
|
|
||||||
|
memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
|
||||||
|
|
||||||
if (memoryAccess != MemoryAccessMaskNone) {
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
load->addImmediateOperand(memoryAccess);
|
load->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessAlignedMask) {
|
||||||
|
load->addImmediateOperand(alignment);
|
||||||
|
}
|
||||||
if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
|
if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
|
||||||
load->addIdOperand(makeUintConstant(scope));
|
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
|
// Go through the source arguments, each one could have either
|
||||||
// a single or multiple components to contribute.
|
// a single or multiple components to contribute.
|
||||||
for (unsigned int i = 0; i < sources.size(); ++i) {
|
for (unsigned int i = 0; i < sources.size(); ++i) {
|
||||||
if (isScalar(sources[i]))
|
|
||||||
|
if (isScalar(sources[i]) || isPointer(sources[i]))
|
||||||
latchResult(sources[i]);
|
latchResult(sources[i]);
|
||||||
else if (isVector(sources[i]))
|
else if (isVector(sources[i]))
|
||||||
accumulateVectorConstituents(sources[i]);
|
accumulateVectorConstituents(sources[i]);
|
||||||
@ -2433,11 +2517,15 @@ void Builder::clearAccessChain()
|
|||||||
accessChain.preSwizzleBaseType = NoType;
|
accessChain.preSwizzleBaseType = NoType;
|
||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
accessChain.coherentFlags.clear();
|
accessChain.coherentFlags.clear();
|
||||||
|
accessChain.alignment = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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
|
// swizzles can be stacked in GLSL, but simplified to a single
|
||||||
// one here; the base type doesn't change
|
// one here; the base type doesn't change
|
||||||
if (accessChain.preSwizzleBaseType == NoType)
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
@ -2459,7 +2547,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// 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);
|
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);
|
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
|
// 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;
|
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
|
id = accessChain.base; // no precision, it was set when this was defined
|
||||||
} else {
|
} else {
|
||||||
transferAccessChainSwizzle(true);
|
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
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain(), memoryAccess, scope);
|
id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
|
||||||
setPrecision(id, precision);
|
setPrecision(id, precision);
|
||||||
addDecoration(id, nonUniform);
|
addDecoration(id, nonUniform);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,9 @@ public:
|
|||||||
// For creating new types (will return old type if the requested one was already made).
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
Id makeVoidType();
|
Id makeVoidType();
|
||||||
Id makeBoolType();
|
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 makeIntegerType(int width, bool hasSign); // generic
|
||||||
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
||||||
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
||||||
@ -194,6 +196,7 @@ public:
|
|||||||
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||||
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
|
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
|
||||||
|
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
|
||||||
|
|
||||||
bool isConstantOpCode(Op opcode) const;
|
bool isConstantOpCode(Op opcode) const;
|
||||||
bool isSpecConstantOpCode(Op opcode) const;
|
bool isSpecConstantOpCode(Op opcode) const;
|
||||||
@ -300,10 +303,10 @@ public:
|
|||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
// Store into an Id and return the l-value
|
// 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
|
// 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
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
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 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
|
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
|
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.
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
struct CoherentFlags {
|
struct CoherentFlags {
|
||||||
@ -601,31 +605,34 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// push offset onto the end of the chain
|
// 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.indexChain.push_back(offset);
|
||||||
accessChain.coherentFlags |= coherentFlags;
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// 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
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
// non-trivial swizzle or no swizzle
|
// 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) {
|
if (accessChain.swizzle.size() != 1) {
|
||||||
accessChain.component = component;
|
accessChain.component = component;
|
||||||
if (accessChain.preSwizzleBaseType == NoType)
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
}
|
}
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// 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
|
// 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
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
@ -639,7 +646,7 @@ public:
|
|||||||
void postProcess();
|
void postProcess();
|
||||||
|
|
||||||
// Hook to visit each instruction in a block in a function
|
// 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.
|
// Hook to visit each instruction in a reachable block in a function.
|
||||||
void postProcessReachable(const Instruction&);
|
void postProcessReachable(const Instruction&);
|
||||||
// Hook to visit each non-32-bit sized float/int operation in a block.
|
// 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 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 dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
void dumpModuleProcesses(std::vector<unsigned int>&) 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
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
|
@ -87,6 +87,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
|||||||
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
||||||
if (width == 8) {
|
if (width == 8) {
|
||||||
switch (storageClass) {
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
case StorageClassUniform:
|
case StorageClassUniform:
|
||||||
case StorageClassStorageBuffer:
|
case StorageClassStorageBuffer:
|
||||||
case StorageClassPushConstant:
|
case StorageClassPushConstant:
|
||||||
@ -97,6 +98,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
|||||||
}
|
}
|
||||||
} else if (width == 16) {
|
} else if (width == 16) {
|
||||||
switch (storageClass) {
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
case StorageClassUniform:
|
case StorageClassUniform:
|
||||||
case StorageClassStorageBuffer:
|
case StorageClassStorageBuffer:
|
||||||
case StorageClassPushConstant:
|
case StorageClassPushConstant:
|
||||||
@ -151,7 +153,7 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called for each instruction that resides in a block.
|
// 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.
|
// Add capabilities based simply on the opcode.
|
||||||
switch (inst.getOpCode()) {
|
switch (inst.getOpCode()) {
|
||||||
@ -190,6 +192,88 @@ void Builder::postProcess(const Instruction& inst)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -258,6 +342,47 @@ void Builder::postProcess()
|
|||||||
Block* b = *bi;
|
Block* b = *bi;
|
||||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||||
postProcess(*ii->get());
|
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:
|
case OperandMemoryAccess:
|
||||||
outputMask(OperandMemoryAccess, stream[word++]);
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
--numOperands;
|
--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);
|
disassembleIds(numOperands);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
@ -124,6 +124,8 @@ const char* AddressingString(int addr)
|
|||||||
case 1: return "Physical32";
|
case 1: return "Physical32";
|
||||||
case 2: return "Physical64";
|
case 2: return "Physical64";
|
||||||
|
|
||||||
|
case AddressingModelPhysicalStorageBuffer64EXT: return "PhysicalStorageBuffer64EXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,6 +222,8 @@ const char* StorageClassString(int StorageClass)
|
|||||||
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
|
case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,6 +299,8 @@ const char* DecorationString(int decoration)
|
|||||||
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
|
||||||
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||||
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
|
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 CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR";
|
||||||
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
|
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
|
||||||
|
|
||||||
|
case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2014-2018 The Khronos Group Inc.
|
// Copyright (c) 2014-2019 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and/or associated documentation files (the "Materials"),
|
// of this software and/or associated documentation files (the "Materials"),
|
||||||
@ -26,14 +26,16 @@
|
|||||||
// the Binary Section of the SPIR-V specification.
|
// the Binary Section of the SPIR-V specification.
|
||||||
|
|
||||||
// Enumeration tokens for SPIR-V, in various styles:
|
// Enumeration tokens for SPIR-V, in various styles:
|
||||||
// C, C++, C++11, JSON, Lua, Python, C#
|
// C, C++, C++11, JSON, Lua, Python, C#, D
|
||||||
//
|
//
|
||||||
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||||
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||||
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
||||||
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
||||||
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
||||||
// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL
|
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||||
|
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||||
|
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||||
//
|
//
|
||||||
// Some tokens act like mask values, which can be OR'd together,
|
// Some tokens act like mask values, which can be OR'd together,
|
||||||
// while others are mutually exclusive. The mask-like ones have
|
// while others are mutually exclusive. The mask-like ones have
|
||||||
@ -48,11 +50,11 @@ namespace spv {
|
|||||||
typedef unsigned int Id;
|
typedef unsigned int Id;
|
||||||
|
|
||||||
#define SPV_VERSION 0x10300
|
#define SPV_VERSION 0x10300
|
||||||
#define SPV_REVISION 1
|
#define SPV_REVISION 6
|
||||||
|
|
||||||
static const unsigned int MagicNumber = 0x07230203;
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
static const unsigned int Version = 0x00010300;
|
static const unsigned int Version = 0x00010300;
|
||||||
static const unsigned int Revision = 1;
|
static const unsigned int Revision = 6;
|
||||||
static const unsigned int OpCodeMask = 0xffff;
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
static const unsigned int WordCountShift = 16;
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
@ -89,6 +91,7 @@ enum AddressingModel {
|
|||||||
AddressingModelLogical = 0,
|
AddressingModelLogical = 0,
|
||||||
AddressingModelPhysical32 = 1,
|
AddressingModelPhysical32 = 1,
|
||||||
AddressingModelPhysical64 = 2,
|
AddressingModelPhysical64 = 2,
|
||||||
|
AddressingModelPhysicalStorageBuffer64EXT = 5348,
|
||||||
AddressingModelMax = 0x7fffffff,
|
AddressingModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -140,6 +143,11 @@ enum ExecutionMode {
|
|||||||
ExecutionModeLocalSizeId = 38,
|
ExecutionModeLocalSizeId = 38,
|
||||||
ExecutionModeLocalSizeHintId = 39,
|
ExecutionModeLocalSizeHintId = 39,
|
||||||
ExecutionModePostDepthCoverage = 4446,
|
ExecutionModePostDepthCoverage = 4446,
|
||||||
|
ExecutionModeDenormPreserve = 4459,
|
||||||
|
ExecutionModeDenormFlushToZero = 4460,
|
||||||
|
ExecutionModeSignedZeroInfNanPreserve = 4461,
|
||||||
|
ExecutionModeRoundingModeRTE = 4462,
|
||||||
|
ExecutionModeRoundingModeRTZ = 4463,
|
||||||
ExecutionModeStencilRefReplacingEXT = 5027,
|
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||||
ExecutionModeOutputLinesNV = 5269,
|
ExecutionModeOutputLinesNV = 5269,
|
||||||
ExecutionModeOutputPrimitivesNV = 5270,
|
ExecutionModeOutputPrimitivesNV = 5270,
|
||||||
@ -169,6 +177,7 @@ enum StorageClass {
|
|||||||
StorageClassHitAttributeNV = 5339,
|
StorageClassHitAttributeNV = 5339,
|
||||||
StorageClassIncomingRayPayloadNV = 5342,
|
StorageClassIncomingRayPayloadNV = 5342,
|
||||||
StorageClassShaderRecordBufferNV = 5343,
|
StorageClassShaderRecordBufferNV = 5343,
|
||||||
|
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||||
StorageClassMax = 0x7fffffff,
|
StorageClassMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -417,6 +426,8 @@ enum Decoration {
|
|||||||
DecorationMaxByteOffset = 45,
|
DecorationMaxByteOffset = 45,
|
||||||
DecorationAlignmentId = 46,
|
DecorationAlignmentId = 46,
|
||||||
DecorationMaxByteOffsetId = 47,
|
DecorationMaxByteOffsetId = 47,
|
||||||
|
DecorationNoSignedWrap = 4469,
|
||||||
|
DecorationNoUnsignedWrap = 4470,
|
||||||
DecorationExplicitInterpAMD = 4999,
|
DecorationExplicitInterpAMD = 4999,
|
||||||
DecorationOverrideCoverageNV = 5248,
|
DecorationOverrideCoverageNV = 5248,
|
||||||
DecorationPassthroughNV = 5250,
|
DecorationPassthroughNV = 5250,
|
||||||
@ -427,6 +438,8 @@ enum Decoration {
|
|||||||
DecorationPerTaskNV = 5273,
|
DecorationPerTaskNV = 5273,
|
||||||
DecorationPerVertexNV = 5285,
|
DecorationPerVertexNV = 5285,
|
||||||
DecorationNonUniformEXT = 5300,
|
DecorationNonUniformEXT = 5300,
|
||||||
|
DecorationRestrictPointerEXT = 5355,
|
||||||
|
DecorationAliasedPointerEXT = 5356,
|
||||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||||
DecorationHlslSemanticGOOGLE = 5635,
|
DecorationHlslSemanticGOOGLE = 5635,
|
||||||
DecorationMax = 0x7fffffff,
|
DecorationMax = 0x7fffffff,
|
||||||
@ -756,6 +769,11 @@ enum Capability {
|
|||||||
CapabilityStorageBuffer8BitAccess = 4448,
|
CapabilityStorageBuffer8BitAccess = 4448,
|
||||||
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
|
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
|
||||||
CapabilityStoragePushConstant8 = 4450,
|
CapabilityStoragePushConstant8 = 4450,
|
||||||
|
CapabilityDenormPreserve = 4464,
|
||||||
|
CapabilityDenormFlushToZero = 4465,
|
||||||
|
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||||
|
CapabilityRoundingModeRTE = 4467,
|
||||||
|
CapabilityRoundingModeRTZ = 4468,
|
||||||
CapabilityFloat16ImageAMD = 5008,
|
CapabilityFloat16ImageAMD = 5008,
|
||||||
CapabilityImageGatherBiasLodAMD = 5009,
|
CapabilityImageGatherBiasLodAMD = 5009,
|
||||||
CapabilityFragmentMaskAMD = 5010,
|
CapabilityFragmentMaskAMD = 5010,
|
||||||
@ -791,6 +809,7 @@ enum Capability {
|
|||||||
CapabilityRayTracingNV = 5340,
|
CapabilityRayTracingNV = 5340,
|
||||||
CapabilityVulkanMemoryModelKHR = 5345,
|
CapabilityVulkanMemoryModelKHR = 5345,
|
||||||
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
|
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
|
||||||
|
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
|
||||||
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
||||||
CapabilitySubgroupShuffleINTEL = 5568,
|
CapabilitySubgroupShuffleINTEL = 5568,
|
||||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||||
|
@ -102,6 +102,11 @@ public:
|
|||||||
operands.push_back(immediate);
|
operands.push_back(immediate);
|
||||||
idOperand.push_back(false);
|
idOperand.push_back(false);
|
||||||
}
|
}
|
||||||
|
void setImmediateOperand(unsigned idx, unsigned int immediate) {
|
||||||
|
assert(!idOperand[idx]);
|
||||||
|
operands[idx] = immediate;
|
||||||
|
}
|
||||||
|
|
||||||
void addStringOperand(const char* str)
|
void addStringOperand(const char* str)
|
||||||
{
|
{
|
||||||
unsigned int word;
|
unsigned int word;
|
||||||
@ -203,6 +208,7 @@ public:
|
|||||||
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||||
void setUnreachable() { unreachable = true; }
|
void setUnreachable() { unreachable = true; }
|
||||||
bool isUnreachable() const { return unreachable; }
|
bool isUnreachable() const { return unreachable; }
|
||||||
// Returns the block's merge instruction, if one exists (otherwise null).
|
// 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,
|
EbtAccStructNV,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EbtReference,
|
||||||
|
|
||||||
// HLSL types that live only temporarily.
|
// HLSL types that live only temporarily.
|
||||||
EbtString,
|
EbtString,
|
||||||
|
|
||||||
|
@ -721,6 +721,7 @@ public:
|
|||||||
clearUniformLayout();
|
clearUniformLayout();
|
||||||
|
|
||||||
layoutPushConstant = false;
|
layoutPushConstant = false;
|
||||||
|
layoutBufferReference = false;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutPassthrough = false;
|
layoutPassthrough = false;
|
||||||
layoutViewportRelative = false;
|
layoutViewportRelative = false;
|
||||||
@ -729,6 +730,8 @@ public:
|
|||||||
layoutShaderRecordNV = false;
|
layoutShaderRecordNV = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
||||||
|
|
||||||
clearInterstageLayout();
|
clearInterstageLayout();
|
||||||
|
|
||||||
layoutSpecConstantId = layoutSpecConstantIdEnd;
|
layoutSpecConstantId = layoutSpecConstantIdEnd;
|
||||||
@ -763,7 +766,8 @@ public:
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutShaderRecordNV ||
|
layoutShaderRecordNV ||
|
||||||
#endif
|
#endif
|
||||||
layoutPushConstant;
|
layoutPushConstant ||
|
||||||
|
layoutBufferReference;
|
||||||
}
|
}
|
||||||
bool hasLayout() const
|
bool hasLayout() const
|
||||||
{
|
{
|
||||||
@ -808,9 +812,14 @@ public:
|
|||||||
unsigned int layoutSpecConstantId : 11;
|
unsigned int layoutSpecConstantId : 11;
|
||||||
static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
|
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;
|
TLayoutFormat layoutFormat : 8;
|
||||||
|
|
||||||
bool layoutPushConstant;
|
bool layoutPushConstant;
|
||||||
|
bool layoutBufferReference;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
bool layoutPassthrough;
|
bool layoutPassthrough;
|
||||||
@ -918,6 +927,10 @@ public:
|
|||||||
// is just whether or not it was declared with an ID.
|
// is just whether or not it was declared with an ID.
|
||||||
return layoutSpecConstantId != layoutSpecConstantIdEnd;
|
return layoutSpecConstantId != layoutSpecConstantIdEnd;
|
||||||
}
|
}
|
||||||
|
bool hasBufferReferenceAlign() const
|
||||||
|
{
|
||||||
|
return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd;
|
||||||
|
}
|
||||||
bool isSpecConstant() const
|
bool isSpecConstant() const
|
||||||
{
|
{
|
||||||
// True if type is a specialization constant, whether or not it
|
// True if type is a specialization constant, whether or not it
|
||||||
@ -1308,7 +1321,12 @@ public:
|
|||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier = p.qualifier;
|
qualifier = p.qualifier;
|
||||||
if (p.userDef) {
|
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());
|
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1377,6 +1395,17 @@ public:
|
|||||||
sampler.clear();
|
sampler.clear();
|
||||||
typeName = NewPoolTString(n.c_str());
|
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() {}
|
virtual ~TType() {}
|
||||||
|
|
||||||
// Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
|
// 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;
|
matrixRows = copyOf.matrixRows;
|
||||||
vector1 = copyOf.vector1;
|
vector1 = copyOf.vector1;
|
||||||
arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
|
arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
|
||||||
structure = copyOf.structure;
|
|
||||||
fieldName = copyOf.fieldName;
|
fieldName = copyOf.fieldName;
|
||||||
typeName = copyOf.typeName;
|
typeName = copyOf.typeName;
|
||||||
|
if (isStruct()) {
|
||||||
|
structure = copyOf.structure;
|
||||||
|
} else {
|
||||||
|
referentType = copyOf.referentType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make complete copy of the whole type graph rooted at 'copyOf'.
|
// Make complete copy of the whole type graph rooted at 'copyOf'.
|
||||||
@ -1457,6 +1490,7 @@ public:
|
|||||||
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
|
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
|
||||||
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
|
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
|
||||||
virtual TArraySizes* getArraySizes() { return arraySizes; }
|
virtual TArraySizes* getArraySizes() { return arraySizes; }
|
||||||
|
virtual TType* getReferentType() const { return referentType; }
|
||||||
|
|
||||||
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
|
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
|
||||||
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
|
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
|
||||||
@ -1468,7 +1502,7 @@ public:
|
|||||||
virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
|
virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
|
||||||
virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
|
virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
|
||||||
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
|
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 isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
|
||||||
virtual bool isIntegerDomain() const
|
virtual bool isIntegerDomain() const
|
||||||
{
|
{
|
||||||
@ -1509,7 +1543,7 @@ public:
|
|||||||
|
|
||||||
const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
|
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
|
// Recursively checks if the type contains the given basic type
|
||||||
@ -1688,6 +1722,7 @@ public:
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case EbtAccStructNV: return "accelerationStructureNV";
|
case EbtAccStructNV: return "accelerationStructureNV";
|
||||||
#endif
|
#endif
|
||||||
|
case EbtReference: return "reference";
|
||||||
default: return "unknown type";
|
default: return "unknown type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1773,6 +1808,12 @@ public:
|
|||||||
}
|
}
|
||||||
if (qualifier.layoutPushConstant)
|
if (qualifier.layoutPushConstant)
|
||||||
appendStr(" push_constant");
|
appendStr(" push_constant");
|
||||||
|
if (qualifier.layoutBufferReference)
|
||||||
|
appendStr(" buffer_reference");
|
||||||
|
if (qualifier.hasBufferReferenceAlign()) {
|
||||||
|
appendStr(" buffer_reference_align=");
|
||||||
|
appendUint(1u << qualifier.layoutBufferReferenceAlign);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (qualifier.layoutPassthrough)
|
if (qualifier.layoutPassthrough)
|
||||||
@ -1892,7 +1933,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add struct/block members
|
// Add struct/block members
|
||||||
if (structure) {
|
if (isStruct()) {
|
||||||
appendStr("{");
|
appendStr("{");
|
||||||
for (size_t i = 0; i < structure->size(); ++i) {
|
for (size_t i = 0; i < structure->size(); ++i) {
|
||||||
if (! (*structure)[i].type->hiddenMember()) {
|
if (! (*structure)[i].type->hiddenMember()) {
|
||||||
@ -1920,9 +1961,9 @@ public:
|
|||||||
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
|
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
|
||||||
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
|
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
|
||||||
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
|
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
|
||||||
const TTypeList* getStruct() const { return structure; }
|
const TTypeList* getStruct() const { assert(isStruct()); return structure; }
|
||||||
void setStruct(TTypeList* s) { structure = s; }
|
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
|
||||||
TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads
|
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
|
||||||
|
|
||||||
int computeNumComponents() const
|
int computeNumComponents() const
|
||||||
{
|
{
|
||||||
@ -1961,11 +2002,12 @@ public:
|
|||||||
bool sameStructType(const TType& right) const
|
bool sameStructType(const TType& right) const
|
||||||
{
|
{
|
||||||
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
|
// 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;
|
return true;
|
||||||
|
|
||||||
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
// 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())
|
structure->size() != right.structure->size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1985,6 +2027,23 @@ public:
|
|||||||
return true;
|
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
|
// See if two types match, in all aspects except arrayness
|
||||||
bool sameElementType(const TType& right) const
|
bool sameElementType(const TType& right) const
|
||||||
{
|
{
|
||||||
@ -2013,7 +2072,8 @@ public:
|
|||||||
matrixCols == right.matrixCols &&
|
matrixCols == right.matrixCols &&
|
||||||
matrixRows == right.matrixRows &&
|
matrixRows == right.matrixRows &&
|
||||||
vector1 == right.vector1 &&
|
vector1 == right.vector1 &&
|
||||||
sameStructType(right);
|
sameStructType(right) &&
|
||||||
|
sameReferenceType(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if two types match in all ways (just the actual type, not qualification)
|
// See if two types match in all ways (just the actual type, not qualification)
|
||||||
@ -2044,7 +2104,7 @@ protected:
|
|||||||
*arraySizes = *copyOf.arraySizes;
|
*arraySizes = *copyOf.arraySizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copyOf.structure) {
|
if (copyOf.isStruct() && copyOf.structure) {
|
||||||
auto prevCopy = copiedMap.find(copyOf.structure);
|
auto prevCopy = copiedMap.find(copyOf.structure);
|
||||||
if (prevCopy != copiedMap.end())
|
if (prevCopy != copiedMap.end())
|
||||||
structure = prevCopy->second;
|
structure = prevCopy->second;
|
||||||
@ -2082,7 +2142,12 @@ protected:
|
|||||||
TQualifier qualifier;
|
TQualifier qualifier;
|
||||||
|
|
||||||
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
|
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 *fieldName; // for structure field names
|
||||||
TString *typeName; // for structure type name
|
TString *typeName; // for structure type name
|
||||||
TSampler sampler;
|
TSampler sampler;
|
||||||
|
@ -269,6 +269,10 @@ enum TOperator {
|
|||||||
EOpConvDoubleToFloat16,
|
EOpConvDoubleToFloat16,
|
||||||
EOpConvDoubleToFloat,
|
EOpConvDoubleToFloat,
|
||||||
|
|
||||||
|
// uint64_t <-> pointer
|
||||||
|
EOpConvUint64ToPtr,
|
||||||
|
EOpConvPtrToUint64,
|
||||||
|
|
||||||
//
|
//
|
||||||
// binary operations
|
// binary operations
|
||||||
//
|
//
|
||||||
@ -732,6 +736,7 @@ enum TOperator {
|
|||||||
EOpConstructStruct,
|
EOpConstructStruct,
|
||||||
EOpConstructTextureSampler,
|
EOpConstructTextureSampler,
|
||||||
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
||||||
|
EOpConstructReference,
|
||||||
EOpConstructGuardEnd,
|
EOpConstructGuardEnd,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -984,6 +984,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
case EOpSequence:
|
case EOpSequence:
|
||||||
case EOpConstructStruct:
|
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())
|
if (type.getBasicType() == node->getType().getBasicType())
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
@ -2131,6 +2139,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EbtReference:
|
||||||
|
op = EOpConstructReference;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -354,6 +354,11 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
|
|||||||
if (variable->getType().getQualifier().isIo())
|
if (variable->getType().getQualifier().isIo())
|
||||||
intermediate.addIoAccessed(*string);
|
intermediate.addIoAccessed(*string);
|
||||||
|
|
||||||
|
if (variable->getType().getBasicType() == EbtReference &&
|
||||||
|
variable->getType().getQualifier().isMemory()) {
|
||||||
|
intermediate.setUseVulkanMemoryModel();
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,8 +816,12 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||||||
if (base->getType().getQualifier().isSpecConstant())
|
if (base->getType().getQualifier().isSpecConstant())
|
||||||
result->getWritableType().getQualifier().makeSpecConstant();
|
result->getWritableType().getQualifier().makeSpecConstant();
|
||||||
}
|
}
|
||||||
} else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) {
|
} else if (base->getBasicType() == EbtStruct ||
|
||||||
const TTypeList* fields = base->getType().getStruct();
|
base->getBasicType() == EbtBlock ||
|
||||||
|
base->getBasicType() == EbtReference) {
|
||||||
|
const TTypeList* fields = base->getBasicType() == EbtReference ?
|
||||||
|
base->getType().getReferentType()->getStruct() :
|
||||||
|
base->getType().getStruct();
|
||||||
bool fieldFound = false;
|
bool fieldFound = false;
|
||||||
int member;
|
int member;
|
||||||
for (member = 0; member < (int)fields->size(); ++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
|
// Let the base class check errors
|
||||||
if (TParseContextBase::lValueErrorCheck(loc, op, node))
|
if (TParseContextBase::lValueErrorCheck(loc, op, node))
|
||||||
return true;
|
return true;
|
||||||
@ -3096,13 +3109,17 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
if (! symbolTable.atGlobalLevel())
|
if (! symbolTable.atGlobalLevel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
|
if (!(publicType.userDef && publicType.userDef->getBasicType() == EbtReference)) {
|
||||||
error(loc, "memory qualifiers cannot be used on this type", "", "");
|
if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
|
||||||
} else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
|
error(loc, "memory qualifiers cannot be used on this type", "", "");
|
||||||
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", "");
|
error(loc, "buffers can be declared only as blocks", "buffer", "");
|
||||||
|
|
||||||
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
|
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
|
||||||
@ -3760,6 +3777,21 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType
|
|||||||
if (isRuntimeLength(base))
|
if (isRuntimeLength(base))
|
||||||
return;
|
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
|
// check for additional things allowed by GL_EXT_nonuniform_qualifier
|
||||||
if (base.getBasicType() == EbtSampler ||
|
if (base.getBasicType() == EbtSampler ||
|
||||||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
|
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
|
||||||
@ -3777,6 +3809,10 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
|
|||||||
if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
|
if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
|
||||||
// is it the last member?
|
// is it the last member?
|
||||||
const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
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();
|
const int memberCount = (int)binary->getLeft()->getType().getStruct()->size();
|
||||||
if (index == memberCount - 1)
|
if (index == memberCount - 1)
|
||||||
return true;
|
return true;
|
||||||
@ -4655,6 +4691,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
publicType.qualifier.layoutPushConstant = true;
|
publicType.qualifier.layoutPushConstant = true;
|
||||||
return;
|
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
|
if (language == EShLangGeometry || language == EShLangTessEvaluation
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|| language == EShLangMeshNV
|
|| language == EShLangMeshNV
|
||||||
@ -5013,6 +5057,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
}
|
}
|
||||||
#endif
|
#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) {
|
switch (language) {
|
||||||
case EShLangVertex:
|
case EShLangVertex:
|
||||||
break;
|
break;
|
||||||
@ -5177,6 +5230,9 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
|||||||
if (src.hasAlign())
|
if (src.hasAlign())
|
||||||
dst.layoutAlign = src.layoutAlign;
|
dst.layoutAlign = src.layoutAlign;
|
||||||
|
|
||||||
|
if (src.hasBufferReferenceAlign())
|
||||||
|
dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign;
|
||||||
|
|
||||||
if (! inheritOnly) {
|
if (! inheritOnly) {
|
||||||
if (src.hasLocation())
|
if (src.hasLocation())
|
||||||
dst.layoutLocation = src.layoutLocation;
|
dst.layoutLocation = src.layoutLocation;
|
||||||
@ -5205,6 +5261,9 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
|||||||
if (src.layoutPushConstant)
|
if (src.layoutPushConstant)
|
||||||
dst.layoutPushConstant = true;
|
dst.layoutPushConstant = true;
|
||||||
|
|
||||||
|
if (src.layoutBufferReference)
|
||||||
|
dst.layoutBufferReference = true;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (src.layoutPassthrough)
|
if (src.layoutPassthrough)
|
||||||
dst.layoutPassthrough = true;
|
dst.layoutPassthrough = true;
|
||||||
@ -5452,7 +5511,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
!qualifier.layoutShaderRecordNV &&
|
!qualifier.layoutShaderRecordNV &&
|
||||||
#endif
|
#endif
|
||||||
!qualifier.layoutAttachment)
|
!qualifier.layoutAttachment &&
|
||||||
|
!qualifier.layoutBufferReference)
|
||||||
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
|
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
|
||||||
else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler)
|
else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler)
|
||||||
error(loc, "sampler/texture/image requires layout(binding=X)", "binding", "");
|
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)
|
if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock)
|
||||||
error(loc, "can only be used with a block", "push_constant", "");
|
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
|
#ifdef NV_EXTENSIONS
|
||||||
if (qualifier.layoutShaderRecordNV && type.getBasicType() != EbtBlock)
|
if (qualifier.layoutShaderRecordNV && type.getBasicType() != EbtBlock)
|
||||||
error(loc, "can only be used with a block", "shaderRecordNV", "");
|
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())
|
if (qualifier.hasSet())
|
||||||
error(loc, "cannot be used with push_constant", "set", "");
|
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
|
#ifdef NV_EXTENSIONS
|
||||||
if (qualifier.layoutShaderRecordNV) {
|
if (qualifier.layoutShaderRecordNV) {
|
||||||
if (qualifier.storage != EvqBuffer)
|
if (qualifier.storage != EvqBuffer)
|
||||||
@ -6051,7 +6118,7 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publicType.qualifier.hasLayout())
|
if (publicType.qualifier.hasLayout() && !publicType.qualifier.layoutBufferReference)
|
||||||
warn(loc, "useless application of layout qualifier", "layout", "");
|
warn(loc, "useless application of layout qualifier", "layout", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6659,10 +6726,15 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
|||||||
basicOp = EOpConstructInt64;
|
basicOp = EOpConstructInt64;
|
||||||
break;
|
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 EOpConstructU64Vec2:
|
||||||
case EOpConstructU64Vec3:
|
case EOpConstructU64Vec3:
|
||||||
case EOpConstructU64Vec4:
|
case EOpConstructU64Vec4:
|
||||||
case EOpConstructUint64:
|
|
||||||
basicOp = EOpConstructUint64;
|
basicOp = EOpConstructUint64;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -6678,6 +6750,19 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
|||||||
return node;
|
return node;
|
||||||
break;
|
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:
|
default:
|
||||||
error(loc, "unsupported construction", "", "");
|
error(loc, "unsupported construction", "", "");
|
||||||
|
|
||||||
@ -6922,31 +7007,57 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
else
|
else
|
||||||
ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
|
ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
|
||||||
|
|
||||||
//
|
if (currentBlockQualifier.layoutBufferReference) {
|
||||||
// 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.
|
if (currentBlockQualifier.storage != EvqBuffer)
|
||||||
//
|
error(loc, "can only be used with buffer", "buffer_reference", "");
|
||||||
// "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
|
// Create the block reference type. If it was forward-declared, detect that
|
||||||
// other than as a block name (e.g., use of a block name for a global variable name or function name is
|
// as a referent struct type with no members. Replace the referent type with
|
||||||
// currently reserved)."
|
// blockType.
|
||||||
//
|
TType blockNameType(EbtReference, blockType, *blockName);
|
||||||
// Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
|
TVariable* blockNameVar = new TVariable(blockName, blockNameType, true);
|
||||||
// whose type is EbtBlock, but without all the structure; that will come from the type
|
if (! symbolTable.insert(*blockNameVar)) {
|
||||||
// the instances point to.
|
TSymbol* existingName = symbolTable.find(*blockName);
|
||||||
//
|
if (existingName->getType().getBasicType() == EbtReference &&
|
||||||
TType blockNameType(EbtBlock, blockType.getQualifier().storage);
|
existingName->getType().getReferentType()->getStruct() &&
|
||||||
TVariable* blockNameVar = new TVariable(blockName, blockNameType);
|
existingName->getType().getReferentType()->getStruct()->size() == 0 &&
|
||||||
if (! symbolTable.insert(*blockNameVar)) {
|
existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
|
||||||
TSymbol* existingName = symbolTable.find(*blockName);
|
existingName->getType().getReferentType()->deepCopy(blockType);
|
||||||
if (existingName->getType().getBasicType() == EbtBlock) {
|
} else {
|
||||||
if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
|
error(loc, "block name cannot be redefined", blockName->c_str(), "");
|
||||||
error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
|
}
|
||||||
|
}
|
||||||
|
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;
|
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)
|
void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
|
||||||
{
|
{
|
||||||
TSymbol* symbol = symbolTable.find(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) {
|
if (! symbol) {
|
||||||
error(loc, "identifier not previously declared", identifier.c_str(), "");
|
error(loc, "identifier not previously declared", identifier.c_str(), "");
|
||||||
return;
|
return;
|
||||||
@ -7580,6 +7707,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
|||||||
error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
|
error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
|
||||||
if (qualifier.layoutPushConstant)
|
if (qualifier.layoutPushConstant)
|
||||||
error(loc, "cannot declare a default, can only be used on a block", "push_constant", "");
|
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())
|
if (qualifier.hasSpecConstantId())
|
||||||
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
|
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
@ -776,7 +776,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
|||||||
loc = ppToken.loc;
|
loc = ppToken.loc;
|
||||||
parserToken->sType.lex.loc = loc;
|
parserToken->sType.lex.loc = loc;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case ';': afterType = false; return SEMICOLON;
|
case ';': afterType = false; afterBuffer = false; return SEMICOLON;
|
||||||
case ',': afterType = false; return COMMA;
|
case ',': afterType = false; return COMMA;
|
||||||
case ':': return COLON;
|
case ':': return COLON;
|
||||||
case '=': afterType = false; return EQUAL;
|
case '=': afterType = false; return EQUAL;
|
||||||
@ -798,7 +798,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
|||||||
case '?': return QUESTION;
|
case '?': return QUESTION;
|
||||||
case '[': return LEFT_BRACKET;
|
case '[': return LEFT_BRACKET;
|
||||||
case ']': return RIGHT_BRACKET;
|
case ']': return RIGHT_BRACKET;
|
||||||
case '{': afterStruct = false; return LEFT_BRACE;
|
case '{': afterStruct = false; afterBuffer = false; return LEFT_BRACE;
|
||||||
case '}': return RIGHT_BRACE;
|
case '}': return RIGHT_BRACE;
|
||||||
case '\\':
|
case '\\':
|
||||||
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
||||||
@ -945,6 +945,7 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
case BUFFER:
|
case BUFFER:
|
||||||
|
afterBuffer = true;
|
||||||
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
|
||||||
(parseContext.profile != EEsProfile && parseContext.version < 430))
|
(parseContext.profile != EEsProfile && parseContext.version < 430))
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
@ -1617,7 +1618,9 @@ int TScanContext::identifierOrType()
|
|||||||
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
|
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
|
||||||
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
|
if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
|
||||||
if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
|
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;
|
afterType = true;
|
||||||
|
|
||||||
return TYPE_NAME;
|
return TYPE_NAME;
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
explicit TScanContext(TParseContextBase& pc) :
|
explicit TScanContext(TParseContextBase& pc) :
|
||||||
parseContext(pc),
|
parseContext(pc),
|
||||||
afterType(false), afterStruct(false),
|
afterType(false), afterStruct(false),
|
||||||
field(false) { }
|
field(false), afterBuffer(false) { }
|
||||||
virtual ~TScanContext() { }
|
virtual ~TScanContext() { }
|
||||||
|
|
||||||
static void fillInKeywordMap();
|
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 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 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 field; // true if we're on a field, right after a '.'
|
||||||
|
bool afterBuffer; // true if we've recognized the BUFFER keyword
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
TParserToken* parserToken;
|
TParserToken* parserToken;
|
||||||
TPpToken* ppToken;
|
TPpToken* ppToken;
|
||||||
|
@ -207,6 +207,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
|
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_fragment_invocation_density] = 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_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_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_samplerless_texture_functions 1\n"
|
||||||
"#define GL_EXT_scalar_block_layout 1\n"
|
"#define GL_EXT_scalar_block_layout 1\n"
|
||||||
"#define GL_EXT_fragment_invocation_density 1\n"
|
"#define GL_EXT_fragment_invocation_density 1\n"
|
||||||
|
"#define GL_EXT_buffer_reference 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#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_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_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_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
|
// 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 EOpIndexDirect: out.debug << "direct index"; break;
|
||||||
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
||||||
case EOpIndexDirectStruct:
|
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 EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
||||||
case EOpMatrixSwizzle: out.debug << "matrix 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 EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
||||||
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; 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 EOpRadians: out.debug << "radians"; break;
|
||||||
case EOpDegrees: out.debug << "degrees"; 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 EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
|
case EOpConstructReference: out.debug << "Construct reference type"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
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 EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break;
|
||||||
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||||
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; 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 EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||||
case EOpGreaterThan: out.debug << "Compare Greater 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(needToLegalize);
|
||||||
MERGE_TRUE(binaryDoubleOutput);
|
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 EbtUint8: size = 1; return 1;
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
case EbtUint16: size = 2; return 2;
|
case EbtUint16: size = 2; return 2;
|
||||||
|
case EbtReference: size = 8; return 8;
|
||||||
default: size = 4; return 4;
|
default: size = 4; return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,6 +255,7 @@ public:
|
|||||||
textureSamplerTransformMode(EShTexSampTransKeep),
|
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||||
needToLegalize(false),
|
needToLegalize(false),
|
||||||
binaryDoubleOutput(false),
|
binaryDoubleOutput(false),
|
||||||
|
usePhysicalStorageBuffer(false),
|
||||||
uniformLocationBase(0)
|
uniformLocationBase(0)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
@ -390,6 +391,11 @@ public:
|
|||||||
processes.addProcess("use-vulkan-memory-model");
|
processes.addProcess("use-vulkan-memory-model");
|
||||||
}
|
}
|
||||||
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
|
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; }
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
bool hasCounterBufferName(const TString& name) const {
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
@ -825,6 +831,7 @@ protected:
|
|||||||
|
|
||||||
bool needToLegalize;
|
bool needToLegalize;
|
||||||
bool binaryDoubleOutput;
|
bool binaryDoubleOutput;
|
||||||
|
bool usePhysicalStorageBuffer;
|
||||||
|
|
||||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||||
int uniformLocationBase;
|
int uniformLocationBase;
|
||||||
|
@ -265,6 +265,22 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.bool.vert",
|
"spv.bool.vert",
|
||||||
"spv.boolInBlock.frag",
|
"spv.boolInBlock.frag",
|
||||||
"spv.branch-return.vert",
|
"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.builtInXFB.vert",
|
||||||
"spv.conditionalDiscard.frag",
|
"spv.conditionalDiscard.frag",
|
||||||
"spv.constStruct.vert",
|
"spv.constStruct.vert",
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
"site" : "github",
|
"site" : "github",
|
||||||
"subrepo" : "KhronosGroup/SPIRV-Tools",
|
"subrepo" : "KhronosGroup/SPIRV-Tools",
|
||||||
"subdir" : "External/spirv-tools",
|
"subdir" : "External/spirv-tools",
|
||||||
"commit" : "a87d3ce48e88a653e855c3245a6b68deeae58efc"
|
"commit" : "5eab6df648eace6eab69c44ccd17bd0f5e57406d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "spirv-tools/external/spirv-headers",
|
"name" : "spirv-tools/external/spirv-headers",
|
||||||
"site" : "github",
|
"site" : "github",
|
||||||
"subrepo" : "KhronosGroup/SPIRV-Headers",
|
"subrepo" : "KhronosGroup/SPIRV-Headers",
|
||||||
"subdir" : "External/spirv-tools/external/spirv-headers",
|
"subdir" : "External/spirv-tools/external/spirv-headers",
|
||||||
"commit" : "4618b86e9e4b027a22040732dfee35e399cd2c47"
|
"commit" : "79b6681aadcb53c27d1052e5f8a0e82a981dbf2f"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user