GL_KHR_memory_scope_semantics
This commit is contained in:
		
							parent
							
								
									97068d8b30
								
							
						
					
					
						commit
						36831c9bad
					
				@ -39,5 +39,6 @@ static const char* const E_SPV_KHR_16bit_storage                = "SPV_KHR_16bit
 | 
				
			|||||||
static const char* const E_SPV_KHR_8bit_storage                 = "SPV_KHR_8bit_storage";
 | 
					static const char* const E_SPV_KHR_8bit_storage                 = "SPV_KHR_8bit_storage";
 | 
				
			||||||
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";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // #ifndef GLSLextKHR_H
 | 
					#endif  // #ifndef GLSLextKHR_H
 | 
				
			||||||
 | 
				
			|||||||
@ -129,6 +129,10 @@ protected:
 | 
				
			|||||||
    spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
 | 
					    spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
 | 
				
			||||||
    spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
 | 
					    spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
 | 
				
			||||||
    spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
 | 
					    spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
 | 
				
			||||||
 | 
					    spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type);
 | 
				
			||||||
 | 
					    spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
 | 
				
			||||||
 | 
					    spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
 | 
				
			||||||
 | 
					    spv::Scope TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
 | 
				
			||||||
    spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
 | 
					    spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
 | 
				
			||||||
    spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
 | 
					    spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
 | 
				
			||||||
    spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
 | 
					    spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
 | 
				
			||||||
@ -327,13 +331,15 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Translate glslang type to SPIR-V memory decorations.
 | 
					// Translate glslang type to SPIR-V memory decorations.
 | 
				
			||||||
void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory)
 | 
					void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (qualifier.coherent)
 | 
					    if (!useVulkanMemoryModel) {
 | 
				
			||||||
        memory.push_back(spv::DecorationCoherent);
 | 
					        if (qualifier.coherent)
 | 
				
			||||||
    if (qualifier.volatil) {
 | 
					            memory.push_back(spv::DecorationCoherent);
 | 
				
			||||||
        memory.push_back(spv::DecorationVolatile);
 | 
					        if (qualifier.volatil) {
 | 
				
			||||||
        memory.push_back(spv::DecorationCoherent);
 | 
					            memory.push_back(spv::DecorationVolatile);
 | 
				
			||||||
 | 
					            memory.push_back(spv::DecorationCoherent);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (qualifier.restrict)
 | 
					    if (qualifier.restrict)
 | 
				
			||||||
        memory.push_back(spv::DecorationRestrict);
 | 
					        memory.push_back(spv::DecorationRestrict);
 | 
				
			||||||
@ -450,6 +456,105 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl
 | 
				
			|||||||
        return spv::DecorationMax;
 | 
					        return spv::DecorationMax;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) {
 | 
				
			||||||
 | 
					        return spv::MemoryAccessMaskNone;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
 | 
				
			||||||
 | 
					    if (coherentFlags.volatil ||
 | 
				
			||||||
 | 
					        coherentFlags.coherent ||
 | 
				
			||||||
 | 
					        coherentFlags.devicecoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.queuefamilycoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.workgroupcoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.subgroupcoherent) {
 | 
				
			||||||
 | 
					        mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask |
 | 
				
			||||||
 | 
					                      spv::MemoryAccessMakePointerVisibleKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (coherentFlags.nonprivate) {
 | 
				
			||||||
 | 
					        mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (coherentFlags.volatil) {
 | 
				
			||||||
 | 
					        mask = mask | spv::MemoryAccessVolatileMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (mask != spv::MemoryAccessMaskNone) {
 | 
				
			||||||
 | 
					        builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!glslangIntermediate->usingVulkanMemoryModel()) {
 | 
				
			||||||
 | 
					        return spv::ImageOperandsMaskNone;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
 | 
				
			||||||
 | 
					    if (coherentFlags.volatil ||
 | 
				
			||||||
 | 
					        coherentFlags.coherent ||
 | 
				
			||||||
 | 
					        coherentFlags.devicecoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.queuefamilycoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.workgroupcoherent ||
 | 
				
			||||||
 | 
					        coherentFlags.subgroupcoherent) {
 | 
				
			||||||
 | 
					        mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask |
 | 
				
			||||||
 | 
					                      spv::ImageOperandsMakeTexelVisibleKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (coherentFlags.nonprivate) {
 | 
				
			||||||
 | 
					        mask = mask | spv::ImageOperandsNonPrivateTexelKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (coherentFlags.volatil) {
 | 
				
			||||||
 | 
					        mask = mask | spv::ImageOperandsVolatileTexelKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (mask != spv::ImageOperandsMaskNone) {
 | 
				
			||||||
 | 
					        builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    spv::Builder::AccessChain::CoherentFlags flags;
 | 
				
			||||||
 | 
					    flags.coherent = type.getQualifier().coherent;
 | 
				
			||||||
 | 
					    flags.devicecoherent = type.getQualifier().devicecoherent;
 | 
				
			||||||
 | 
					    flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
 | 
				
			||||||
 | 
					    // shared variables are implicitly workgroupcoherent in GLSL.
 | 
				
			||||||
 | 
					    flags.workgroupcoherent = type.getQualifier().workgroupcoherent ||
 | 
				
			||||||
 | 
					                              type.getQualifier().storage == glslang::EvqShared;
 | 
				
			||||||
 | 
					    flags.subgroupcoherent = type.getQualifier().subgroupcoherent;
 | 
				
			||||||
 | 
					    // *coherent variables are implicitly nonprivate in GLSL
 | 
				
			||||||
 | 
					    flags.nonprivate = type.getQualifier().nonprivate ||
 | 
				
			||||||
 | 
					                       type.getQualifier().subgroupcoherent ||
 | 
				
			||||||
 | 
					                       type.getQualifier().workgroupcoherent ||
 | 
				
			||||||
 | 
					                       type.getQualifier().queuefamilycoherent ||
 | 
				
			||||||
 | 
					                       type.getQualifier().devicecoherent ||
 | 
				
			||||||
 | 
					                       type.getQualifier().coherent;
 | 
				
			||||||
 | 
					    flags.volatil = type.getQualifier().volatil;
 | 
				
			||||||
 | 
					    flags.isImage = type.getBasicType() == glslang::EbtSampler;
 | 
				
			||||||
 | 
					    return flags;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    spv::Scope scope;
 | 
				
			||||||
 | 
					    if (coherentFlags.coherent) {
 | 
				
			||||||
 | 
					        // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
 | 
				
			||||||
 | 
					        scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
 | 
				
			||||||
 | 
					    } else if (coherentFlags.devicecoherent) {
 | 
				
			||||||
 | 
					        scope = spv::ScopeDevice;
 | 
				
			||||||
 | 
					    } else if (coherentFlags.queuefamilycoherent) {
 | 
				
			||||||
 | 
					        scope = spv::ScopeQueueFamilyKHR;
 | 
				
			||||||
 | 
					    } else if (coherentFlags.workgroupcoherent) {
 | 
				
			||||||
 | 
					        scope = spv::ScopeWorkgroup;
 | 
				
			||||||
 | 
					    } else if (coherentFlags.subgroupcoherent) {
 | 
				
			||||||
 | 
					        scope = spv::ScopeSubgroup;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        scope = spv::ScopeMax;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
 | 
				
			||||||
 | 
					        builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return scope;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Translate a glslang built-in variable to a SPIR-V built in decoration.  Also generate
 | 
					// Translate a glslang built-in variable to a SPIR-V built in decoration.  Also generate
 | 
				
			||||||
// associated capabilities when required.  For some built-in variables, a capability
 | 
					// associated capabilities when required.  For some built-in variables, a capability
 | 
				
			||||||
// is generated only when using the variable in an executable instruction, but not when
 | 
					// is generated only when using the variable in an executable instruction, but not when
 | 
				
			||||||
@ -979,6 +1084,16 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
 | 
				
			|||||||
        child.sample = true;
 | 
					        child.sample = true;
 | 
				
			||||||
    if (parent.coherent)
 | 
					    if (parent.coherent)
 | 
				
			||||||
        child.coherent = true;
 | 
					        child.coherent = true;
 | 
				
			||||||
 | 
					    if (parent.devicecoherent)
 | 
				
			||||||
 | 
					        child.devicecoherent = true;
 | 
				
			||||||
 | 
					    if (parent.queuefamilycoherent)
 | 
				
			||||||
 | 
					        child.queuefamilycoherent = true;
 | 
				
			||||||
 | 
					    if (parent.workgroupcoherent)
 | 
				
			||||||
 | 
					        child.workgroupcoherent = true;
 | 
				
			||||||
 | 
					    if (parent.subgroupcoherent)
 | 
				
			||||||
 | 
					        child.subgroupcoherent = true;
 | 
				
			||||||
 | 
					    if (parent.nonprivate)
 | 
				
			||||||
 | 
					        child.nonprivate = true;
 | 
				
			||||||
    if (parent.volatil)
 | 
					    if (parent.volatil)
 | 
				
			||||||
        child.volatil = true;
 | 
					        child.volatil = true;
 | 
				
			||||||
    if (parent.restrict)
 | 
					    if (parent.restrict)
 | 
				
			||||||
@ -1045,7 +1160,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
 | 
				
			|||||||
        builder.setSourceText(text);
 | 
					        builder.setSourceText(text);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    stdBuiltins = builder.import("GLSL.std.450");
 | 
					    stdBuiltins = builder.import("GLSL.std.450");
 | 
				
			||||||
    builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
 | 
					    if (glslangIntermediate->usingVulkanMemoryModel()) {
 | 
				
			||||||
 | 
					        builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelVulkanKHR);
 | 
				
			||||||
 | 
					        builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    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());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1351,7 +1471,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // store the result
 | 
					            // store the result
 | 
				
			||||||
            builder.setAccessChain(lValue);
 | 
					            builder.setAccessChain(lValue);
 | 
				
			||||||
            multiTypeStore(node->getType(), rValue);
 | 
					            multiTypeStore(node->getLeft()->getType(), rValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // assignments are expressions having an rValue after they are evaluated...
 | 
					            // assignments are expressions having an rValue after they are evaluated...
 | 
				
			||||||
            builder.clearAccessChain();
 | 
					            builder.clearAccessChain();
 | 
				
			||||||
@ -1388,7 +1508,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));
 | 
					                builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(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.
 | 
				
			||||||
@ -1424,7 +1544,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
 | 
				
			|||||||
            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()));
 | 
					                builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                builder.accessChainPush(index);
 | 
					                builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    case glslang::EOpVectorSwizzle:
 | 
					    case glslang::EOpVectorSwizzle:
 | 
				
			||||||
@ -1658,11 +1778,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
				
			|||||||
        builder.setAccessChainRValue(result);
 | 
					        builder.setAccessChainRValue(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 | 
					    } else if (node->getOp() == glslang::EOpImageStore ||
 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
    } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) {
 | 
					        node->getOp() == glslang::EOpImageStoreLod ||
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    } else if (node->getOp() == glslang::EOpImageStore) {
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					        node->getOp() == glslang::EOpImageAtomicStore) {
 | 
				
			||||||
        // "imageStore" is a special case, which has no result
 | 
					        // "imageStore" is a special case, which has no result
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1952,6 +2072,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
				
			|||||||
        // These all have 0 operands and will naturally finish up in the code below for 0 operands
 | 
					        // These all have 0 operands and will naturally finish up in the code below for 0 operands
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case glslang::EOpAtomicStore:
 | 
				
			||||||
 | 
					        noReturnValue = true;
 | 
				
			||||||
 | 
					        // fallthrough
 | 
				
			||||||
 | 
					    case glslang::EOpAtomicLoad:
 | 
				
			||||||
    case glslang::EOpAtomicAdd:
 | 
					    case glslang::EOpAtomicAdd:
 | 
				
			||||||
    case glslang::EOpAtomicMin:
 | 
					    case glslang::EOpAtomicMin:
 | 
				
			||||||
    case glslang::EOpAtomicMax:
 | 
					    case glslang::EOpAtomicMax:
 | 
				
			||||||
@ -2050,6 +2174,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
				
			|||||||
        case glslang::EOpAtomicXor:
 | 
					        case glslang::EOpAtomicXor:
 | 
				
			||||||
        case glslang::EOpAtomicExchange:
 | 
					        case glslang::EOpAtomicExchange:
 | 
				
			||||||
        case glslang::EOpAtomicCompSwap:
 | 
					        case glslang::EOpAtomicCompSwap:
 | 
				
			||||||
 | 
					        case glslang::EOpAtomicLoad:
 | 
				
			||||||
 | 
					        case glslang::EOpAtomicStore:
 | 
				
			||||||
        case glslang::EOpAtomicCounterAdd:
 | 
					        case glslang::EOpAtomicCounterAdd:
 | 
				
			||||||
        case glslang::EOpAtomicCounterSubtract:
 | 
					        case glslang::EOpAtomicCounterSubtract:
 | 
				
			||||||
        case glslang::EOpAtomicCounterMin:
 | 
					        case glslang::EOpAtomicCounterMin:
 | 
				
			||||||
@ -2876,7 +3002,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
 | 
				
			|||||||
            qualifier.storage == glslang::EvqBuffer) {
 | 
					            qualifier.storage == glslang::EvqBuffer) {
 | 
				
			||||||
            // Add memory decorations only to top-level members of shader storage block
 | 
					            // Add memory decorations only to top-level members of shader storage block
 | 
				
			||||||
            std::vector<spv::Decoration> memory;
 | 
					            std::vector<spv::Decoration> memory;
 | 
				
			||||||
            TranslateMemoryDecoration(memberQualifier, memory);
 | 
					            TranslateMemoryDecoration(memberQualifier, memory, glslangIntermediate->usingVulkanMemoryModel());
 | 
				
			||||||
            for (unsigned int i = 0; i < memory.size(); ++i)
 | 
					            for (unsigned int i = 0; i < memory.size(); ++i)
 | 
				
			||||||
                builder.addMemberDecoration(spvType, member, memory[i]);
 | 
					                builder.addMemberDecoration(spvType, member, memory[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -2987,8 +3113,15 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
 | 
				
			|||||||
spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
 | 
					spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    spv::Id nominalTypeId = builder.accessChainGetInferredType();
 | 
					    spv::Id nominalTypeId = builder.accessChainGetInferredType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
 | 
				
			||||||
 | 
					    coherentFlags |= TranslateCoherent(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
 | 
					    spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
 | 
				
			||||||
                                               TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId);
 | 
					                                               TranslateNonUniformDecoration(type.getQualifier()),
 | 
				
			||||||
 | 
					                                               nominalTypeId,
 | 
				
			||||||
 | 
					                                               spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
 | 
				
			||||||
 | 
					                                               TranslateMemoryScope(coherentFlags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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) {
 | 
				
			||||||
@ -3044,7 +3177,12 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    builder.accessChainStore(rvalue);
 | 
					    spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
 | 
				
			||||||
 | 
					    coherentFlags |= TranslateCoherent(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    builder.accessChainStore(rvalue,
 | 
				
			||||||
 | 
					                             spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
 | 
				
			||||||
 | 
					                             TranslateMemoryScope(coherentFlags));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			||||||
@ -3090,7 +3228,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));
 | 
					            builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // store the member
 | 
					            // store the member
 | 
				
			||||||
            multiTypeStore(glslangElementType, elementRValue);
 | 
					            multiTypeStore(glslangElementType, elementRValue);
 | 
				
			||||||
@ -3110,7 +3248,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));
 | 
					            builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // store the member
 | 
					            // store the member
 | 
				
			||||||
            multiTypeStore(glslangMemberType, memberRValue);
 | 
					            multiTypeStore(glslangMemberType, memberRValue);
 | 
				
			||||||
@ -3287,11 +3425,11 @@ 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) {
 | 
					    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);
 | 
					        TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
 | 
					    for (int f = 0; f < (int)glslFunctions.size(); ++f) {
 | 
				
			||||||
@ -3330,7 +3468,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
 | 
				
			|||||||
                typeId = builder.makePointer(spv::StorageClassFunction, typeId);
 | 
					                typeId = builder.makePointer(spv::StorageClassFunction, typeId);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId());
 | 
					                rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId());
 | 
				
			||||||
            getParamDecorations(paramDecorations[p], paramType);
 | 
					            getParamDecorations(paramDecorations[p], paramType, glslangIntermediate->usingVulkanMemoryModel());
 | 
				
			||||||
            paramTypes.push_back(typeId);
 | 
					            paramTypes.push_back(typeId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3420,6 +3558,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
 | 
				
			|||||||
        case glslang::EOpImageAtomicXor:
 | 
					        case glslang::EOpImageAtomicXor:
 | 
				
			||||||
        case glslang::EOpImageAtomicExchange:
 | 
					        case glslang::EOpImageAtomicExchange:
 | 
				
			||||||
        case glslang::EOpImageAtomicCompSwap:
 | 
					        case glslang::EOpImageAtomicCompSwap:
 | 
				
			||||||
 | 
					        case glslang::EOpImageAtomicLoad:
 | 
				
			||||||
 | 
					        case glslang::EOpImageAtomicStore:
 | 
				
			||||||
            if (i == 0)
 | 
					            if (i == 0)
 | 
				
			||||||
                lvalue = true;
 | 
					                lvalue = true;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -3547,8 +3687,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
    builder.setLine(node->getLoc().line);
 | 
					    builder.setLine(node->getLoc().line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Process a GLSL texturing op (will be SPV image)
 | 
					    // Process a GLSL texturing op (will be SPV image)
 | 
				
			||||||
    const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler()
 | 
					
 | 
				
			||||||
                                                             : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler();
 | 
					    const glslang::TType &imageType = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
 | 
				
			||||||
 | 
					                                                             : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
 | 
				
			||||||
 | 
					    const glslang::TSampler sampler = imageType.getSampler();
 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
    bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
 | 
					    bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
 | 
				
			||||||
                                ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
 | 
					                                ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
 | 
				
			||||||
@ -3651,22 +3793,38 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
        if (node->getOp() == glslang::EOpImageLoad) {
 | 
					        if (node->getOp() == glslang::EOpImageLoad) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					            spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
 | 
				
			||||||
            if (sampler.ms) {
 | 
					            if (sampler.ms) {
 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
 | 
					                mask = mask | spv::ImageOperandsSampleMask;
 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					            }
 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
            } else if (cracked.lod) {
 | 
					            if (cracked.lod) {
 | 
				
			||||||
                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
					                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
				
			||||||
                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
					                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
				
			||||||
 | 
					                mask = mask | spv::ImageOperandsLodMask;
 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
 | 
				
			||||||
 | 
					            mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
 | 
				
			||||||
 | 
					            if (mask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperands = { false, (unsigned int)mask };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperands);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsSampleMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsLodMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
					            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
				
			||||||
                builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 | 
					                builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3683,29 +3841,52 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
        } else if (node->getOp() == glslang::EOpImageStore) {
 | 
					        } else if (node->getOp() == glslang::EOpImageStore) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            if (sampler.ms) {
 | 
					 | 
				
			||||||
                spv::IdImmediate texel = { true, *(opIt + 1) };
 | 
					 | 
				
			||||||
                operands.push_back(texel);
 | 
					 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					 | 
				
			||||||
            } else if (cracked.lod) {
 | 
					 | 
				
			||||||
                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
					 | 
				
			||||||
                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Push the texel value before the operands
 | 
				
			||||||
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
 | 
					            if (sampler.ms || cracked.lod) {
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            if (sampler.ms) {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
                spv::IdImmediate texel = { true, *(opIt + 1) };
 | 
					                spv::IdImmediate texel = { true, *(opIt + 1) };
 | 
				
			||||||
                operands.push_back(texel);
 | 
					                operands.push_back(texel);
 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                spv::IdImmediate texel = { true, *opIt };
 | 
					                spv::IdImmediate texel = { true, *opIt };
 | 
				
			||||||
                operands.push_back(texel);
 | 
					                operands.push_back(texel);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
 | 
				
			||||||
 | 
					            if (sampler.ms) {
 | 
				
			||||||
 | 
					                mask = mask | spv::ImageOperandsSampleMask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
 | 
					            if (cracked.lod) {
 | 
				
			||||||
 | 
					                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
				
			||||||
 | 
					                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
				
			||||||
 | 
					                mask = mask | spv::ImageOperandsLodMask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
 | 
				
			||||||
 | 
					            mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask);
 | 
				
			||||||
 | 
					            if (mask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperands = { false, (unsigned int)mask };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperands);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsSampleMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsLodMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            builder.createNoResultOp(spv::OpImageWrite, operands);
 | 
					            builder.createNoResultOp(spv::OpImageWrite, operands);
 | 
				
			||||||
            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
					            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
				
			||||||
                builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
 | 
					                builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
 | 
				
			||||||
@ -3719,21 +3900,37 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
					            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
 | 
				
			||||||
                builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 | 
					                builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
 | 
				
			||||||
            if (sampler.ms) {
 | 
					            if (sampler.ms) {
 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
 | 
					                mask = mask | spv::ImageOperandsSampleMask;
 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					            }
 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
					 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
            } else if (cracked.lod) {
 | 
					            if (cracked.lod) {
 | 
				
			||||||
                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
					                builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
 | 
				
			||||||
                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
					                builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
 | 
					                mask = mask | spv::ImageOperandsLodMask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
 | 
				
			||||||
 | 
					            mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
 | 
				
			||||||
 | 
					            if (mask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperands = { false, (unsigned int)mask };
 | 
				
			||||||
                operands.push_back(imageOperands);
 | 
					                operands.push_back(imageOperands);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsSampleMask) {
 | 
				
			||||||
                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
                operands.push_back(imageOperand);
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsLodMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, *opIt++ };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					            if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
 | 
				
			||||||
 | 
					                spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
 | 
				
			||||||
 | 
					                operands.push_back(imageOperand);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Create the return type that was a special structure
 | 
					            // Create the return type that was a special structure
 | 
				
			||||||
@ -3756,7 +3953,14 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
            spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
 | 
					            spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
 | 
				
			||||||
            operands.push_back(sample);
 | 
					            operands.push_back(sample);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
 | 
					            spv::Id resultTypeId;
 | 
				
			||||||
 | 
					            // imageAtomicStore has a void return type so base the pointer type on
 | 
				
			||||||
 | 
					            // the type of the value operand.
 | 
				
			||||||
 | 
					            if (node->getOp() == glslang::EOpImageAtomicStore) {
 | 
				
			||||||
 | 
					                resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word));                
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
 | 
					            spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::vector<spv::Id> operands;
 | 
					            std::vector<spv::Id> operands;
 | 
				
			||||||
@ -3972,6 +4176,16 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // nonprivate
 | 
				
			||||||
 | 
					    if (imageType.getQualifier().nonprivate) {
 | 
				
			||||||
 | 
					        params.nonprivate = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // volatile
 | 
				
			||||||
 | 
					    if (imageType.getQualifier().volatil) {
 | 
				
			||||||
 | 
					        params.volatil = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector<spv::Id> result( 1, 
 | 
					    std::vector<spv::Id> result( 1, 
 | 
				
			||||||
        builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
 | 
					        builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -5340,8 +5554,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
 | 
				
			|||||||
        opCode = spv::OpAtomicIDecrement;
 | 
					        opCode = spv::OpAtomicIDecrement;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case glslang::EOpAtomicCounter:
 | 
					    case glslang::EOpAtomicCounter:
 | 
				
			||||||
 | 
					    case glslang::EOpImageAtomicLoad:
 | 
				
			||||||
 | 
					    case glslang::EOpAtomicLoad:
 | 
				
			||||||
        opCode = spv::OpAtomicLoad;
 | 
					        opCode = spv::OpAtomicLoad;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case glslang::EOpAtomicStore:
 | 
				
			||||||
 | 
					    case glslang::EOpImageAtomicStore:
 | 
				
			||||||
 | 
					        opCode = spv::OpAtomicStore;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        assert(0);
 | 
					        assert(0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -5352,36 +5572,82 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Sort out the operands
 | 
					    // Sort out the operands
 | 
				
			||||||
    //  - mapping from glslang -> SPV
 | 
					    //  - mapping from glslang -> SPV
 | 
				
			||||||
    //  - there are extra SPV operands with no glslang source
 | 
					    //  - there are extra SPV operands that are optional in glslang
 | 
				
			||||||
    //  - compare-exchange swaps the value and comparator
 | 
					    //  - compare-exchange swaps the value and comparator
 | 
				
			||||||
    //  - compare-exchange has an extra memory semantics
 | 
					    //  - compare-exchange has an extra memory semantics
 | 
				
			||||||
    //  - EOpAtomicCounterDecrement needs a post decrement
 | 
					    //  - EOpAtomicCounterDecrement needs a post decrement
 | 
				
			||||||
    std::vector<spv::Id> spvAtomicOperands;  // hold the spv operands
 | 
					    spv::Id pointerId = 0, compareId = 0, valueId = 0;
 | 
				
			||||||
    auto opIt = operands.begin();            // walk the glslang operands
 | 
					    // scope defaults to Device in the old model, QueueFamilyKHR in the new model
 | 
				
			||||||
    spvAtomicOperands.push_back(*(opIt++));
 | 
					    spv::Id scopeId;
 | 
				
			||||||
    spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice));     // TBD: what is the correct scope?
 | 
					    if (glslangIntermediate->usingVulkanMemoryModel()) {
 | 
				
			||||||
    spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
 | 
					        scopeId = builder.makeUintConstant(spv::ScopeQueueFamilyKHR);
 | 
				
			||||||
    if (opCode == spv::OpAtomicCompareExchange) {
 | 
					    } else {
 | 
				
			||||||
        // There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL
 | 
					        scopeId = builder.makeUintConstant(spv::ScopeDevice);
 | 
				
			||||||
        // differs from that in SPIR-V. Hence, special processing is required.
 | 
					    }
 | 
				
			||||||
        spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone));
 | 
					    // semantics default to relaxed 
 | 
				
			||||||
        spvAtomicOperands.push_back(*(opIt + 1));
 | 
					    spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone);
 | 
				
			||||||
        spvAtomicOperands.push_back(*opIt);
 | 
					    spv::Id semanticsId2 = semanticsId;
 | 
				
			||||||
        opIt += 2;
 | 
					
 | 
				
			||||||
 | 
					    pointerId = operands[0];
 | 
				
			||||||
 | 
					    if (opCode == spv::OpAtomicIIncrement || opCode == spv::OpAtomicIDecrement) {
 | 
				
			||||||
 | 
					        // no additional operands
 | 
				
			||||||
 | 
					    } else if (opCode == spv::OpAtomicCompareExchange) {
 | 
				
			||||||
 | 
					        compareId = operands[1];
 | 
				
			||||||
 | 
					        valueId = operands[2];
 | 
				
			||||||
 | 
					        if (operands.size() > 3) {
 | 
				
			||||||
 | 
					            scopeId = operands[3];
 | 
				
			||||||
 | 
					            semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5]));
 | 
				
			||||||
 | 
					            semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if (opCode == spv::OpAtomicLoad) {
 | 
				
			||||||
 | 
					        if (operands.size() > 1) {
 | 
				
			||||||
 | 
					            scopeId = operands[1];
 | 
				
			||||||
 | 
					            semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // atomic store or RMW
 | 
				
			||||||
 | 
					        valueId = operands[1];
 | 
				
			||||||
 | 
					        if (operands.size() > 2) {
 | 
				
			||||||
 | 
					            scopeId = operands[2];
 | 
				
			||||||
 | 
					            semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Add the rest of the operands, skipping any that were dealt with above.
 | 
					    // Check for capabilities
 | 
				
			||||||
    for (; opIt != operands.end(); ++opIt)
 | 
					    unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2);
 | 
				
			||||||
        spvAtomicOperands.push_back(*opIt);
 | 
					    if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
 | 
				
			||||||
 | 
					        builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands);
 | 
					    if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
 | 
				
			||||||
 | 
					        builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // GLSL and HLSL atomic-counter decrement return post-decrement value,
 | 
					    std::vector<spv::Id> spvAtomicOperands;  // hold the spv operands
 | 
				
			||||||
    // while SPIR-V returns pre-decrement value. Translate between these semantics.
 | 
					    spvAtomicOperands.push_back(pointerId);
 | 
				
			||||||
    if (op == glslang::EOpAtomicCounterDecrement)
 | 
					    spvAtomicOperands.push_back(scopeId);
 | 
				
			||||||
        resultId = builder.createBinOp(spv::OpISub, typeId, resultId, builder.makeIntConstant(1));
 | 
					    spvAtomicOperands.push_back(semanticsId);
 | 
				
			||||||
 | 
					    if (opCode == spv::OpAtomicCompareExchange) {
 | 
				
			||||||
 | 
					        spvAtomicOperands.push_back(semanticsId2);
 | 
				
			||||||
 | 
					        spvAtomicOperands.push_back(valueId);
 | 
				
			||||||
 | 
					        spvAtomicOperands.push_back(compareId);
 | 
				
			||||||
 | 
					    } else if (opCode != spv::OpAtomicLoad && opCode != spv::OpAtomicIIncrement && opCode != spv::OpAtomicIDecrement) {
 | 
				
			||||||
 | 
					        spvAtomicOperands.push_back(valueId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return resultId;
 | 
					    if (opCode == spv::OpAtomicStore) {
 | 
				
			||||||
 | 
					        builder.createNoResultOp(opCode, spvAtomicOperands);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // GLSL and HLSL atomic-counter decrement return post-decrement value,
 | 
				
			||||||
 | 
					        // while SPIR-V returns pre-decrement value. Translate between these semantics.
 | 
				
			||||||
 | 
					        if (op == glslang::EOpAtomicCounterDecrement)
 | 
				
			||||||
 | 
					            resultId = builder.createBinOp(spv::OpISub, typeId, resultId, builder.makeIntConstant(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return resultId;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create group invocation operations.
 | 
					// Create group invocation operations.
 | 
				
			||||||
@ -6282,7 +6548,41 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
 | 
				
			|||||||
        libCall = spv::InterpolateAtVertexAMD;
 | 
					        libCall = spv::InterpolateAtVertexAMD;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    case glslang::EOpBarrier:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // This is for the extended controlBarrier function, with four operands.
 | 
				
			||||||
 | 
					            // The unextended barrier() goes through createNoArgOperation.
 | 
				
			||||||
 | 
					            assert(operands.size() == 4);
 | 
				
			||||||
 | 
					            unsigned int executionScope = builder.getConstantScalar(operands[0]);
 | 
				
			||||||
 | 
					            unsigned int memoryScope = builder.getConstantScalar(operands[1]);
 | 
				
			||||||
 | 
					            unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]);
 | 
				
			||||||
 | 
					            builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
 | 
				
			||||||
 | 
					            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
 | 
				
			||||||
 | 
					                builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) {
 | 
				
			||||||
 | 
					                builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case glslang::EOpMemoryBarrier:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // This is for the extended memoryBarrier function, with three operands.
 | 
				
			||||||
 | 
					            // The unextended memoryBarrier() goes through createNoArgOperation.
 | 
				
			||||||
 | 
					            assert(operands.size() == 3);
 | 
				
			||||||
 | 
					            unsigned int memoryScope = builder.getConstantScalar(operands[0]);
 | 
				
			||||||
 | 
					            unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]);
 | 
				
			||||||
 | 
					            builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
 | 
				
			||||||
 | 
					            if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
 | 
				
			||||||
 | 
					                builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) {
 | 
				
			||||||
 | 
					                builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -6351,7 +6651,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
 | 
				
			|||||||
// Intrinsics with no arguments (or no return value, and no precision).
 | 
					// Intrinsics with no arguments (or no return value, and no precision).
 | 
				
			||||||
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
 | 
					spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // TODO: get the barrier operands correct
 | 
					    // GLSL memory barriers use queuefamily scope in new model, device scope in old model
 | 
				
			||||||
 | 
					    spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (op) {
 | 
					    switch (op) {
 | 
				
			||||||
    case glslang::EOpEmitVertex:
 | 
					    case glslang::EOpEmitVertex:
 | 
				
			||||||
@ -6362,11 +6663,14 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
 | 
				
			|||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpBarrier:
 | 
					    case glslang::EOpBarrier:
 | 
				
			||||||
        if (glslangIntermediate->getStage() == EShLangTessControl) {
 | 
					        if (glslangIntermediate->getStage() == EShLangTessControl) {
 | 
				
			||||||
            builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone);
 | 
					            if (glslangIntermediate->usingVulkanMemoryModel()) {
 | 
				
			||||||
            // TODO: prefer the following, when available:
 | 
					                builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
 | 
				
			||||||
            // builder.createControlBarrier(spv::ScopePatch, spv::ScopePatch,
 | 
					                                             spv::MemorySemanticsOutputMemoryKHRMask |
 | 
				
			||||||
            //                                 spv::MemorySemanticsPatchMask |
 | 
					                                             spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
            //                                 spv::MemorySemanticsAcquireReleaseMask);
 | 
					                builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
 | 
					            builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
 | 
				
			||||||
                                            spv::MemorySemanticsWorkgroupMemoryMask |
 | 
					                                            spv::MemorySemanticsWorkgroupMemoryMask |
 | 
				
			||||||
@ -6374,24 +6678,24 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpMemoryBarrier:
 | 
					    case glslang::EOpMemoryBarrier:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory |
 | 
					        builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory |
 | 
				
			||||||
                                                      spv::MemorySemanticsAcquireReleaseMask);
 | 
					                                                        spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpMemoryBarrierAtomicCounter:
 | 
					    case glslang::EOpMemoryBarrierAtomicCounter:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask |
 | 
					        builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask |
 | 
				
			||||||
                                                      spv::MemorySemanticsAcquireReleaseMask);
 | 
					                                                        spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpMemoryBarrierBuffer:
 | 
					    case glslang::EOpMemoryBarrierBuffer:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask |
 | 
					        builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask |
 | 
				
			||||||
                                                      spv::MemorySemanticsAcquireReleaseMask);
 | 
					                                                        spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpMemoryBarrierImage:
 | 
					    case glslang::EOpMemoryBarrierImage:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask |
 | 
					        builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask |
 | 
				
			||||||
                                                      spv::MemorySemanticsAcquireReleaseMask);
 | 
					                                                        spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpMemoryBarrierShared:
 | 
					    case glslang::EOpMemoryBarrierShared:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask |
 | 
					        builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask |
 | 
				
			||||||
                                                      spv::MemorySemanticsAcquireReleaseMask);
 | 
					                                                        spv::MemorySemanticsAcquireReleaseMask);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    case glslang::EOpGroupMemoryBarrier:
 | 
					    case glslang::EOpGroupMemoryBarrier:
 | 
				
			||||||
        builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory |
 | 
					        builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory |
 | 
				
			||||||
@ -6520,7 +6824,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (symbol->getType().isImage()) {
 | 
					    if (symbol->getType().isImage()) {
 | 
				
			||||||
        std::vector<spv::Decoration> memory;
 | 
					        std::vector<spv::Decoration> memory;
 | 
				
			||||||
        TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
 | 
					        TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
 | 
				
			||||||
        for (unsigned int i = 0; i < memory.size(); ++i)
 | 
					        for (unsigned int i = 0; i < memory.size(); ++i)
 | 
				
			||||||
            builder.addDecoration(id, memory[i]);
 | 
					            builder.addDecoration(id, memory[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1216,19 +1216,35 @@ Id Builder::createUndefined(Id type)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Comments in header
 | 
					// Comments in header
 | 
				
			||||||
void Builder::createStore(Id rValue, Id lValue)
 | 
					void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Instruction* store = new Instruction(OpStore);
 | 
					    Instruction* store = new Instruction(OpStore);
 | 
				
			||||||
    store->addIdOperand(lValue);
 | 
					    store->addIdOperand(lValue);
 | 
				
			||||||
    store->addIdOperand(rValue);
 | 
					    store->addIdOperand(rValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (memoryAccess != MemoryAccessMaskNone) {
 | 
				
			||||||
 | 
					        store->addImmediateOperand(memoryAccess);
 | 
				
			||||||
 | 
					        if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
 | 
				
			||||||
 | 
					            store->addIdOperand(makeUintConstant(scope));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
 | 
					    buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Comments in header
 | 
					// Comments in header
 | 
				
			||||||
Id Builder::createLoad(Id lValue)
 | 
					Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
 | 
					    Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
 | 
				
			||||||
    load->addIdOperand(lValue);
 | 
					    load->addIdOperand(lValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (memoryAccess != MemoryAccessMaskNone) {
 | 
				
			||||||
 | 
					        load->addImmediateOperand(memoryAccess);
 | 
				
			||||||
 | 
					        if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
 | 
				
			||||||
 | 
					            load->addIdOperand(makeUintConstant(scope));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
 | 
					    buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return load->getResultId();
 | 
					    return load->getResultId();
 | 
				
			||||||
@ -1361,6 +1377,16 @@ void Builder::createNoResultOp(Op opCode, Id operand)
 | 
				
			|||||||
    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 | 
					    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An opcode that has multiple operands, no result id, and no type
 | 
				
			||||||
 | 
					void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Instruction* op = new Instruction(opCode);
 | 
				
			||||||
 | 
					    for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
 | 
				
			||||||
 | 
					        op->addIdOperand(*it);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// An opcode that has multiple operands, no result id, and no type
 | 
					// An opcode that has multiple operands, no result id, and no type
 | 
				
			||||||
void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
 | 
					void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1679,6 +1705,12 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
 | 
				
			|||||||
        mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
 | 
					        mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
 | 
				
			||||||
        texArgs[numArgs++] = parameters.lodClamp;
 | 
					        texArgs[numArgs++] = parameters.lodClamp;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (parameters.nonprivate) {
 | 
				
			||||||
 | 
					        mask = mask | ImageOperandsNonPrivateTexelKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (parameters.volatil) {
 | 
				
			||||||
 | 
					        mask = mask | ImageOperandsVolatileTexelKHRMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (mask == ImageOperandsMaskNone)
 | 
					    if (mask == ImageOperandsMaskNone)
 | 
				
			||||||
        --numArgs;  // undo speculative reservation for the mask argument
 | 
					        --numArgs;  // undo speculative reservation for the mask argument
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
@ -2352,6 +2384,7 @@ void Builder::clearAccessChain()
 | 
				
			|||||||
    accessChain.component = NoResult;
 | 
					    accessChain.component = NoResult;
 | 
				
			||||||
    accessChain.preSwizzleBaseType = NoType;
 | 
					    accessChain.preSwizzleBaseType = NoType;
 | 
				
			||||||
    accessChain.isRValue = false;
 | 
					    accessChain.isRValue = false;
 | 
				
			||||||
 | 
					    accessChain.coherentFlags.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Comments in header
 | 
					// Comments in header
 | 
				
			||||||
@ -2378,7 +2411,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Comments in header
 | 
					// Comments in header
 | 
				
			||||||
void Builder::accessChainStore(Id rvalue)
 | 
					void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(accessChain.isRValue == false);
 | 
					    assert(accessChain.isRValue == false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2396,11 +2429,11 @@ void Builder::accessChainStore(Id rvalue)
 | 
				
			|||||||
        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
 | 
					        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    createStore(source, base);
 | 
					    createStore(source, base, memoryAccess, scope);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Comments in header
 | 
					// Comments in header
 | 
				
			||||||
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType)
 | 
					Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Id id;
 | 
					    Id id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2444,7 +2477,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        transferAccessChainSwizzle(true);
 | 
					        transferAccessChainSwizzle(true);
 | 
				
			||||||
        // load through the access chain
 | 
					        // load through the access chain
 | 
				
			||||||
        id = createLoad(collapseAccessChain());
 | 
					        id = createLoad(collapseAccessChain(), memoryAccess, scope);
 | 
				
			||||||
        setPrecision(id, precision);
 | 
					        setPrecision(id, precision);
 | 
				
			||||||
        addDecoration(id, nonUniform);
 | 
					        addDecoration(id, nonUniform);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -274,10 +274,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);
 | 
					    void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Load from an Id and return it
 | 
					    // Load from an Id and return it
 | 
				
			||||||
    Id createLoad(Id lValue);
 | 
					    Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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);
 | 
				
			||||||
@ -296,6 +296,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void createNoResultOp(Op);
 | 
					    void createNoResultOp(Op);
 | 
				
			||||||
    void createNoResultOp(Op, Id operand);
 | 
					    void createNoResultOp(Op, Id operand);
 | 
				
			||||||
 | 
					    void createNoResultOp(Op, const std::vector<Id>& operands);
 | 
				
			||||||
    void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
 | 
					    void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
 | 
				
			||||||
    void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
 | 
					    void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
 | 
				
			||||||
    void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
 | 
					    void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
 | 
				
			||||||
@ -365,6 +366,8 @@ public:
 | 
				
			|||||||
        Id component;
 | 
					        Id component;
 | 
				
			||||||
        Id texelOut;
 | 
					        Id texelOut;
 | 
				
			||||||
        Id lodClamp;
 | 
					        Id lodClamp;
 | 
				
			||||||
 | 
					        bool nonprivate;
 | 
				
			||||||
 | 
					        bool volatil;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Select the correct texture operation based on all inputs, and emit the correct instruction
 | 
					    // Select the correct texture operation based on all inputs, and emit the correct instruction
 | 
				
			||||||
@ -504,6 +507,43 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Accumulate whether anything in the chain of structures has coherent decorations.
 | 
				
			||||||
 | 
					        struct CoherentFlags {
 | 
				
			||||||
 | 
					            unsigned coherent : 1;
 | 
				
			||||||
 | 
					            unsigned devicecoherent : 1;
 | 
				
			||||||
 | 
					            unsigned queuefamilycoherent : 1;
 | 
				
			||||||
 | 
					            unsigned workgroupcoherent : 1;
 | 
				
			||||||
 | 
					            unsigned subgroupcoherent : 1;
 | 
				
			||||||
 | 
					            unsigned nonprivate : 1;
 | 
				
			||||||
 | 
					            unsigned volatil : 1;
 | 
				
			||||||
 | 
					            unsigned isImage : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void clear() {
 | 
				
			||||||
 | 
					                coherent = 0;
 | 
				
			||||||
 | 
					                devicecoherent = 0;
 | 
				
			||||||
 | 
					                queuefamilycoherent = 0;
 | 
				
			||||||
 | 
					                workgroupcoherent = 0;
 | 
				
			||||||
 | 
					                subgroupcoherent = 0;
 | 
				
			||||||
 | 
					                nonprivate = 0;
 | 
				
			||||||
 | 
					                volatil = 0;
 | 
				
			||||||
 | 
					                isImage = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CoherentFlags() { clear(); }
 | 
				
			||||||
 | 
					            CoherentFlags operator |=(const CoherentFlags &other) {
 | 
				
			||||||
 | 
					                coherent |= other.coherent;
 | 
				
			||||||
 | 
					                devicecoherent |= other.devicecoherent;
 | 
				
			||||||
 | 
					                queuefamilycoherent |= other.queuefamilycoherent;
 | 
				
			||||||
 | 
					                workgroupcoherent |= other.workgroupcoherent;
 | 
				
			||||||
 | 
					                subgroupcoherent |= other.subgroupcoherent;
 | 
				
			||||||
 | 
					                nonprivate |= other.nonprivate;
 | 
				
			||||||
 | 
					                volatil |= other.volatil;
 | 
				
			||||||
 | 
					                isImage |= other.isImage;
 | 
				
			||||||
 | 
					                return *this;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        CoherentFlags coherentFlags;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
@ -533,9 +573,10 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // push offset onto the end of the chain
 | 
					    // push offset onto the end of the chain
 | 
				
			||||||
    void accessChainPush(Id offset)
 | 
					    void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        accessChain.indexChain.push_back(offset);
 | 
					        accessChain.indexChain.push_back(offset);
 | 
				
			||||||
 | 
					        accessChain.coherentFlags |= coherentFlags;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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
 | 
				
			||||||
@ -553,10 +594,10 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // use accessChain and swizzle to store value
 | 
					    // use accessChain and swizzle to store value
 | 
				
			||||||
    void accessChainStore(Id rvalue);
 | 
					    void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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);
 | 
					    Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // get the direct pointer for an l-value
 | 
					    // get the direct pointer for an l-value
 | 
				
			||||||
    Id accessChainGetLValue();
 | 
					    Id accessChainGetLValue();
 | 
				
			||||||
 | 
				
			|||||||
@ -535,6 +535,11 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
 | 
				
			|||||||
        case OperandLiteralString:
 | 
					        case OperandLiteralString:
 | 
				
			||||||
            numOperands -= disassembleString();
 | 
					            numOperands -= disassembleString();
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case OperandMemoryAccess:
 | 
				
			||||||
 | 
					            outputMask(OperandMemoryAccess, stream[word++]);
 | 
				
			||||||
 | 
					            --numOperands;
 | 
				
			||||||
 | 
					            disassembleIds(numOperands);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            assert(operandClass >= OperandSource && operandClass < OperandOpcode);
 | 
					            assert(operandClass >= OperandSource && operandClass < OperandOpcode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -117,9 +117,10 @@ const char* AddressingString(int addr)
 | 
				
			|||||||
const char* MemoryString(int mem)
 | 
					const char* MemoryString(int mem)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (mem) {
 | 
					    switch (mem) {
 | 
				
			||||||
    case 0:  return "Simple";
 | 
					    case MemoryModelSimple:     return "Simple";
 | 
				
			||||||
    case 1:  return "GLSL450";
 | 
					    case MemoryModelGLSL450:    return "GLSL450";
 | 
				
			||||||
    case 2:  return "OpenCL";
 | 
					    case MemoryModelOpenCL:     return "OpenCL";
 | 
				
			||||||
 | 
					    case MemoryModelVulkanKHR:  return "VulkanKHR";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default: return "Bad";
 | 
					    default: return "Bad";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -499,19 +500,23 @@ const char* ImageChannelDataTypeString(int type)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const int ImageOperandsCeiling = 8;
 | 
					const int ImageOperandsCeiling = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* ImageOperandsString(int format)
 | 
					const char* ImageOperandsString(int format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (format) {
 | 
					    switch (format) {
 | 
				
			||||||
    case 0: return "Bias";
 | 
					    case ImageOperandsBiasShift:                    return "Bias";
 | 
				
			||||||
    case 1: return "Lod";
 | 
					    case ImageOperandsLodShift:                     return "Lod";
 | 
				
			||||||
    case 2: return "Grad";
 | 
					    case ImageOperandsGradShift:                    return "Grad";
 | 
				
			||||||
    case 3: return "ConstOffset";
 | 
					    case ImageOperandsConstOffsetShift:             return "ConstOffset";
 | 
				
			||||||
    case 4: return "Offset";
 | 
					    case ImageOperandsOffsetShift:                  return "Offset";
 | 
				
			||||||
    case 5: return "ConstOffsets";
 | 
					    case ImageOperandsConstOffsetsShift:            return "ConstOffsets";
 | 
				
			||||||
    case 6: return "Sample";
 | 
					    case ImageOperandsSampleShift:                  return "Sample";
 | 
				
			||||||
    case 7: return "MinLod";
 | 
					    case ImageOperandsMinLodShift:                  return "MinLod";
 | 
				
			||||||
 | 
					    case ImageOperandsMakeTexelAvailableKHRShift:   return "MakeTexelAvailableKHR";
 | 
				
			||||||
 | 
					    case ImageOperandsMakeTexelVisibleKHRShift:     return "MakeTexelVisibleKHR";
 | 
				
			||||||
 | 
					    case ImageOperandsNonPrivateTexelKHRShift:      return "NonPrivateTexelKHR";
 | 
				
			||||||
 | 
					    case ImageOperandsVolatileTexelKHRShift:        return "VolatileTexelKHR";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case ImageOperandsCeiling:
 | 
					    case ImageOperandsCeiling:
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
@ -645,12 +650,17 @@ const char* MemorySemanticsString(int mem)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const int MemoryAccessCeiling = 6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* MemoryAccessString(int mem)
 | 
					const char* MemoryAccessString(int mem)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (mem) {
 | 
					    switch (mem) {
 | 
				
			||||||
    case 0:  return "Volatile";
 | 
					    case MemoryAccessVolatileShift:                 return "Volatile";
 | 
				
			||||||
    case 1:  return "Aligned";
 | 
					    case MemoryAccessAlignedShift:                  return "Aligned";
 | 
				
			||||||
    case 2:  return "Nontemporal";
 | 
					    case MemoryAccessNontemporalShift:              return "Nontemporal";
 | 
				
			||||||
 | 
					    case MemoryAccessMakePointerAvailableKHRShift:  return "MakePointerAvailableKHR";
 | 
				
			||||||
 | 
					    case MemoryAccessMakePointerVisibleKHRShift:    return "MakePointerVisibleKHR";
 | 
				
			||||||
 | 
					    case MemoryAccessNonPrivatePointerKHRShift:     return "NonPrivatePointerKHR";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default: return "Bad";
 | 
					    default: return "Bad";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -833,6 +843,9 @@ const char* CapabilityString(int info)
 | 
				
			|||||||
    case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
 | 
					    case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
 | 
				
			||||||
    case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
 | 
					    case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case CapabilityVulkanMemoryModelKHR:                return "CapabilityVulkanMemoryModelKHR";
 | 
				
			||||||
 | 
					    case CapabilityVulkanMemoryModelDeviceScopeKHR:     return "CapabilityVulkanMemoryModelDeviceScopeKHR";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default: return "Bad";
 | 
					    default: return "Bad";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1245,6 +1258,7 @@ EnumParameters DecorationParams[DecorationCeiling];
 | 
				
			|||||||
EnumParameters LoopControlParams[FunctionControlCeiling];
 | 
					EnumParameters LoopControlParams[FunctionControlCeiling];
 | 
				
			||||||
EnumParameters SelectionControlParams[SelectControlCeiling];
 | 
					EnumParameters SelectionControlParams[SelectControlCeiling];
 | 
				
			||||||
EnumParameters FunctionControlParams[FunctionControlCeiling];
 | 
					EnumParameters FunctionControlParams[FunctionControlCeiling];
 | 
				
			||||||
 | 
					EnumParameters MemoryAccessParams[MemoryAccessCeiling];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set up all the parameterizing descriptions of the opcodes, operands, etc.
 | 
					// Set up all the parameterizing descriptions of the opcodes, operands, etc.
 | 
				
			||||||
void Parameterize()
 | 
					void Parameterize()
 | 
				
			||||||
@ -1400,7 +1414,7 @@ void Parameterize()
 | 
				
			|||||||
    OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
 | 
					    OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
 | 
				
			||||||
    OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
 | 
					    OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
 | 
				
			||||||
    OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
 | 
					    OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
 | 
				
			||||||
    OperandClassParams[OperandMemoryAccess].set(0, MemoryAccessString, nullptr, true);
 | 
					    OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true);
 | 
				
			||||||
    OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
 | 
					    OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
 | 
				
			||||||
    OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
 | 
					    OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
 | 
				
			||||||
    OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
 | 
					    OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
 | 
				
			||||||
@ -1522,10 +1536,14 @@ void Parameterize()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
 | 
					    InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
 | 
				
			||||||
    InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
 | 
					    InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
 | 
				
			||||||
 | 
					    InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true);
 | 
				
			||||||
 | 
					    InstructionDesc[OpLoad].operands.push(OperandId, "", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
 | 
					    InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
 | 
				
			||||||
    InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
 | 
					    InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
 | 
				
			||||||
    InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
 | 
					    InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
 | 
				
			||||||
 | 
					    InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true);
 | 
				
			||||||
 | 
					    InstructionDesc[OpStore].operands.push(OperandId, "", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
 | 
					    InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -87,6 +87,7 @@ enum MemoryModel {
 | 
				
			|||||||
    MemoryModelSimple = 0,
 | 
					    MemoryModelSimple = 0,
 | 
				
			||||||
    MemoryModelGLSL450 = 1,
 | 
					    MemoryModelGLSL450 = 1,
 | 
				
			||||||
    MemoryModelOpenCL = 2,
 | 
					    MemoryModelOpenCL = 2,
 | 
				
			||||||
 | 
					    MemoryModelVulkanKHR = 3,
 | 
				
			||||||
    MemoryModelMax = 0x7fffffff,
 | 
					    MemoryModelMax = 0x7fffffff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -275,6 +276,10 @@ enum ImageOperandsShift {
 | 
				
			|||||||
    ImageOperandsConstOffsetsShift = 5,
 | 
					    ImageOperandsConstOffsetsShift = 5,
 | 
				
			||||||
    ImageOperandsSampleShift = 6,
 | 
					    ImageOperandsSampleShift = 6,
 | 
				
			||||||
    ImageOperandsMinLodShift = 7,
 | 
					    ImageOperandsMinLodShift = 7,
 | 
				
			||||||
 | 
					    ImageOperandsMakeTexelAvailableKHRShift = 8,
 | 
				
			||||||
 | 
					    ImageOperandsMakeTexelVisibleKHRShift = 9,
 | 
				
			||||||
 | 
					    ImageOperandsNonPrivateTexelKHRShift = 10,
 | 
				
			||||||
 | 
					    ImageOperandsVolatileTexelKHRShift = 11,
 | 
				
			||||||
    ImageOperandsMax = 0x7fffffff,
 | 
					    ImageOperandsMax = 0x7fffffff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -288,6 +293,10 @@ enum ImageOperandsMask {
 | 
				
			|||||||
    ImageOperandsConstOffsetsMask = 0x00000020,
 | 
					    ImageOperandsConstOffsetsMask = 0x00000020,
 | 
				
			||||||
    ImageOperandsSampleMask = 0x00000040,
 | 
					    ImageOperandsSampleMask = 0x00000040,
 | 
				
			||||||
    ImageOperandsMinLodMask = 0x00000080,
 | 
					    ImageOperandsMinLodMask = 0x00000080,
 | 
				
			||||||
 | 
					    ImageOperandsMakeTexelAvailableKHRMask = 0x00000100,
 | 
				
			||||||
 | 
					    ImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
 | 
				
			||||||
 | 
					    ImageOperandsNonPrivateTexelKHRMask = 0x00000400,
 | 
				
			||||||
 | 
					    ImageOperandsVolatileTexelKHRMask = 0x00000800,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FPFastMathModeShift {
 | 
					enum FPFastMathModeShift {
 | 
				
			||||||
@ -528,6 +537,9 @@ enum MemorySemanticsShift {
 | 
				
			|||||||
    MemorySemanticsCrossWorkgroupMemoryShift = 9,
 | 
					    MemorySemanticsCrossWorkgroupMemoryShift = 9,
 | 
				
			||||||
    MemorySemanticsAtomicCounterMemoryShift = 10,
 | 
					    MemorySemanticsAtomicCounterMemoryShift = 10,
 | 
				
			||||||
    MemorySemanticsImageMemoryShift = 11,
 | 
					    MemorySemanticsImageMemoryShift = 11,
 | 
				
			||||||
 | 
					    MemorySemanticsOutputMemoryKHRShift = 12,
 | 
				
			||||||
 | 
					    MemorySemanticsMakeAvailableKHRShift = 13,
 | 
				
			||||||
 | 
					    MemorySemanticsMakeVisibleKHRShift = 14,
 | 
				
			||||||
    MemorySemanticsMax = 0x7fffffff,
 | 
					    MemorySemanticsMax = 0x7fffffff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -543,12 +555,18 @@ enum MemorySemanticsMask {
 | 
				
			|||||||
    MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
 | 
					    MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
 | 
				
			||||||
    MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
 | 
					    MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
 | 
				
			||||||
    MemorySemanticsImageMemoryMask = 0x00000800,
 | 
					    MemorySemanticsImageMemoryMask = 0x00000800,
 | 
				
			||||||
 | 
					    MemorySemanticsOutputMemoryKHRMask = 0x00001000,
 | 
				
			||||||
 | 
					    MemorySemanticsMakeAvailableKHRMask = 0x00002000,
 | 
				
			||||||
 | 
					    MemorySemanticsMakeVisibleKHRMask = 0x00004000,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum MemoryAccessShift {
 | 
					enum MemoryAccessShift {
 | 
				
			||||||
    MemoryAccessVolatileShift = 0,
 | 
					    MemoryAccessVolatileShift = 0,
 | 
				
			||||||
    MemoryAccessAlignedShift = 1,
 | 
					    MemoryAccessAlignedShift = 1,
 | 
				
			||||||
    MemoryAccessNontemporalShift = 2,
 | 
					    MemoryAccessNontemporalShift = 2,
 | 
				
			||||||
 | 
					    MemoryAccessMakePointerAvailableKHRShift = 3,
 | 
				
			||||||
 | 
					    MemoryAccessMakePointerVisibleKHRShift = 4,
 | 
				
			||||||
 | 
					    MemoryAccessNonPrivatePointerKHRShift = 5,
 | 
				
			||||||
    MemoryAccessMax = 0x7fffffff,
 | 
					    MemoryAccessMax = 0x7fffffff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -557,6 +575,9 @@ enum MemoryAccessMask {
 | 
				
			|||||||
    MemoryAccessVolatileMask = 0x00000001,
 | 
					    MemoryAccessVolatileMask = 0x00000001,
 | 
				
			||||||
    MemoryAccessAlignedMask = 0x00000002,
 | 
					    MemoryAccessAlignedMask = 0x00000002,
 | 
				
			||||||
    MemoryAccessNontemporalMask = 0x00000004,
 | 
					    MemoryAccessNontemporalMask = 0x00000004,
 | 
				
			||||||
 | 
					    MemoryAccessMakePointerAvailableKHRMask = 0x00000008,
 | 
				
			||||||
 | 
					    MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
 | 
				
			||||||
 | 
					    MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum Scope {
 | 
					enum Scope {
 | 
				
			||||||
@ -565,6 +586,7 @@ enum Scope {
 | 
				
			|||||||
    ScopeWorkgroup = 2,
 | 
					    ScopeWorkgroup = 2,
 | 
				
			||||||
    ScopeSubgroup = 3,
 | 
					    ScopeSubgroup = 3,
 | 
				
			||||||
    ScopeInvocation = 4,
 | 
					    ScopeInvocation = 4,
 | 
				
			||||||
 | 
					    ScopeQueueFamilyKHR = 5,
 | 
				
			||||||
    ScopeMax = 0x7fffffff,
 | 
					    ScopeMax = 0x7fffffff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -708,6 +730,8 @@ enum Capability {
 | 
				
			|||||||
    CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
 | 
					    CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
 | 
				
			||||||
    CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
 | 
					    CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
 | 
				
			||||||
    CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
 | 
					    CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
 | 
				
			||||||
 | 
					    CapabilityVulkanMemoryModelKHR = 5345,
 | 
				
			||||||
 | 
					    CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
 | 
				
			||||||
    CapabilitySubgroupShuffleINTEL = 5568,
 | 
					    CapabilitySubgroupShuffleINTEL = 5568,
 | 
				
			||||||
    CapabilitySubgroupBufferBlockIOINTEL = 5569,
 | 
					    CapabilitySubgroupBufferBlockIOINTEL = 5569,
 | 
				
			||||||
    CapabilitySubgroupImageBlockIOINTEL = 5570,
 | 
					    CapabilitySubgroupImageBlockIOINTEL = 5570,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										243
									
								
								Test/baseResults/spv.memoryScopeSemantics.comp.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								Test/baseResults/spv.memoryScopeSemantics.comp.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,243 @@
 | 
				
			|||||||
 | 
					spv.memoryScopeSemantics.comp
 | 
				
			||||||
 | 
					error: SPIRV-Tools Validation Errors
 | 
				
			||||||
 | 
					error: Capability Int64Atomics is not allowed by Vulkan 1.0 specification (or requires extension)
 | 
				
			||||||
 | 
					  OpCapability Int64Atomics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Module Version 10000
 | 
				
			||||||
 | 
					// Generated by (magic number): 80007
 | 
				
			||||||
 | 
					// Id's are bound by 142
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                              Capability Shader
 | 
				
			||||||
 | 
					                              Capability Int64
 | 
				
			||||||
 | 
					                              Capability Int64Atomics
 | 
				
			||||||
 | 
					                              Capability CapabilityVulkanMemoryModelKHR
 | 
				
			||||||
 | 
					                              Capability CapabilityVulkanMemoryModelDeviceScopeKHR
 | 
				
			||||||
 | 
					                              Extension  "SPV_KHR_vulkan_memory_model"
 | 
				
			||||||
 | 
					               1:             ExtInstImport  "GLSL.std.450"
 | 
				
			||||||
 | 
					                              MemoryModel Logical VulkanKHR
 | 
				
			||||||
 | 
					                              EntryPoint GLCompute 4  "main"
 | 
				
			||||||
 | 
					                              ExecutionMode 4 LocalSize 1 1 1
 | 
				
			||||||
 | 
					                              Source GLSL 450
 | 
				
			||||||
 | 
					                              SourceExtension  "GL_ARB_gpu_shader_int64"
 | 
				
			||||||
 | 
					                              SourceExtension  "GL_KHR_memory_scope_semantics"
 | 
				
			||||||
 | 
					                              Name 4  "main"
 | 
				
			||||||
 | 
					                              Name 8  "origi"
 | 
				
			||||||
 | 
					                              Name 10  "atomi"
 | 
				
			||||||
 | 
					                              Name 21  "origu"
 | 
				
			||||||
 | 
					                              Name 23  "atomu"
 | 
				
			||||||
 | 
					                              Name 24  "value"
 | 
				
			||||||
 | 
					                              Name 36  "imagei"
 | 
				
			||||||
 | 
					                              Name 45  "imageu"
 | 
				
			||||||
 | 
					                              Name 65  "BufferU"
 | 
				
			||||||
 | 
					                              MemberName 65(BufferU) 0  "x"
 | 
				
			||||||
 | 
					                              Name 67  "bufferu"
 | 
				
			||||||
 | 
					                              Name 72  "y"
 | 
				
			||||||
 | 
					                              Name 77  "BufferI"
 | 
				
			||||||
 | 
					                              MemberName 77(BufferI) 0  "x"
 | 
				
			||||||
 | 
					                              Name 79  "bufferi"
 | 
				
			||||||
 | 
					                              Name 83  "A"
 | 
				
			||||||
 | 
					                              MemberName 83(A) 0  "x"
 | 
				
			||||||
 | 
					                              Name 84  "BufferJ"
 | 
				
			||||||
 | 
					                              MemberName 84(BufferJ) 0  "a"
 | 
				
			||||||
 | 
					                              Name 87  "bufferj"
 | 
				
			||||||
 | 
					                              Name 98  "BufferK"
 | 
				
			||||||
 | 
					                              MemberName 98(BufferK) 0  "x"
 | 
				
			||||||
 | 
					                              Name 100  "bufferk"
 | 
				
			||||||
 | 
					                              Name 109  "imagej"
 | 
				
			||||||
 | 
					                              Name 121  "samp"
 | 
				
			||||||
 | 
					                              Name 132  "atomu64"
 | 
				
			||||||
 | 
					                              Name 137  "atomi64"
 | 
				
			||||||
 | 
					                              Decorate 36(imagei) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 36(imagei) Binding 1
 | 
				
			||||||
 | 
					                              Decorate 45(imageu) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 45(imageu) Binding 0
 | 
				
			||||||
 | 
					                              MemberDecorate 65(BufferU) 0 Offset 0
 | 
				
			||||||
 | 
					                              Decorate 65(BufferU) BufferBlock
 | 
				
			||||||
 | 
					                              Decorate 67(bufferu) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 67(bufferu) Binding 2
 | 
				
			||||||
 | 
					                              MemberDecorate 77(BufferI) 0 Offset 0
 | 
				
			||||||
 | 
					                              Decorate 77(BufferI) BufferBlock
 | 
				
			||||||
 | 
					                              Decorate 79(bufferi) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 79(bufferi) Binding 3
 | 
				
			||||||
 | 
					                              Decorate 82 ArrayStride 4
 | 
				
			||||||
 | 
					                              MemberDecorate 83(A) 0 Offset 0
 | 
				
			||||||
 | 
					                              MemberDecorate 84(BufferJ) 0 Offset 0
 | 
				
			||||||
 | 
					                              Decorate 84(BufferJ) BufferBlock
 | 
				
			||||||
 | 
					                              Decorate 87(bufferj) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 87(bufferj) Binding 4
 | 
				
			||||||
 | 
					                              MemberDecorate 98(BufferK) 0 Offset 0
 | 
				
			||||||
 | 
					                              Decorate 98(BufferK) Block
 | 
				
			||||||
 | 
					                              Decorate 100(bufferk) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 100(bufferk) Binding 7
 | 
				
			||||||
 | 
					                              Decorate 109(imagej) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 109(imagej) Binding 5
 | 
				
			||||||
 | 
					                              Decorate 121(samp) DescriptorSet 0
 | 
				
			||||||
 | 
					                              Decorate 121(samp) Binding 6
 | 
				
			||||||
 | 
					               2:             TypeVoid
 | 
				
			||||||
 | 
					               3:             TypeFunction 2
 | 
				
			||||||
 | 
					               6:             TypeInt 32 1
 | 
				
			||||||
 | 
					               7:             TypePointer Function 6(int)
 | 
				
			||||||
 | 
					               9:             TypePointer Workgroup 6(int)
 | 
				
			||||||
 | 
					       10(atomi):      9(ptr) Variable Workgroup
 | 
				
			||||||
 | 
					              11:      6(int) Constant 3
 | 
				
			||||||
 | 
					              12:      6(int) Constant 1
 | 
				
			||||||
 | 
					              13:      6(int) Constant 320
 | 
				
			||||||
 | 
					              14:      6(int) Constant 4
 | 
				
			||||||
 | 
					              15:             TypeInt 32 0
 | 
				
			||||||
 | 
					              16:     15(int) Constant 5
 | 
				
			||||||
 | 
					              17:     15(int) Constant 0
 | 
				
			||||||
 | 
					              18:     15(int) Constant 324
 | 
				
			||||||
 | 
					              20:             TypePointer Function 15(int)
 | 
				
			||||||
 | 
					              22:             TypePointer Workgroup 15(int)
 | 
				
			||||||
 | 
					       23(atomu):     22(ptr) Variable Workgroup
 | 
				
			||||||
 | 
					       24(value):     22(ptr) Variable Workgroup
 | 
				
			||||||
 | 
					              26:     15(int) Constant 2
 | 
				
			||||||
 | 
					              28:      6(int) Constant 64
 | 
				
			||||||
 | 
					              29:      6(int) Constant 2
 | 
				
			||||||
 | 
					              30:     15(int) Constant 66
 | 
				
			||||||
 | 
					              33:     15(int) Constant 68
 | 
				
			||||||
 | 
					              34:             TypeImage 6(int) 2D nonsampled format:R32i
 | 
				
			||||||
 | 
					              35:             TypePointer UniformConstant 34
 | 
				
			||||||
 | 
					      36(imagei):     35(ptr) Variable UniformConstant
 | 
				
			||||||
 | 
					              37:             TypeVector 6(int) 2
 | 
				
			||||||
 | 
					              38:      6(int) Constant 0
 | 
				
			||||||
 | 
					              39:   37(ivec2) ConstantComposite 38 38
 | 
				
			||||||
 | 
					              40:             TypePointer Image 6(int)
 | 
				
			||||||
 | 
					              43:             TypeImage 15(int) 2D nonsampled format:R32ui
 | 
				
			||||||
 | 
					              44:             TypePointer UniformConstant 43
 | 
				
			||||||
 | 
					      45(imageu):     44(ptr) Variable UniformConstant
 | 
				
			||||||
 | 
					              46:     15(int) Constant 3
 | 
				
			||||||
 | 
					              47:             TypePointer Image 15(int)
 | 
				
			||||||
 | 
					              50:     15(int) Constant 4
 | 
				
			||||||
 | 
					              52:     15(int) Constant 7
 | 
				
			||||||
 | 
					              57:      6(int) Constant 7
 | 
				
			||||||
 | 
					              61:     15(int) Constant 10
 | 
				
			||||||
 | 
					              63:     15(int) Constant 322
 | 
				
			||||||
 | 
					     65(BufferU):             TypeStruct 15(int)
 | 
				
			||||||
 | 
					              66:             TypePointer Uniform 65(BufferU)
 | 
				
			||||||
 | 
					     67(bufferu):     66(ptr) Variable Uniform
 | 
				
			||||||
 | 
					              68:             TypePointer Uniform 15(int)
 | 
				
			||||||
 | 
					              70:     15(int) Constant 1
 | 
				
			||||||
 | 
					     77(BufferI):             TypeStruct 15(int)
 | 
				
			||||||
 | 
					              78:             TypePointer Uniform 77(BufferI)
 | 
				
			||||||
 | 
					     79(bufferi):     78(ptr) Variable Uniform
 | 
				
			||||||
 | 
					              82:             TypeArray 15(int) 26
 | 
				
			||||||
 | 
					           83(A):             TypeStruct 82
 | 
				
			||||||
 | 
					     84(BufferJ):             TypeStruct 83(A)
 | 
				
			||||||
 | 
					              85:             TypeArray 84(BufferJ) 26
 | 
				
			||||||
 | 
					              86:             TypePointer Uniform 85
 | 
				
			||||||
 | 
					     87(bufferj):     86(ptr) Variable Uniform
 | 
				
			||||||
 | 
					              94:             TypePointer Uniform 83(A)
 | 
				
			||||||
 | 
					     98(BufferK):             TypeStruct 15(int)
 | 
				
			||||||
 | 
					              99:             TypePointer Uniform 98(BufferK)
 | 
				
			||||||
 | 
					    100(bufferk):     99(ptr) Variable Uniform
 | 
				
			||||||
 | 
					             105:             TypeVector 6(int) 4
 | 
				
			||||||
 | 
					             107:             TypeArray 34 26
 | 
				
			||||||
 | 
					             108:             TypePointer UniformConstant 107
 | 
				
			||||||
 | 
					     109(imagej):    108(ptr) Variable UniformConstant
 | 
				
			||||||
 | 
					             115:  105(ivec4) ConstantComposite 38 38 38 38
 | 
				
			||||||
 | 
					             116:             TypeFloat 32
 | 
				
			||||||
 | 
					             117:             TypeImage 116(float) 2D sampled format:Unknown
 | 
				
			||||||
 | 
					             118:             TypeSampledImage 117
 | 
				
			||||||
 | 
					             119:             TypeArray 118 26
 | 
				
			||||||
 | 
					             120:             TypePointer UniformConstant 119
 | 
				
			||||||
 | 
					       121(samp):    120(ptr) Variable UniformConstant
 | 
				
			||||||
 | 
					             122:             TypePointer UniformConstant 118
 | 
				
			||||||
 | 
					             125:             TypeVector 116(float) 2
 | 
				
			||||||
 | 
					             126:  116(float) Constant 0
 | 
				
			||||||
 | 
					             127:  125(fvec2) ConstantComposite 126 126
 | 
				
			||||||
 | 
					             128:             TypeVector 116(float) 4
 | 
				
			||||||
 | 
					             130:             TypeInt 64 0
 | 
				
			||||||
 | 
					             131:             TypePointer Workgroup 130(int64_t)
 | 
				
			||||||
 | 
					    132(atomu64):    131(ptr) Variable Workgroup
 | 
				
			||||||
 | 
					             133:130(int64_t) Constant 7 0
 | 
				
			||||||
 | 
					             135:             TypeInt 64 1
 | 
				
			||||||
 | 
					             136:             TypePointer Workgroup 135(int64_t)
 | 
				
			||||||
 | 
					    137(atomi64):    136(ptr) Variable Workgroup
 | 
				
			||||||
 | 
					             138:135(int64_t) Constant 10 0
 | 
				
			||||||
 | 
					         4(main):           2 Function None 3
 | 
				
			||||||
 | 
					               5:             Label
 | 
				
			||||||
 | 
					        8(origi):      7(ptr) Variable Function
 | 
				
			||||||
 | 
					       21(origu):     20(ptr) Variable Function
 | 
				
			||||||
 | 
					           72(y):     20(ptr) Variable Function
 | 
				
			||||||
 | 
					              19:      6(int) AtomicIAdd 10(atomi) 12 18 11
 | 
				
			||||||
 | 
					                              Store 8(origi) 19
 | 
				
			||||||
 | 
					              25:     15(int) Load 24(value) MakePointerVisibleKHR 26
 | 
				
			||||||
 | 
					              27:     15(int) AtomicAnd 23(atomu) 16 17 25
 | 
				
			||||||
 | 
					                              Store 21(origu) 27
 | 
				
			||||||
 | 
					              31:      6(int) AtomicLoad 10(atomi) 12 30
 | 
				
			||||||
 | 
					                              Store 8(origi) 31
 | 
				
			||||||
 | 
					              32:     15(int) Load 24(value) MakePointerVisibleKHR 26
 | 
				
			||||||
 | 
					                              AtomicStore 23(atomu) 12 33 32
 | 
				
			||||||
 | 
					              41:     40(ptr) ImageTexelPointer 36(imagei) 39 17
 | 
				
			||||||
 | 
					              42:      6(int) AtomicLoad 41 12 30
 | 
				
			||||||
 | 
					                              Store 8(origi) 42
 | 
				
			||||||
 | 
					              48:     47(ptr) ImageTexelPointer 45(imageu) 39 17
 | 
				
			||||||
 | 
					              49:     15(int) AtomicIAdd 48 12 30 46
 | 
				
			||||||
 | 
					                              Store 21(origu) 49
 | 
				
			||||||
 | 
					              51:     47(ptr) ImageTexelPointer 45(imageu) 39 17
 | 
				
			||||||
 | 
					                              AtomicStore 51 12 33 50
 | 
				
			||||||
 | 
					              53:     15(int) AtomicOr 23(atomu) 12 17 52
 | 
				
			||||||
 | 
					                              Store 21(origu) 53
 | 
				
			||||||
 | 
					              54:     15(int) AtomicXor 23(atomu) 12 17 52
 | 
				
			||||||
 | 
					                              Store 21(origu) 54
 | 
				
			||||||
 | 
					              55:     15(int) Load 24(value) MakePointerVisibleKHR 26
 | 
				
			||||||
 | 
					              56:     15(int) AtomicUMin 23(atomu) 12 17 55
 | 
				
			||||||
 | 
					                              Store 21(origu) 56
 | 
				
			||||||
 | 
					              58:      6(int) AtomicSMax 10(atomi) 12 17 57
 | 
				
			||||||
 | 
					                              Store 8(origi) 58
 | 
				
			||||||
 | 
					              59:      6(int) Load 8(origi)
 | 
				
			||||||
 | 
					              60:      6(int) AtomicExchange 10(atomi) 12 17 59
 | 
				
			||||||
 | 
					                              Store 8(origi) 60
 | 
				
			||||||
 | 
					              62:     15(int) Load 24(value) MakePointerVisibleKHR 26
 | 
				
			||||||
 | 
					              64:     15(int) AtomicCompareExchange 23(atomu) 12 63 63 62 61
 | 
				
			||||||
 | 
					                              Store 21(origu) 64
 | 
				
			||||||
 | 
					              69:     68(ptr) AccessChain 67(bufferu) 38
 | 
				
			||||||
 | 
					              71:     15(int) AtomicIAdd 69 12 18 70
 | 
				
			||||||
 | 
					                              MemoryBarrier 26 18
 | 
				
			||||||
 | 
					                              ControlBarrier 26 26 63
 | 
				
			||||||
 | 
					                              ControlBarrier 26 26 17
 | 
				
			||||||
 | 
					              73:     68(ptr) AccessChain 67(bufferu) 38
 | 
				
			||||||
 | 
					              74:     15(int) Load 73 MakePointerVisibleKHR NonPrivatePointerKHR 26
 | 
				
			||||||
 | 
					                              Store 72(y) 74
 | 
				
			||||||
 | 
					              75:     15(int) Load 72(y)
 | 
				
			||||||
 | 
					              76:     68(ptr) AccessChain 67(bufferu) 38
 | 
				
			||||||
 | 
					                              Store 76 75 MakePointerAvailableKHR NonPrivatePointerKHR 26
 | 
				
			||||||
 | 
					              80:     68(ptr) AccessChain 79(bufferi) 38
 | 
				
			||||||
 | 
					              81:     15(int) Load 80 MakePointerVisibleKHR NonPrivatePointerKHR 16
 | 
				
			||||||
 | 
					                              Store 72(y) 81
 | 
				
			||||||
 | 
					              88:     68(ptr) AccessChain 87(bufferj) 38 38 38 12
 | 
				
			||||||
 | 
					              89:     15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
 | 
				
			||||||
 | 
					                              Store 72(y) 89
 | 
				
			||||||
 | 
					              90:     15(int) Load 72(y)
 | 
				
			||||||
 | 
					              91:     68(ptr) AccessChain 79(bufferi) 38
 | 
				
			||||||
 | 
					                              Store 91 90 MakePointerAvailableKHR NonPrivatePointerKHR 16
 | 
				
			||||||
 | 
					              92:     15(int) Load 72(y)
 | 
				
			||||||
 | 
					              93:     68(ptr) AccessChain 87(bufferj) 38 38 38 12
 | 
				
			||||||
 | 
					                              Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
 | 
				
			||||||
 | 
					              95:     94(ptr) AccessChain 87(bufferj) 12 38
 | 
				
			||||||
 | 
					              96:       83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
 | 
				
			||||||
 | 
					              97:     94(ptr) AccessChain 87(bufferj) 38 38
 | 
				
			||||||
 | 
					                              Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
 | 
				
			||||||
 | 
					             101:     68(ptr) AccessChain 100(bufferk) 38
 | 
				
			||||||
 | 
					             102:     15(int) Load 101 NonPrivatePointerKHR 
 | 
				
			||||||
 | 
					             103:     68(ptr) AccessChain 79(bufferi) 38
 | 
				
			||||||
 | 
					                              Store 103 102 MakePointerAvailableKHR NonPrivatePointerKHR 16
 | 
				
			||||||
 | 
					             104:          34 Load 36(imagei)
 | 
				
			||||||
 | 
					             106:  105(ivec4) ImageRead 104 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16
 | 
				
			||||||
 | 
					             110:     35(ptr) AccessChain 109(imagej) 38
 | 
				
			||||||
 | 
					             111:          34 Load 110
 | 
				
			||||||
 | 
					             112:  105(ivec4) ImageRead 111 39 NonPrivateTexelKHR 
 | 
				
			||||||
 | 
					             113:     35(ptr) AccessChain 109(imagej) 12
 | 
				
			||||||
 | 
					             114:          34 Load 113
 | 
				
			||||||
 | 
					                              ImageWrite 114 39 115 NonPrivateTexelKHR 
 | 
				
			||||||
 | 
					             123:    122(ptr) AccessChain 121(samp) 38
 | 
				
			||||||
 | 
					             124:         118 Load 123
 | 
				
			||||||
 | 
					             129:  128(fvec4) ImageSampleExplicitLod 124 127 Lod NonPrivateTexelKHR 126
 | 
				
			||||||
 | 
					             134:130(int64_t) AtomicUMax 132(atomu64) 12 17 133
 | 
				
			||||||
 | 
					                              Store 132(atomu64) 134 MakePointerAvailableKHR 26
 | 
				
			||||||
 | 
					             139:130(int64_t) Load 132(atomu64) MakePointerVisibleKHR 26
 | 
				
			||||||
 | 
					             140:135(int64_t) Bitcast 139
 | 
				
			||||||
 | 
					             141:135(int64_t) AtomicCompareExchange 137(atomi64) 12 63 63 140 138
 | 
				
			||||||
 | 
					                              Return
 | 
				
			||||||
 | 
					                              FunctionEnd
 | 
				
			||||||
							
								
								
									
										17
									
								
								Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					spv.memoryScopeSemantics_Error.comp
 | 
				
			||||||
 | 
					ERROR: 0:15: 'atomicStore' : gl_SemanticsAcquire must not be used with (image) atomic store 
 | 
				
			||||||
 | 
					ERROR: 0:16: 'imageAtomicLoad' : gl_SemanticsRelease must not be used with (image) atomic load 
 | 
				
			||||||
 | 
					ERROR: 0:17: 'atomicStore' : gl_SemanticsAcquireRelease must not be used with (image) atomic load/store 
 | 
				
			||||||
 | 
					ERROR: 0:18: 'atomicStore' : Invalid semantics value 
 | 
				
			||||||
 | 
					ERROR: 0:19: 'imageAtomicLoad' : Invalid storage class semantics value 
 | 
				
			||||||
 | 
					ERROR: 0:20: 'memoryBarrier' : Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 0:21: 'memoryBarrier' : Storage class semantics must not be zero 
 | 
				
			||||||
 | 
					ERROR: 0:22: 'memoryBarrier' : Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 0:23: 'atomicAdd' : Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 0:24: 'atomicCompSwap' : semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 0:25: 'memoryBarrier' : gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 0:26: 'memoryBarrier' : gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease 
 | 
				
			||||||
 | 
					ERROR: 12 compilation errors.  No code generated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPIR-V is not generated for failed compile or link
 | 
				
			||||||
@ -11,7 +11,7 @@ spv.specConstant.vert
 | 
				
			|||||||
                              Source GLSL 400
 | 
					                              Source GLSL 400
 | 
				
			||||||
                              Name 4  "main"
 | 
					                              Name 4  "main"
 | 
				
			||||||
                              Name 9  "arraySize"
 | 
					                              Name 9  "arraySize"
 | 
				
			||||||
                              Name 14  "foo(vf4[s2543];"
 | 
					                              Name 14  "foo(vf4[s2765];"
 | 
				
			||||||
                              Name 13  "p"
 | 
					                              Name 13  "p"
 | 
				
			||||||
                              Name 17  "builtin_spec_constant("
 | 
					                              Name 17  "builtin_spec_constant("
 | 
				
			||||||
                              Name 20  "color"
 | 
					                              Name 20  "color"
 | 
				
			||||||
@ -102,10 +102,10 @@ spv.specConstant.vert
 | 
				
			|||||||
                              Store 20(color) 46
 | 
					                              Store 20(color) 46
 | 
				
			||||||
              48:          10 Load 22(ucol)
 | 
					              48:          10 Load 22(ucol)
 | 
				
			||||||
                              Store 47(param) 48
 | 
					                              Store 47(param) 48
 | 
				
			||||||
              49:           2 FunctionCall 14(foo(vf4[s2543];) 47(param)
 | 
					              49:           2 FunctionCall 14(foo(vf4[s2765];) 47(param)
 | 
				
			||||||
                              Return
 | 
					                              Return
 | 
				
			||||||
                              FunctionEnd
 | 
					                              FunctionEnd
 | 
				
			||||||
14(foo(vf4[s2543];):           2 Function None 12
 | 
					14(foo(vf4[s2765];):           2 Function None 12
 | 
				
			||||||
           13(p):     11(ptr) FunctionParameter
 | 
					           13(p):     11(ptr) FunctionParameter
 | 
				
			||||||
              15:             Label
 | 
					              15:             Label
 | 
				
			||||||
              54:     24(ptr) AccessChain 53(dupUcol) 23
 | 
					              54:     24(ptr) AccessChain 53(dupUcol) 23
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								Test/spv.memoryScopeSemantics.comp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								Test/spv.memoryScopeSemantics.comp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					#version 450
 | 
				
			||||||
 | 
					#extension GL_KHR_memory_scope_semantics : require
 | 
				
			||||||
 | 
					#extension GL_ARB_gpu_shader_int64 : require
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma use_vulkan_memory_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					shared uint value;
 | 
				
			||||||
 | 
					shared int atomi;
 | 
				
			||||||
 | 
					shared uint atomu;
 | 
				
			||||||
 | 
					layout(binding = 0, r32ui) workgroupcoherent uniform uimage2D imageu;
 | 
				
			||||||
 | 
					layout(binding = 1, r32i) volatile coherent uniform iimage2D imagei;
 | 
				
			||||||
 | 
					layout(binding = 5, r32i) nonprivate uniform iimage2D imagej[2];
 | 
				
			||||||
 | 
					layout (binding = 2) buffer BufferU { workgroupcoherent uint x; } bufferu;
 | 
				
			||||||
 | 
					layout (binding = 3) coherent buffer BufferI { uint x; } bufferi;
 | 
				
			||||||
 | 
					struct A { uint x[2]; };
 | 
				
			||||||
 | 
					layout (binding = 4) volatile buffer BufferJ { subgroupcoherent A a; } bufferj[2];
 | 
				
			||||||
 | 
					layout (binding = 6) nonprivate uniform sampler2D samp[2];
 | 
				
			||||||
 | 
					layout (binding = 7) nonprivate uniform BufferK { uint x; } bufferk;
 | 
				
			||||||
 | 
					shared uint64_t atomu64;
 | 
				
			||||||
 | 
					shared int64_t atomi64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int origi = atomicAdd(atomi, 3, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    uint origu = atomicAnd(atomu, value);
 | 
				
			||||||
 | 
					    origi = atomicLoad(atomi, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    origu = imageAtomicAdd(imageu, ivec2(0,0), 3u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    imageAtomicStore(imageu, ivec2(0,0), 4u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    origu = atomicOr(atomu, 7u, gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    origu = atomicXor(atomu, 7u, gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    origu = atomicMin(atomu, value, gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    origi = atomicMax(atomi, 7, gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    origi = atomicExchange(atomi, origi, gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    atomicAdd(bufferu.x, 1, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint y;
 | 
				
			||||||
 | 
					    y = bufferu.x;
 | 
				
			||||||
 | 
					    bufferu.x = y;
 | 
				
			||||||
 | 
					    y = bufferi.x;
 | 
				
			||||||
 | 
					    y = bufferj[0].a.x[1];
 | 
				
			||||||
 | 
					    bufferi.x = y;
 | 
				
			||||||
 | 
					    bufferj[0].a.x[1] = y;
 | 
				
			||||||
 | 
					    bufferj[0].a = bufferj[1].a;
 | 
				
			||||||
 | 
					    bufferi.x = bufferk.x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    imageLoad(imagei, ivec2(0,0));
 | 
				
			||||||
 | 
					    imageLoad(imagej[0], ivec2(0,0));
 | 
				
			||||||
 | 
					    imageStore(imagej[1], ivec2(0,0), ivec4(0,0,0,0));
 | 
				
			||||||
 | 
					    texture(samp[0], vec2(0,0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    atomu64 = atomicMax(atomu64, uint64_t(7), gl_ScopeDevice, 0, 0);
 | 
				
			||||||
 | 
					    atomicCompSwap(atomi64, int64_t(10), int64_t(atomu64), gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								Test/spv.memoryScopeSemantics_Error.comp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Test/spv.memoryScopeSemantics_Error.comp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					#version 450
 | 
				
			||||||
 | 
					#extension GL_KHR_memory_scope_semantics : require
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					shared uint value;
 | 
				
			||||||
 | 
					shared int atomi;
 | 
				
			||||||
 | 
					shared uint atomu;
 | 
				
			||||||
 | 
					layout(binding = 0, r32ui) workgroupcoherent uniform uimage2D imageu;
 | 
				
			||||||
 | 
					layout(binding = 1, r32i) coherent uniform iimage2D imagei;
 | 
				
			||||||
 | 
					layout (binding = 2) buffer BufferU { workgroupcoherent uint x; } bufferu;
 | 
				
			||||||
 | 
					layout (binding = 3) subgroupcoherent buffer BufferI { uint x; } bufferi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    int origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquireRelease);
 | 
				
			||||||
 | 
					    atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_StorageSemanticsBuffer);
 | 
				
			||||||
 | 
					    origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_SemanticsAcquire, gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, 0);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, 0, gl_SemanticsRelease);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease | gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    atomicAdd(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsAcquire);
 | 
				
			||||||
 | 
					    uint origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsMakeVisible);
 | 
				
			||||||
 | 
					    memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsMakeAvailable);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -462,6 +462,11 @@ public:
 | 
				
			|||||||
    void clearMemory()
 | 
					    void clearMemory()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        coherent     = false;
 | 
					        coherent     = false;
 | 
				
			||||||
 | 
					        devicecoherent = false;
 | 
				
			||||||
 | 
					        queuefamilycoherent = false;
 | 
				
			||||||
 | 
					        workgroupcoherent = false;
 | 
				
			||||||
 | 
					        subgroupcoherent  = false;
 | 
				
			||||||
 | 
					        nonprivate = false;
 | 
				
			||||||
        volatil      = false;
 | 
					        volatil      = false;
 | 
				
			||||||
        restrict     = false;
 | 
					        restrict     = false;
 | 
				
			||||||
        readonly     = false;
 | 
					        readonly     = false;
 | 
				
			||||||
@ -499,6 +504,11 @@ public:
 | 
				
			|||||||
    bool patch        : 1;
 | 
					    bool patch        : 1;
 | 
				
			||||||
    bool sample       : 1;
 | 
					    bool sample       : 1;
 | 
				
			||||||
    bool coherent     : 1;
 | 
					    bool coherent     : 1;
 | 
				
			||||||
 | 
					    bool devicecoherent : 1;
 | 
				
			||||||
 | 
					    bool queuefamilycoherent : 1;
 | 
				
			||||||
 | 
					    bool workgroupcoherent : 1;
 | 
				
			||||||
 | 
					    bool subgroupcoherent  : 1;
 | 
				
			||||||
 | 
					    bool nonprivate   : 1;
 | 
				
			||||||
    bool volatil      : 1;
 | 
					    bool volatil      : 1;
 | 
				
			||||||
    bool restrict     : 1;
 | 
					    bool restrict     : 1;
 | 
				
			||||||
    bool readonly     : 1;
 | 
					    bool readonly     : 1;
 | 
				
			||||||
@ -508,7 +518,11 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool isMemory() const
 | 
					    bool isMemory() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return coherent || volatil || restrict || readonly || writeonly;
 | 
					        return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    bool isMemoryQualifierImageAndSSBOOnly() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bool isInterpolation() const
 | 
					    bool isInterpolation() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -1713,6 +1727,16 @@ public:
 | 
				
			|||||||
            appendStr(" sample");
 | 
					            appendStr(" sample");
 | 
				
			||||||
        if (qualifier.coherent)
 | 
					        if (qualifier.coherent)
 | 
				
			||||||
            appendStr(" coherent");
 | 
					            appendStr(" coherent");
 | 
				
			||||||
 | 
					        if (qualifier.devicecoherent)
 | 
				
			||||||
 | 
					            appendStr(" devicecoherent");
 | 
				
			||||||
 | 
					        if (qualifier.queuefamilycoherent)
 | 
				
			||||||
 | 
					            appendStr(" queuefamilycoherent");
 | 
				
			||||||
 | 
					        if (qualifier.workgroupcoherent)
 | 
				
			||||||
 | 
					            appendStr(" workgroupcoherent");
 | 
				
			||||||
 | 
					        if (qualifier.subgroupcoherent)
 | 
				
			||||||
 | 
					            appendStr(" subgroupcoherent");
 | 
				
			||||||
 | 
					        if (qualifier.nonprivate)
 | 
				
			||||||
 | 
					            appendStr(" nonprivate");
 | 
				
			||||||
        if (qualifier.volatil)
 | 
					        if (qualifier.volatil)
 | 
				
			||||||
            appendStr(" volatile");
 | 
					            appendStr(" volatile");
 | 
				
			||||||
        if (qualifier.restrict)
 | 
					        if (qualifier.restrict)
 | 
				
			||||||
 | 
				
			|||||||
@ -592,6 +592,8 @@ enum TOperator {
 | 
				
			|||||||
    EOpAtomicXor,
 | 
					    EOpAtomicXor,
 | 
				
			||||||
    EOpAtomicExchange,
 | 
					    EOpAtomicExchange,
 | 
				
			||||||
    EOpAtomicCompSwap,
 | 
					    EOpAtomicCompSwap,
 | 
				
			||||||
 | 
					    EOpAtomicLoad,
 | 
				
			||||||
 | 
					    EOpAtomicStore,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EOpAtomicCounterIncrement, // results in pre-increment value
 | 
					    EOpAtomicCounterIncrement, // results in pre-increment value
 | 
				
			||||||
    EOpAtomicCounterDecrement, // results in post-decrement value
 | 
					    EOpAtomicCounterDecrement, // results in post-decrement value
 | 
				
			||||||
@ -784,6 +786,8 @@ enum TOperator {
 | 
				
			|||||||
    EOpImageAtomicXor,
 | 
					    EOpImageAtomicXor,
 | 
				
			||||||
    EOpImageAtomicExchange,
 | 
					    EOpImageAtomicExchange,
 | 
				
			||||||
    EOpImageAtomicCompSwap,
 | 
					    EOpImageAtomicCompSwap,
 | 
				
			||||||
 | 
					    EOpImageAtomicLoad,
 | 
				
			||||||
 | 
					    EOpImageAtomicStore,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EOpSubpassLoad,
 | 
					    EOpSubpassLoad,
 | 
				
			||||||
    EOpSubpassLoadMS,
 | 
					    EOpSubpassLoadMS,
 | 
				
			||||||
 | 
				
			|||||||
@ -935,27 +935,49 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 | 
				
			|||||||
        commonBuiltins.append(
 | 
					        commonBuiltins.append(
 | 
				
			||||||
            "uint atomicAdd(coherent volatile inout uint, uint);"
 | 
					            "uint atomicAdd(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicAdd(coherent volatile inout  int,  int);"
 | 
					            " int atomicAdd(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicAdd(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicAdd(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicMin(coherent volatile inout uint, uint);"
 | 
					            "uint atomicMin(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicMin(coherent volatile inout  int,  int);"
 | 
					            " int atomicMin(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicMin(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicMin(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicMax(coherent volatile inout uint, uint);"
 | 
					            "uint atomicMax(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicMax(coherent volatile inout  int,  int);"
 | 
					            " int atomicMax(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicMax(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicMax(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicAnd(coherent volatile inout uint, uint);"
 | 
					            "uint atomicAnd(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicAnd(coherent volatile inout  int,  int);"
 | 
					            " int atomicAnd(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicAnd(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicAnd(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicOr (coherent volatile inout uint, uint);"
 | 
					            "uint atomicOr (coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicOr (coherent volatile inout  int,  int);"
 | 
					            " int atomicOr (coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicOr (coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicOr (coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicXor(coherent volatile inout uint, uint);"
 | 
					            "uint atomicXor(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicXor(coherent volatile inout  int,  int);"
 | 
					            " int atomicXor(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicXor(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicXor(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicExchange(coherent volatile inout uint, uint);"
 | 
					            "uint atomicExchange(coherent volatile inout uint, uint);"
 | 
				
			||||||
            " int atomicExchange(coherent volatile inout  int,  int);"
 | 
					            " int atomicExchange(coherent volatile inout  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicExchange(coherent volatile inout uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicExchange(coherent volatile inout  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint atomicCompSwap(coherent volatile inout uint, uint, uint);"
 | 
					            "uint atomicCompSwap(coherent volatile inout uint, uint, uint);"
 | 
				
			||||||
            " int atomicCompSwap(coherent volatile inout  int,  int,  int);"
 | 
					            " int atomicCompSwap(coherent volatile inout  int,  int,  int);"
 | 
				
			||||||
 | 
					            "uint atomicCompSwap(coherent volatile inout uint, uint, uint, int, int, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicCompSwap(coherent volatile inout  int,  int,  int, int, int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "uint atomicLoad(coherent volatile in uint, int, int, int);"
 | 
				
			||||||
 | 
					            " int atomicLoad(coherent volatile in  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "void atomicStore(coherent volatile out uint, uint, int, int, int);"
 | 
				
			||||||
 | 
					            "void atomicStore(coherent volatile out  int,  int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "\n");
 | 
					            "\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -965,23 +987,49 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 | 
				
			|||||||
        commonBuiltins.append(
 | 
					        commonBuiltins.append(
 | 
				
			||||||
            "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);"
 | 
					            "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicMin(coherent volatile inout  int64_t,  int64_t);"
 | 
					            " int64_t atomicMin(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicMin(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
 | 
					            "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicMax(coherent volatile inout  int64_t,  int64_t);"
 | 
					            " int64_t atomicMax(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicMax(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
 | 
					            "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicAnd(coherent volatile inout  int64_t,  int64_t);"
 | 
					            " int64_t atomicAnd(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicAnd(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);"
 | 
					            "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicOr (coherent volatile inout  int64_t,  int64_t);"
 | 
					            " int64_t atomicOr (coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicOr (coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);"
 | 
					            "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicXor(coherent volatile inout  int64_t,  int64_t);"
 | 
					            " int64_t atomicXor(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicXor(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
 | 
					            "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
            " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
 | 
					            " int64_t atomicAdd(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
            " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);"
 | 
					            "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicAdd(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);"
 | 
				
			||||||
 | 
					            " int64_t atomicExchange(coherent volatile inout  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicExchange(coherent volatile inout  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);"
 | 
				
			||||||
 | 
					            " int64_t atomicCompSwap(coherent volatile inout  int64_t,  int64_t,  int64_t);"
 | 
				
			||||||
 | 
					            "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t, int, int, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicCompSwap(coherent volatile inout  int64_t,  int64_t,  int64_t, int, int, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            " int64_t atomicLoad(coherent volatile in  int64_t, int, int, int);"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
 | 
				
			||||||
 | 
					            "void atomicStore(coherent volatile out  int64_t,  int64_t, int, int, int);"
 | 
				
			||||||
            "\n");
 | 
					            "\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -4693,6 +4741,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    commonBuiltins.append("void controlBarrier(int, int, int, int);\n"
 | 
				
			||||||
 | 
					                          "void memoryBarrier(int, int, int);\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //============================================================================
 | 
					    //============================================================================
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    // Prototypes for built-in functions seen by fragment shaders only.
 | 
					    // Prototypes for built-in functions seen by fragment shaders only.
 | 
				
			||||||
@ -5807,6 +5858,28 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 | 
				
			|||||||
            "\n");
 | 
					            "\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((profile != EEsProfile && version >= 420) ||
 | 
				
			||||||
 | 
					        (profile == EEsProfile && version >= 310)) {
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_ScopeDevice      = 1;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_ScopeWorkgroup   = 2;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_ScopeSubgroup    = 3;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_ScopeInvocation  = 4;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_ScopeQueueFamily = 5;\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsRelaxed         = 0x0;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsAcquire         = 0x2;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsRelease         = 0x4;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsAcquireRelease  = 0x8;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsMakeAvailable   = 0x2000;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_SemanticsMakeVisible     = 0x4000;\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_StorageSemanticsNone     = 0x0;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_StorageSemanticsBuffer   = 0x40;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_StorageSemanticsShared   = 0x100;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_StorageSemanticsImage    = 0x800;\n");
 | 
				
			||||||
 | 
					        commonBuiltins.append("const int gl_StorageSemanticsOutput   = 0x1000;\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // printf("%s\n", commonBuiltins.c_str());
 | 
					    // printf("%s\n", commonBuiltins.c_str());
 | 
				
			||||||
    // printf("%s\n", stageBuiltins[EShLangFragment].c_str());
 | 
					    // printf("%s\n", stageBuiltins[EShLangFragment].c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -6106,23 +6179,44 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
 | 
				
			|||||||
                " imageAtomicExchange(volatile coherent "
 | 
					                " imageAtomicExchange(volatile coherent "
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (size_t i = 0; i < numBuiltins; ++i) {
 | 
					            // Loop twice to add prototypes with/without scope/semantics
 | 
				
			||||||
 | 
					            for (int j = 0; j < 2; ++j) {
 | 
				
			||||||
 | 
					                for (size_t i = 0; i < numBuiltins; ++i) {
 | 
				
			||||||
 | 
					                    commonBuiltins.append(dataType);
 | 
				
			||||||
 | 
					                    commonBuiltins.append(atomicFunc[i]);
 | 
				
			||||||
 | 
					                    commonBuiltins.append(imageParams);
 | 
				
			||||||
 | 
					                    commonBuiltins.append(", ");
 | 
				
			||||||
 | 
					                    commonBuiltins.append(dataType);
 | 
				
			||||||
 | 
					                    if (j == 1) {
 | 
				
			||||||
 | 
					                        commonBuiltins.append(", int, int, int");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    commonBuiltins.append(");\n");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                commonBuiltins.append(dataType);
 | 
					                commonBuiltins.append(dataType);
 | 
				
			||||||
                commonBuiltins.append(atomicFunc[i]);
 | 
					                commonBuiltins.append(" imageAtomicCompSwap(volatile coherent ");
 | 
				
			||||||
                commonBuiltins.append(imageParams);
 | 
					                commonBuiltins.append(imageParams);
 | 
				
			||||||
                commonBuiltins.append(", ");
 | 
					                commonBuiltins.append(", ");
 | 
				
			||||||
                commonBuiltins.append(dataType);
 | 
					                commonBuiltins.append(dataType);
 | 
				
			||||||
 | 
					                commonBuiltins.append(", ");
 | 
				
			||||||
 | 
					                commonBuiltins.append(dataType);
 | 
				
			||||||
 | 
					                if (j == 1) {
 | 
				
			||||||
 | 
					                    commonBuiltins.append(", int, int, int, int, int");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                commonBuiltins.append(");\n");
 | 
					                commonBuiltins.append(");\n");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            commonBuiltins.append(dataType);
 | 
					            commonBuiltins.append(dataType);
 | 
				
			||||||
            commonBuiltins.append(" imageAtomicCompSwap(volatile coherent ");
 | 
					            commonBuiltins.append(" imageAtomicLoad(volatile coherent ");
 | 
				
			||||||
 | 
					            commonBuiltins.append(imageParams);
 | 
				
			||||||
 | 
					            commonBuiltins.append(", int, int, int);\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            commonBuiltins.append("void imageAtomicStore(volatile coherent ");
 | 
				
			||||||
            commonBuiltins.append(imageParams);
 | 
					            commonBuiltins.append(imageParams);
 | 
				
			||||||
            commonBuiltins.append(", ");
 | 
					            commonBuiltins.append(", ");
 | 
				
			||||||
            commonBuiltins.append(dataType);
 | 
					            commonBuiltins.append(dataType);
 | 
				
			||||||
            commonBuiltins.append(", ");
 | 
					            commonBuiltins.append(", int, int, int);\n");
 | 
				
			||||||
            commonBuiltins.append(dataType);
 | 
					
 | 
				
			||||||
            commonBuiltins.append(");\n");
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // not int or uint
 | 
					            // not int or uint
 | 
				
			||||||
            // GL_ARB_ES3_1_compatibility
 | 
					            // GL_ARB_ES3_1_compatibility
 | 
				
			||||||
@ -7969,6 +8063,26 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 | 
				
			|||||||
            symbolTable.setFunctionExtensions("shadow2DEXT",        1, &E_GL_EXT_shadow_samplers);
 | 
					            symbolTable.setFunctionExtensions("shadow2DEXT",        1, &E_GL_EXT_shadow_samplers);
 | 
				
			||||||
            symbolTable.setFunctionExtensions("shadow2DProjEXT",    1, &E_GL_EXT_shadow_samplers);
 | 
					            symbolTable.setFunctionExtensions("shadow2DProjEXT",    1, &E_GL_EXT_shadow_samplers);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (spvVersion.vulkan > 0) {
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_ScopeDevice",             1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_ScopeWorkgroup",          1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_ScopeSubgroup",           1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_ScopeInvocation",         1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsRelaxed",        1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsAcquire",        1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsRelease",        1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable",  1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_SemanticsMakeVisible",    1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_StorageSemanticsNone",    1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer",  1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_StorageSemanticsShared",  1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_StorageSemanticsImage",   1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					            symbolTable.setVariableExtensions("gl_StorageSemanticsOutput",  1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case EShLangCompute:
 | 
					    case EShLangCompute:
 | 
				
			||||||
@ -8003,6 +8117,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 | 
				
			|||||||
            symbolTable.setFunctionExtensions("groupMemoryBarrier",         1, &E_GL_ARB_compute_shader);
 | 
					            symbolTable.setFunctionExtensions("groupMemoryBarrier",         1, &E_GL_ARB_compute_shader);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        symbolTable.setFunctionExtensions("controlBarrier",                 1, &E_GL_KHR_memory_scope_semantics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // GL_ARB_shader_ballot
 | 
					        // GL_ARB_shader_ballot
 | 
				
			||||||
        if (profile != EEsProfile) {
 | 
					        if (profile != EEsProfile) {
 | 
				
			||||||
            symbolTable.setVariableExtensions("gl_SubGroupSizeARB",       1, &E_GL_ARB_shader_ballot);
 | 
					            symbolTable.setVariableExtensions("gl_SubGroupSizeARB",       1, &E_GL_ARB_shader_ballot);
 | 
				
			||||||
@ -8213,6 +8329,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 | 
				
			|||||||
    symbolTable.relateToOperator("all",          EOpAll);
 | 
					    symbolTable.relateToOperator("all",          EOpAll);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    symbolTable.relateToOperator("barrier",                    EOpBarrier);
 | 
					    symbolTable.relateToOperator("barrier",                    EOpBarrier);
 | 
				
			||||||
 | 
					    symbolTable.relateToOperator("controlBarrier",             EOpBarrier);
 | 
				
			||||||
    symbolTable.relateToOperator("memoryBarrier",              EOpMemoryBarrier);
 | 
					    symbolTable.relateToOperator("memoryBarrier",              EOpMemoryBarrier);
 | 
				
			||||||
    symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
 | 
					    symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
 | 
				
			||||||
    symbolTable.relateToOperator("memoryBarrierBuffer",        EOpMemoryBarrierBuffer);
 | 
					    symbolTable.relateToOperator("memoryBarrierBuffer",        EOpMemoryBarrierBuffer);
 | 
				
			||||||
@ -8226,6 +8343,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 | 
				
			|||||||
    symbolTable.relateToOperator("atomicXor",      EOpAtomicXor);
 | 
					    symbolTable.relateToOperator("atomicXor",      EOpAtomicXor);
 | 
				
			||||||
    symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange);
 | 
					    symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange);
 | 
				
			||||||
    symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap);
 | 
					    symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap);
 | 
				
			||||||
 | 
					    symbolTable.relateToOperator("atomicLoad",     EOpAtomicLoad);
 | 
				
			||||||
 | 
					    symbolTable.relateToOperator("atomicStore",    EOpAtomicStore);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement);
 | 
					    symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement);
 | 
				
			||||||
    symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
 | 
					    symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
 | 
				
			||||||
@ -8270,6 +8389,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 | 
				
			|||||||
        symbolTable.relateToOperator("imageAtomicXor",          EOpImageAtomicXor);
 | 
					        symbolTable.relateToOperator("imageAtomicXor",          EOpImageAtomicXor);
 | 
				
			||||||
        symbolTable.relateToOperator("imageAtomicExchange",     EOpImageAtomicExchange);
 | 
					        symbolTable.relateToOperator("imageAtomicExchange",     EOpImageAtomicExchange);
 | 
				
			||||||
        symbolTable.relateToOperator("imageAtomicCompSwap",     EOpImageAtomicCompSwap);
 | 
					        symbolTable.relateToOperator("imageAtomicCompSwap",     EOpImageAtomicCompSwap);
 | 
				
			||||||
 | 
					        symbolTable.relateToOperator("imageAtomicLoad",         EOpImageAtomicLoad);
 | 
				
			||||||
 | 
					        symbolTable.relateToOperator("imageAtomicStore",        EOpImageAtomicStore);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        symbolTable.relateToOperator("subpassLoad",             EOpSubpassLoad);
 | 
					        symbolTable.relateToOperator("subpassLoad",             EOpSubpassLoad);
 | 
				
			||||||
        symbolTable.relateToOperator("subpassLoadMS",           EOpSubpassLoadMS);
 | 
					        symbolTable.relateToOperator("subpassLoadMS",           EOpSubpassLoadMS);
 | 
				
			||||||
 | 
				
			|||||||
@ -267,6 +267,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
 | 
				
			|||||||
        if (tokens.size() != 1)
 | 
					        if (tokens.size() != 1)
 | 
				
			||||||
            error(loc, "extra tokens", "#pragma", "");
 | 
					            error(loc, "extra tokens", "#pragma", "");
 | 
				
			||||||
        intermediate.setUseStorageBuffer();
 | 
					        intermediate.setUseStorageBuffer();
 | 
				
			||||||
 | 
					    } else if (spvVersion.spv > 0 && tokens[0].compare("use_vulkan_memory_model") == 0) {
 | 
				
			||||||
 | 
					        if (tokens.size() != 1)
 | 
				
			||||||
 | 
					            error(loc, "extra tokens", "#pragma", "");
 | 
				
			||||||
 | 
					        intermediate.setUseVulkanMemoryModel();
 | 
				
			||||||
    } else if (tokens[0].compare("once") == 0) {
 | 
					    } else if (tokens[0].compare("once") == 0) {
 | 
				
			||||||
        warn(loc, "not implemented", "#pragma once", "");
 | 
					        warn(loc, "not implemented", "#pragma once", "");
 | 
				
			||||||
    } else if (tokens[0].compare("glslang_binary_double_output") == 0)
 | 
					    } else if (tokens[0].compare("glslang_binary_double_output") == 0)
 | 
				
			||||||
@ -1028,8 +1032,16 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
 | 
				
			|||||||
                        const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
 | 
					                        const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
 | 
				
			||||||
                        if (argQualifier.volatil && ! formalQualifier.volatil)
 | 
					                        if (argQualifier.volatil && ! formalQualifier.volatil)
 | 
				
			||||||
                            error(arguments->getLoc(), message, "volatile", "");
 | 
					                            error(arguments->getLoc(), message, "volatile", "");
 | 
				
			||||||
                        if (argQualifier.coherent && ! formalQualifier.coherent)
 | 
					                        if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
 | 
				
			||||||
                            error(arguments->getLoc(), message, "coherent", "");
 | 
					                            error(arguments->getLoc(), message, "coherent", "");
 | 
				
			||||||
 | 
					                        if (argQualifier.devicecoherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
 | 
				
			||||||
 | 
					                            error(arguments->getLoc(), message, "devicecoherent", "");
 | 
				
			||||||
 | 
					                        if (argQualifier.queuefamilycoherent && ! (formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
 | 
				
			||||||
 | 
					                            error(arguments->getLoc(), message, "queuefamilycoherent", "");
 | 
				
			||||||
 | 
					                        if (argQualifier.workgroupcoherent && ! (formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
 | 
				
			||||||
 | 
					                            error(arguments->getLoc(), message, "workgroupcoherent", "");
 | 
				
			||||||
 | 
					                        if (argQualifier.subgroupcoherent && ! (formalQualifier.subgroupcoherent || formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
 | 
				
			||||||
 | 
					                            error(arguments->getLoc(), message, "subgroupcoherent", "");
 | 
				
			||||||
                        if (argQualifier.readonly && ! formalQualifier.readonly)
 | 
					                        if (argQualifier.readonly && ! formalQualifier.readonly)
 | 
				
			||||||
                            error(arguments->getLoc(), message, "readonly", "");
 | 
					                            error(arguments->getLoc(), message, "readonly", "");
 | 
				
			||||||
                        if (argQualifier.writeonly && ! formalQualifier.writeonly)
 | 
					                        if (argQualifier.writeonly && ! formalQualifier.writeonly)
 | 
				
			||||||
@ -1428,6 +1440,159 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
 | 
				
			|||||||
    return conversionTree;
 | 
					    return conversionTree;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const int gl_SemanticsRelaxed         = 0x0;
 | 
				
			||||||
 | 
					    const int gl_SemanticsAcquire         = 0x2;
 | 
				
			||||||
 | 
					    const int gl_SemanticsRelease         = 0x4;
 | 
				
			||||||
 | 
					    const int gl_SemanticsAcquireRelease  = 0x8;
 | 
				
			||||||
 | 
					    const int gl_SemanticsMakeAvailable   = 0x2000;
 | 
				
			||||||
 | 
					    const int gl_SemanticsMakeVisible     = 0x4000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const int gl_StorageSemanticsNone     = 0x0;
 | 
				
			||||||
 | 
					    const int gl_StorageSemanticsBuffer   = 0x40;
 | 
				
			||||||
 | 
					    const int gl_StorageSemanticsShared   = 0x100;
 | 
				
			||||||
 | 
					    const int gl_StorageSemanticsImage    = 0x800;
 | 
				
			||||||
 | 
					    const int gl_StorageSemanticsOutput   = 0x1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned int semantics = 0, storageClassSemantics = 0;
 | 
				
			||||||
 | 
					    unsigned int semantics2 = 0, storageClassSemantics2 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Grab the semantics and storage class semantics from the operands, based on opcode
 | 
				
			||||||
 | 
					    switch (callNode.getOp()) {
 | 
				
			||||||
 | 
					    case EOpAtomicAdd:
 | 
				
			||||||
 | 
					    case EOpAtomicMin:
 | 
				
			||||||
 | 
					    case EOpAtomicMax:
 | 
				
			||||||
 | 
					    case EOpAtomicAnd:
 | 
				
			||||||
 | 
					    case EOpAtomicOr:
 | 
				
			||||||
 | 
					    case EOpAtomicXor:
 | 
				
			||||||
 | 
					    case EOpAtomicExchange:
 | 
				
			||||||
 | 
					    case EOpAtomicStore:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EOpAtomicLoad:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EOpAtomicCompSwap:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        storageClassSemantics2 = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case EOpImageAtomicAdd:
 | 
				
			||||||
 | 
					    case EOpImageAtomicMin:
 | 
				
			||||||
 | 
					    case EOpImageAtomicMax:
 | 
				
			||||||
 | 
					    case EOpImageAtomicAnd:
 | 
				
			||||||
 | 
					    case EOpImageAtomicOr:
 | 
				
			||||||
 | 
					    case EOpImageAtomicXor:
 | 
				
			||||||
 | 
					    case EOpImageAtomicExchange:
 | 
				
			||||||
 | 
					    case EOpImageAtomicStore:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EOpImageAtomicLoad:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EOpImageAtomicCompSwap:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case EOpBarrier:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EOpMemoryBarrier:
 | 
				
			||||||
 | 
					        storageClassSemantics = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        semantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((semantics & gl_SemanticsAcquire) && 
 | 
				
			||||||
 | 
					        (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) {
 | 
				
			||||||
 | 
					        error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((semantics & gl_SemanticsRelease) && 
 | 
				
			||||||
 | 
					        (callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
 | 
				
			||||||
 | 
					        error(loc, "gl_SemanticsRelease must not be used with (image) atomic load",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((semantics & gl_SemanticsAcquireRelease) && 
 | 
				
			||||||
 | 
					        (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore || 
 | 
				
			||||||
 | 
					         callNode.getOp() == EOpAtomicLoad  || callNode.getOp() == EOpImageAtomicLoad)) {
 | 
				
			||||||
 | 
					        error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (((semantics | semantics2) & ~(gl_SemanticsAcquire |
 | 
				
			||||||
 | 
					                                      gl_SemanticsRelease |
 | 
				
			||||||
 | 
					                                      gl_SemanticsAcquireRelease |
 | 
				
			||||||
 | 
					                                      gl_SemanticsMakeAvailable |
 | 
				
			||||||
 | 
					                                      gl_SemanticsMakeVisible))) {
 | 
				
			||||||
 | 
					        error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer |
 | 
				
			||||||
 | 
					                                                              gl_StorageSemanticsShared |
 | 
				
			||||||
 | 
					                                                              gl_StorageSemanticsImage |
 | 
				
			||||||
 | 
					                                                              gl_StorageSemanticsOutput))) {
 | 
				
			||||||
 | 
					        error(loc, "Invalid storage class semantics value", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (callNode.getOp() == EOpMemoryBarrier) {
 | 
				
			||||||
 | 
					        if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					            error(loc, "Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or "
 | 
				
			||||||
 | 
					                       "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
 | 
				
			||||||
 | 
					            if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					                error(loc, "Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
 | 
				
			||||||
 | 
					                           "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
 | 
				
			||||||
 | 
					            if (!IsPow2(semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					                error(loc, "semUnequal must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
 | 
				
			||||||
 | 
					                           "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (callNode.getOp() == EOpMemoryBarrier) {
 | 
				
			||||||
 | 
					        if (storageClassSemantics == 0) {
 | 
				
			||||||
 | 
					            error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (callNode.getOp() == EOpBarrier && semantics != 0 && storageClassSemantics == 0) {
 | 
				
			||||||
 | 
					        error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
 | 
				
			||||||
 | 
					        (semantics2 & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					        error(loc, "semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((semantics & gl_SemanticsMakeAvailable) &&
 | 
				
			||||||
 | 
					        !(semantics & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					        error(loc, "gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((semantics & gl_SemanticsMakeVisible) &&
 | 
				
			||||||
 | 
					        !(semantics & (gl_SemanticsAcquire | gl_SemanticsAcquireRelease))) {
 | 
				
			||||||
 | 
					        error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease",
 | 
				
			||||||
 | 
					              fnCandidate.getName().c_str(), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Do additional checking of built-in function calls that is not caught
 | 
					// Do additional checking of built-in function calls that is not caught
 | 
				
			||||||
// by normal semantic checks on argument type, extension tagging, etc.
 | 
					// by normal semantic checks on argument type, extension tagging, etc.
 | 
				
			||||||
@ -1656,6 +1821,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
 | 
				
			|||||||
    case EOpImageAtomicXor:
 | 
					    case EOpImageAtomicXor:
 | 
				
			||||||
    case EOpImageAtomicExchange:
 | 
					    case EOpImageAtomicExchange:
 | 
				
			||||||
    case EOpImageAtomicCompSwap:
 | 
					    case EOpImageAtomicCompSwap:
 | 
				
			||||||
 | 
					    case EOpImageAtomicLoad:
 | 
				
			||||||
 | 
					    case EOpImageAtomicStore:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Make sure the image types have the correct layout() format and correct argument types
 | 
					        // Make sure the image types have the correct layout() format and correct argument types
 | 
				
			||||||
        const TType& imageType = arg0->getType();
 | 
					        const TType& imageType = arg0->getType();
 | 
				
			||||||
@ -1669,10 +1836,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
 | 
				
			|||||||
                error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
 | 
					                error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (argp->size() > 4) {
 | 
				
			||||||
 | 
					            requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
 | 
				
			||||||
 | 
					            memorySemanticsCheck(loc, fnCandidate, callNode);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef NV_EXTENSIONS
 | 
					 | 
				
			||||||
    case EOpAtomicAdd:
 | 
					    case EOpAtomicAdd:
 | 
				
			||||||
    case EOpAtomicMin:
 | 
					    case EOpAtomicMin:
 | 
				
			||||||
    case EOpAtomicMax:
 | 
					    case EOpAtomicMax:
 | 
				
			||||||
@ -1681,13 +1852,19 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
 | 
				
			|||||||
    case EOpAtomicXor:
 | 
					    case EOpAtomicXor:
 | 
				
			||||||
    case EOpAtomicExchange:
 | 
					    case EOpAtomicExchange:
 | 
				
			||||||
    case EOpAtomicCompSwap:
 | 
					    case EOpAtomicCompSwap:
 | 
				
			||||||
 | 
					    case EOpAtomicLoad:
 | 
				
			||||||
 | 
					    case EOpAtomicStore:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64)
 | 
					        if (argp->size() > 3) {
 | 
				
			||||||
 | 
					            requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
 | 
				
			||||||
 | 
					            memorySemanticsCheck(loc, fnCandidate, callNode);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#ifdef NV_EXTENSIONS
 | 
				
			||||||
 | 
					        else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64)
 | 
				
			||||||
            requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str());
 | 
					            requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case EOpInterpolateAtCentroid:
 | 
					    case EOpInterpolateAtCentroid:
 | 
				
			||||||
    case EOpInterpolateAtSample:
 | 
					    case EOpInterpolateAtSample:
 | 
				
			||||||
@ -1751,6 +1928,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case EOpBarrier:
 | 
				
			||||||
 | 
					    case EOpMemoryBarrier:
 | 
				
			||||||
 | 
					        if (argp->size() > 0) {
 | 
				
			||||||
 | 
					            requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
 | 
				
			||||||
 | 
					            memorySemanticsCheck(loc, fnCandidate, callNode);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -2806,8 +2991,11 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
 | 
				
			|||||||
    if (! symbolTable.atGlobalLevel())
 | 
					    if (! symbolTable.atGlobalLevel())
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer)
 | 
					    if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
 | 
				
			||||||
        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)
 | 
				
			||||||
        error(loc, "buffers can be declared only as blocks", "buffer", "");
 | 
					        error(loc, "buffers can be declared only as blocks", "buffer", "");
 | 
				
			||||||
@ -3020,6 +3208,13 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
 | 
				
			|||||||
    if (dst.precision == EpqNone || (force && src.precision != EpqNone))
 | 
					    if (dst.precision == EpqNone || (force && src.precision != EpqNone))
 | 
				
			||||||
        dst.precision = src.precision;
 | 
					        dst.precision = src.precision;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
 | 
				
			||||||
 | 
					                   (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
 | 
				
			||||||
 | 
					                   (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
 | 
				
			||||||
 | 
					                   (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) ||
 | 
				
			||||||
 | 
					                   (src.subgroupcoherent  && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) {
 | 
				
			||||||
 | 
					        error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), "");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    // Layout qualifiers
 | 
					    // Layout qualifiers
 | 
				
			||||||
    mergeObjectLayoutQualifiers(dst, src, false);
 | 
					    mergeObjectLayoutQualifiers(dst, src, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3038,6 +3233,11 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
 | 
				
			|||||||
    MERGE_SINGLETON(patch);
 | 
					    MERGE_SINGLETON(patch);
 | 
				
			||||||
    MERGE_SINGLETON(sample);
 | 
					    MERGE_SINGLETON(sample);
 | 
				
			||||||
    MERGE_SINGLETON(coherent);
 | 
					    MERGE_SINGLETON(coherent);
 | 
				
			||||||
 | 
					    MERGE_SINGLETON(devicecoherent);
 | 
				
			||||||
 | 
					    MERGE_SINGLETON(queuefamilycoherent);
 | 
				
			||||||
 | 
					    MERGE_SINGLETON(workgroupcoherent);
 | 
				
			||||||
 | 
					    MERGE_SINGLETON(subgroupcoherent);
 | 
				
			||||||
 | 
					    MERGE_SINGLETON(nonprivate);
 | 
				
			||||||
    MERGE_SINGLETON(volatil);
 | 
					    MERGE_SINGLETON(volatil);
 | 
				
			||||||
    MERGE_SINGLETON(restrict);
 | 
					    MERGE_SINGLETON(restrict);
 | 
				
			||||||
    MERGE_SINGLETON(readonly);
 | 
					    MERGE_SINGLETON(readonly);
 | 
				
			||||||
@ -3862,6 +4062,11 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
 | 
				
			|||||||
    if (qualifier.isMemory()) {
 | 
					    if (qualifier.isMemory()) {
 | 
				
			||||||
        type.getQualifier().volatil   = qualifier.volatil;
 | 
					        type.getQualifier().volatil   = qualifier.volatil;
 | 
				
			||||||
        type.getQualifier().coherent  = qualifier.coherent;
 | 
					        type.getQualifier().coherent  = qualifier.coherent;
 | 
				
			||||||
 | 
					        type.getQualifier().devicecoherent  = qualifier.devicecoherent ;
 | 
				
			||||||
 | 
					        type.getQualifier().queuefamilycoherent  = qualifier.queuefamilycoherent;
 | 
				
			||||||
 | 
					        type.getQualifier().workgroupcoherent  = qualifier.workgroupcoherent;
 | 
				
			||||||
 | 
					        type.getQualifier().subgroupcoherent  = qualifier.subgroupcoherent;
 | 
				
			||||||
 | 
					        type.getQualifier().nonprivate = qualifier.nonprivate;
 | 
				
			||||||
        type.getQualifier().readonly  = qualifier.readonly;
 | 
					        type.getQualifier().readonly  = qualifier.readonly;
 | 
				
			||||||
        type.getQualifier().writeonly = qualifier.writeonly;
 | 
					        type.getQualifier().writeonly = qualifier.writeonly;
 | 
				
			||||||
        type.getQualifier().restrict  = qualifier.restrict;
 | 
					        type.getQualifier().restrict  = qualifier.restrict;
 | 
				
			||||||
 | 
				
			|||||||
@ -323,6 +323,7 @@ public:
 | 
				
			|||||||
    TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
 | 
					    TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
 | 
				
			||||||
    void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
 | 
					    void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
 | 
				
			||||||
    void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
 | 
					    void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
 | 
				
			||||||
 | 
					    void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void assignError(const TSourceLoc&, const char* op, TString left, TString right);
 | 
					    void assignError(const TSourceLoc&, const char* op, TString left, TString right);
 | 
				
			||||||
    void unaryOpError(const TSourceLoc&, const char* op, TString operand);
 | 
					    void unaryOpError(const TSourceLoc&, const char* op, TString operand);
 | 
				
			||||||
 | 
				
			|||||||
@ -380,6 +380,11 @@ void TScanContext::fillInKeywordMap()
 | 
				
			|||||||
    (*KeywordMap)["varying"] =                 VARYING;
 | 
					    (*KeywordMap)["varying"] =                 VARYING;
 | 
				
			||||||
    (*KeywordMap)["buffer"] =                  BUFFER;
 | 
					    (*KeywordMap)["buffer"] =                  BUFFER;
 | 
				
			||||||
    (*KeywordMap)["coherent"] =                COHERENT;
 | 
					    (*KeywordMap)["coherent"] =                COHERENT;
 | 
				
			||||||
 | 
					    (*KeywordMap)["devicecoherent"] =          DEVICECOHERENT;
 | 
				
			||||||
 | 
					    (*KeywordMap)["queuefamilycoherent"] =     QUEUEFAMILYCOHERENT;
 | 
				
			||||||
 | 
					    (*KeywordMap)["workgroupcoherent"] =       WORKGROUPCOHERENT;
 | 
				
			||||||
 | 
					    (*KeywordMap)["subgroupcoherent"] =        SUBGROUPCOHERENT;
 | 
				
			||||||
 | 
					    (*KeywordMap)["nonprivate"] =              NONPRIVATE;
 | 
				
			||||||
    (*KeywordMap)["restrict"] =                RESTRICT;
 | 
					    (*KeywordMap)["restrict"] =                RESTRICT;
 | 
				
			||||||
    (*KeywordMap)["readonly"] =                READONLY;
 | 
					    (*KeywordMap)["readonly"] =                READONLY;
 | 
				
			||||||
    (*KeywordMap)["writeonly"] =               WRITEONLY;
 | 
					    (*KeywordMap)["writeonly"] =               WRITEONLY;
 | 
				
			||||||
@ -937,6 +942,11 @@ int TScanContext::tokenizeIdentifier()
 | 
				
			|||||||
        return es30ReservedFromGLSL(420);
 | 
					        return es30ReservedFromGLSL(420);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case COHERENT:
 | 
					    case COHERENT:
 | 
				
			||||||
 | 
					    case DEVICECOHERENT:
 | 
				
			||||||
 | 
					    case QUEUEFAMILYCOHERENT:
 | 
				
			||||||
 | 
					    case WORKGROUPCOHERENT:
 | 
				
			||||||
 | 
					    case SUBGROUPCOHERENT:
 | 
				
			||||||
 | 
					    case NONPRIVATE:
 | 
				
			||||||
    case RESTRICT:
 | 
					    case RESTRICT:
 | 
				
			||||||
    case READONLY:
 | 
					    case READONLY:
 | 
				
			||||||
    case WRITEONLY:
 | 
					    case WRITEONLY:
 | 
				
			||||||
 | 
				
			|||||||
@ -194,6 +194,7 @@ void TParseVersions::initializeExtensionBehavior()
 | 
				
			|||||||
    extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
 | 
					    extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
 | 
				
			||||||
    extensionBehavior[E_GL_KHR_shader_subgroup_clustered]        = EBhDisable;
 | 
					    extensionBehavior[E_GL_KHR_shader_subgroup_clustered]        = EBhDisable;
 | 
				
			||||||
    extensionBehavior[E_GL_KHR_shader_subgroup_quad]             = EBhDisable;
 | 
					    extensionBehavior[E_GL_KHR_shader_subgroup_quad]             = EBhDisable;
 | 
				
			||||||
 | 
					    extensionBehavior[E_GL_KHR_memory_scope_semantics]           = EBhDisable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
 | 
					    extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
 | 
				
			||||||
    extensionBehavior[E_GL_EXT_shader_image_load_formatted]             = EBhDisable;
 | 
					    extensionBehavior[E_GL_EXT_shader_image_load_formatted]             = EBhDisable;
 | 
				
			||||||
 | 
				
			|||||||
@ -148,6 +148,7 @@ const char* const E_GL_KHR_shader_subgroup_shuffle          = "GL_KHR_shader_sub
 | 
				
			|||||||
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
 | 
					const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
 | 
				
			||||||
const char* const E_GL_KHR_shader_subgroup_clustered        = "GL_KHR_shader_subgroup_clustered";
 | 
					const char* const E_GL_KHR_shader_subgroup_clustered        = "GL_KHR_shader_subgroup_clustered";
 | 
				
			||||||
const char* const E_GL_KHR_shader_subgroup_quad             = "GL_KHR_shader_subgroup_quad";
 | 
					const char* const E_GL_KHR_shader_subgroup_quad             = "GL_KHR_shader_subgroup_quad";
 | 
				
			||||||
 | 
					const char* const E_GL_KHR_memory_scope_semantics           = "GL_KHR_memory_scope_semantics";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
 | 
					const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
 | 
				
			||||||
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
 | 
					const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
 | 
				
			||||||
 | 
				
			|||||||
@ -141,7 +141,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 | 
				
			|||||||
%token <lex> VEC2 VEC3 VEC4
 | 
					%token <lex> VEC2 VEC3 VEC4
 | 
				
			||||||
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
 | 
					%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
 | 
				
			||||||
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
 | 
					%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
 | 
				
			||||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
 | 
					%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT SUBGROUPCOHERENT NONPRIVATE
 | 
				
			||||||
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
 | 
					%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
 | 
				
			||||||
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
 | 
					%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
 | 
				
			||||||
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
 | 
					%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
 | 
				
			||||||
@ -1317,6 +1317,31 @@ storage_qualifier
 | 
				
			|||||||
        $$.init($1.loc);
 | 
					        $$.init($1.loc);
 | 
				
			||||||
        $$.qualifier.coherent = true;
 | 
					        $$.qualifier.coherent = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    | DEVICECOHERENT {
 | 
				
			||||||
 | 
					        $$.init($1.loc);
 | 
				
			||||||
 | 
					        parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent");
 | 
				
			||||||
 | 
					        $$.qualifier.devicecoherent = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    | QUEUEFAMILYCOHERENT {
 | 
				
			||||||
 | 
					        $$.init($1.loc);
 | 
				
			||||||
 | 
					        parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent");
 | 
				
			||||||
 | 
					        $$.qualifier.queuefamilycoherent = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    | WORKGROUPCOHERENT {
 | 
				
			||||||
 | 
					        $$.init($1.loc);
 | 
				
			||||||
 | 
					        parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent");
 | 
				
			||||||
 | 
					        $$.qualifier.workgroupcoherent = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    | SUBGROUPCOHERENT {
 | 
				
			||||||
 | 
					        $$.init($1.loc);
 | 
				
			||||||
 | 
					        parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent");
 | 
				
			||||||
 | 
					        $$.qualifier.subgroupcoherent = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    | NONPRIVATE {
 | 
				
			||||||
 | 
					        $$.init($1.loc);
 | 
				
			||||||
 | 
					        parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate");
 | 
				
			||||||
 | 
					        $$.qualifier.nonprivate = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    | VOLATILE {
 | 
					    | VOLATILE {
 | 
				
			||||||
        $$.init($1.loc);
 | 
					        $$.init($1.loc);
 | 
				
			||||||
        $$.qualifier.volatil = true;
 | 
					        $$.qualifier.volatil = true;
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,8 +1,8 @@
 | 
				
			|||||||
/* A Bison parser, made by GNU Bison 3.0.  */
 | 
					/* A Bison parser, made by GNU Bison 3.0.4.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Bison interface for Yacc-like parsers in C
 | 
					/* Bison interface for Yacc-like parsers in C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
 | 
					   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   This program is free software: you can redistribute it and/or modify
 | 
					   This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
   it under the terms of the GNU General Public License as published by
 | 
					   it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@ -130,315 +130,320 @@ extern int yydebug;
 | 
				
			|||||||
    RESTRICT = 340,
 | 
					    RESTRICT = 340,
 | 
				
			||||||
    READONLY = 341,
 | 
					    READONLY = 341,
 | 
				
			||||||
    WRITEONLY = 342,
 | 
					    WRITEONLY = 342,
 | 
				
			||||||
    DVEC2 = 343,
 | 
					    DEVICECOHERENT = 343,
 | 
				
			||||||
    DVEC3 = 344,
 | 
					    QUEUEFAMILYCOHERENT = 344,
 | 
				
			||||||
    DVEC4 = 345,
 | 
					    WORKGROUPCOHERENT = 345,
 | 
				
			||||||
    DMAT2 = 346,
 | 
					    SUBGROUPCOHERENT = 346,
 | 
				
			||||||
    DMAT3 = 347,
 | 
					    NONPRIVATE = 347,
 | 
				
			||||||
    DMAT4 = 348,
 | 
					    DVEC2 = 348,
 | 
				
			||||||
    F16VEC2 = 349,
 | 
					    DVEC3 = 349,
 | 
				
			||||||
    F16VEC3 = 350,
 | 
					    DVEC4 = 350,
 | 
				
			||||||
    F16VEC4 = 351,
 | 
					    DMAT2 = 351,
 | 
				
			||||||
    F16MAT2 = 352,
 | 
					    DMAT3 = 352,
 | 
				
			||||||
    F16MAT3 = 353,
 | 
					    DMAT4 = 353,
 | 
				
			||||||
    F16MAT4 = 354,
 | 
					    F16VEC2 = 354,
 | 
				
			||||||
    F32VEC2 = 355,
 | 
					    F16VEC3 = 355,
 | 
				
			||||||
    F32VEC3 = 356,
 | 
					    F16VEC4 = 356,
 | 
				
			||||||
    F32VEC4 = 357,
 | 
					    F16MAT2 = 357,
 | 
				
			||||||
    F32MAT2 = 358,
 | 
					    F16MAT3 = 358,
 | 
				
			||||||
    F32MAT3 = 359,
 | 
					    F16MAT4 = 359,
 | 
				
			||||||
    F32MAT4 = 360,
 | 
					    F32VEC2 = 360,
 | 
				
			||||||
    F64VEC2 = 361,
 | 
					    F32VEC3 = 361,
 | 
				
			||||||
    F64VEC3 = 362,
 | 
					    F32VEC4 = 362,
 | 
				
			||||||
    F64VEC4 = 363,
 | 
					    F32MAT2 = 363,
 | 
				
			||||||
    F64MAT2 = 364,
 | 
					    F32MAT3 = 364,
 | 
				
			||||||
    F64MAT3 = 365,
 | 
					    F32MAT4 = 365,
 | 
				
			||||||
    F64MAT4 = 366,
 | 
					    F64VEC2 = 366,
 | 
				
			||||||
    NOPERSPECTIVE = 367,
 | 
					    F64VEC3 = 367,
 | 
				
			||||||
    FLAT = 368,
 | 
					    F64VEC4 = 368,
 | 
				
			||||||
    SMOOTH = 369,
 | 
					    F64MAT2 = 369,
 | 
				
			||||||
    LAYOUT = 370,
 | 
					    F64MAT3 = 370,
 | 
				
			||||||
    EXPLICITINTERPAMD = 371,
 | 
					    F64MAT4 = 371,
 | 
				
			||||||
    MAT2X2 = 372,
 | 
					    NOPERSPECTIVE = 372,
 | 
				
			||||||
    MAT2X3 = 373,
 | 
					    FLAT = 373,
 | 
				
			||||||
    MAT2X4 = 374,
 | 
					    SMOOTH = 374,
 | 
				
			||||||
    MAT3X2 = 375,
 | 
					    LAYOUT = 375,
 | 
				
			||||||
    MAT3X3 = 376,
 | 
					    EXPLICITINTERPAMD = 376,
 | 
				
			||||||
    MAT3X4 = 377,
 | 
					    MAT2X2 = 377,
 | 
				
			||||||
    MAT4X2 = 378,
 | 
					    MAT2X3 = 378,
 | 
				
			||||||
    MAT4X3 = 379,
 | 
					    MAT2X4 = 379,
 | 
				
			||||||
    MAT4X4 = 380,
 | 
					    MAT3X2 = 380,
 | 
				
			||||||
    DMAT2X2 = 381,
 | 
					    MAT3X3 = 381,
 | 
				
			||||||
    DMAT2X3 = 382,
 | 
					    MAT3X4 = 382,
 | 
				
			||||||
    DMAT2X4 = 383,
 | 
					    MAT4X2 = 383,
 | 
				
			||||||
    DMAT3X2 = 384,
 | 
					    MAT4X3 = 384,
 | 
				
			||||||
    DMAT3X3 = 385,
 | 
					    MAT4X4 = 385,
 | 
				
			||||||
    DMAT3X4 = 386,
 | 
					    DMAT2X2 = 386,
 | 
				
			||||||
    DMAT4X2 = 387,
 | 
					    DMAT2X3 = 387,
 | 
				
			||||||
    DMAT4X3 = 388,
 | 
					    DMAT2X4 = 388,
 | 
				
			||||||
    DMAT4X4 = 389,
 | 
					    DMAT3X2 = 389,
 | 
				
			||||||
    F16MAT2X2 = 390,
 | 
					    DMAT3X3 = 390,
 | 
				
			||||||
    F16MAT2X3 = 391,
 | 
					    DMAT3X4 = 391,
 | 
				
			||||||
    F16MAT2X4 = 392,
 | 
					    DMAT4X2 = 392,
 | 
				
			||||||
    F16MAT3X2 = 393,
 | 
					    DMAT4X3 = 393,
 | 
				
			||||||
    F16MAT3X3 = 394,
 | 
					    DMAT4X4 = 394,
 | 
				
			||||||
    F16MAT3X4 = 395,
 | 
					    F16MAT2X2 = 395,
 | 
				
			||||||
    F16MAT4X2 = 396,
 | 
					    F16MAT2X3 = 396,
 | 
				
			||||||
    F16MAT4X3 = 397,
 | 
					    F16MAT2X4 = 397,
 | 
				
			||||||
    F16MAT4X4 = 398,
 | 
					    F16MAT3X2 = 398,
 | 
				
			||||||
    F32MAT2X2 = 399,
 | 
					    F16MAT3X3 = 399,
 | 
				
			||||||
    F32MAT2X3 = 400,
 | 
					    F16MAT3X4 = 400,
 | 
				
			||||||
    F32MAT2X4 = 401,
 | 
					    F16MAT4X2 = 401,
 | 
				
			||||||
    F32MAT3X2 = 402,
 | 
					    F16MAT4X3 = 402,
 | 
				
			||||||
    F32MAT3X3 = 403,
 | 
					    F16MAT4X4 = 403,
 | 
				
			||||||
    F32MAT3X4 = 404,
 | 
					    F32MAT2X2 = 404,
 | 
				
			||||||
    F32MAT4X2 = 405,
 | 
					    F32MAT2X3 = 405,
 | 
				
			||||||
    F32MAT4X3 = 406,
 | 
					    F32MAT2X4 = 406,
 | 
				
			||||||
    F32MAT4X4 = 407,
 | 
					    F32MAT3X2 = 407,
 | 
				
			||||||
    F64MAT2X2 = 408,
 | 
					    F32MAT3X3 = 408,
 | 
				
			||||||
    F64MAT2X3 = 409,
 | 
					    F32MAT3X4 = 409,
 | 
				
			||||||
    F64MAT2X4 = 410,
 | 
					    F32MAT4X2 = 410,
 | 
				
			||||||
    F64MAT3X2 = 411,
 | 
					    F32MAT4X3 = 411,
 | 
				
			||||||
    F64MAT3X3 = 412,
 | 
					    F32MAT4X4 = 412,
 | 
				
			||||||
    F64MAT3X4 = 413,
 | 
					    F64MAT2X2 = 413,
 | 
				
			||||||
    F64MAT4X2 = 414,
 | 
					    F64MAT2X3 = 414,
 | 
				
			||||||
    F64MAT4X3 = 415,
 | 
					    F64MAT2X4 = 415,
 | 
				
			||||||
    F64MAT4X4 = 416,
 | 
					    F64MAT3X2 = 416,
 | 
				
			||||||
    ATOMIC_UINT = 417,
 | 
					    F64MAT3X3 = 417,
 | 
				
			||||||
    SAMPLER1D = 418,
 | 
					    F64MAT3X4 = 418,
 | 
				
			||||||
    SAMPLER2D = 419,
 | 
					    F64MAT4X2 = 419,
 | 
				
			||||||
    SAMPLER3D = 420,
 | 
					    F64MAT4X3 = 420,
 | 
				
			||||||
    SAMPLERCUBE = 421,
 | 
					    F64MAT4X4 = 421,
 | 
				
			||||||
    SAMPLER1DSHADOW = 422,
 | 
					    ATOMIC_UINT = 422,
 | 
				
			||||||
    SAMPLER2DSHADOW = 423,
 | 
					    SAMPLER1D = 423,
 | 
				
			||||||
    SAMPLERCUBESHADOW = 424,
 | 
					    SAMPLER2D = 424,
 | 
				
			||||||
    SAMPLER1DARRAY = 425,
 | 
					    SAMPLER3D = 425,
 | 
				
			||||||
    SAMPLER2DARRAY = 426,
 | 
					    SAMPLERCUBE = 426,
 | 
				
			||||||
    SAMPLER1DARRAYSHADOW = 427,
 | 
					    SAMPLER1DSHADOW = 427,
 | 
				
			||||||
    SAMPLER2DARRAYSHADOW = 428,
 | 
					    SAMPLER2DSHADOW = 428,
 | 
				
			||||||
    ISAMPLER1D = 429,
 | 
					    SAMPLERCUBESHADOW = 429,
 | 
				
			||||||
    ISAMPLER2D = 430,
 | 
					    SAMPLER1DARRAY = 430,
 | 
				
			||||||
    ISAMPLER3D = 431,
 | 
					    SAMPLER2DARRAY = 431,
 | 
				
			||||||
    ISAMPLERCUBE = 432,
 | 
					    SAMPLER1DARRAYSHADOW = 432,
 | 
				
			||||||
    ISAMPLER1DARRAY = 433,
 | 
					    SAMPLER2DARRAYSHADOW = 433,
 | 
				
			||||||
    ISAMPLER2DARRAY = 434,
 | 
					    ISAMPLER1D = 434,
 | 
				
			||||||
    USAMPLER1D = 435,
 | 
					    ISAMPLER2D = 435,
 | 
				
			||||||
    USAMPLER2D = 436,
 | 
					    ISAMPLER3D = 436,
 | 
				
			||||||
    USAMPLER3D = 437,
 | 
					    ISAMPLERCUBE = 437,
 | 
				
			||||||
    USAMPLERCUBE = 438,
 | 
					    ISAMPLER1DARRAY = 438,
 | 
				
			||||||
    USAMPLER1DARRAY = 439,
 | 
					    ISAMPLER2DARRAY = 439,
 | 
				
			||||||
    USAMPLER2DARRAY = 440,
 | 
					    USAMPLER1D = 440,
 | 
				
			||||||
    SAMPLER2DRECT = 441,
 | 
					    USAMPLER2D = 441,
 | 
				
			||||||
    SAMPLER2DRECTSHADOW = 442,
 | 
					    USAMPLER3D = 442,
 | 
				
			||||||
    ISAMPLER2DRECT = 443,
 | 
					    USAMPLERCUBE = 443,
 | 
				
			||||||
    USAMPLER2DRECT = 444,
 | 
					    USAMPLER1DARRAY = 444,
 | 
				
			||||||
    SAMPLERBUFFER = 445,
 | 
					    USAMPLER2DARRAY = 445,
 | 
				
			||||||
    ISAMPLERBUFFER = 446,
 | 
					    SAMPLER2DRECT = 446,
 | 
				
			||||||
    USAMPLERBUFFER = 447,
 | 
					    SAMPLER2DRECTSHADOW = 447,
 | 
				
			||||||
    SAMPLERCUBEARRAY = 448,
 | 
					    ISAMPLER2DRECT = 448,
 | 
				
			||||||
    SAMPLERCUBEARRAYSHADOW = 449,
 | 
					    USAMPLER2DRECT = 449,
 | 
				
			||||||
    ISAMPLERCUBEARRAY = 450,
 | 
					    SAMPLERBUFFER = 450,
 | 
				
			||||||
    USAMPLERCUBEARRAY = 451,
 | 
					    ISAMPLERBUFFER = 451,
 | 
				
			||||||
    SAMPLER2DMS = 452,
 | 
					    USAMPLERBUFFER = 452,
 | 
				
			||||||
    ISAMPLER2DMS = 453,
 | 
					    SAMPLERCUBEARRAY = 453,
 | 
				
			||||||
    USAMPLER2DMS = 454,
 | 
					    SAMPLERCUBEARRAYSHADOW = 454,
 | 
				
			||||||
    SAMPLER2DMSARRAY = 455,
 | 
					    ISAMPLERCUBEARRAY = 455,
 | 
				
			||||||
    ISAMPLER2DMSARRAY = 456,
 | 
					    USAMPLERCUBEARRAY = 456,
 | 
				
			||||||
    USAMPLER2DMSARRAY = 457,
 | 
					    SAMPLER2DMS = 457,
 | 
				
			||||||
    SAMPLEREXTERNALOES = 458,
 | 
					    ISAMPLER2DMS = 458,
 | 
				
			||||||
    F16SAMPLER1D = 459,
 | 
					    USAMPLER2DMS = 459,
 | 
				
			||||||
    F16SAMPLER2D = 460,
 | 
					    SAMPLER2DMSARRAY = 460,
 | 
				
			||||||
    F16SAMPLER3D = 461,
 | 
					    ISAMPLER2DMSARRAY = 461,
 | 
				
			||||||
    F16SAMPLER2DRECT = 462,
 | 
					    USAMPLER2DMSARRAY = 462,
 | 
				
			||||||
    F16SAMPLERCUBE = 463,
 | 
					    SAMPLEREXTERNALOES = 463,
 | 
				
			||||||
    F16SAMPLER1DARRAY = 464,
 | 
					    F16SAMPLER1D = 464,
 | 
				
			||||||
    F16SAMPLER2DARRAY = 465,
 | 
					    F16SAMPLER2D = 465,
 | 
				
			||||||
    F16SAMPLERCUBEARRAY = 466,
 | 
					    F16SAMPLER3D = 466,
 | 
				
			||||||
    F16SAMPLERBUFFER = 467,
 | 
					    F16SAMPLER2DRECT = 467,
 | 
				
			||||||
    F16SAMPLER2DMS = 468,
 | 
					    F16SAMPLERCUBE = 468,
 | 
				
			||||||
    F16SAMPLER2DMSARRAY = 469,
 | 
					    F16SAMPLER1DARRAY = 469,
 | 
				
			||||||
    F16SAMPLER1DSHADOW = 470,
 | 
					    F16SAMPLER2DARRAY = 470,
 | 
				
			||||||
    F16SAMPLER2DSHADOW = 471,
 | 
					    F16SAMPLERCUBEARRAY = 471,
 | 
				
			||||||
    F16SAMPLER1DARRAYSHADOW = 472,
 | 
					    F16SAMPLERBUFFER = 472,
 | 
				
			||||||
    F16SAMPLER2DARRAYSHADOW = 473,
 | 
					    F16SAMPLER2DMS = 473,
 | 
				
			||||||
    F16SAMPLER2DRECTSHADOW = 474,
 | 
					    F16SAMPLER2DMSARRAY = 474,
 | 
				
			||||||
    F16SAMPLERCUBESHADOW = 475,
 | 
					    F16SAMPLER1DSHADOW = 475,
 | 
				
			||||||
    F16SAMPLERCUBEARRAYSHADOW = 476,
 | 
					    F16SAMPLER2DSHADOW = 476,
 | 
				
			||||||
    SAMPLER = 477,
 | 
					    F16SAMPLER1DARRAYSHADOW = 477,
 | 
				
			||||||
    SAMPLERSHADOW = 478,
 | 
					    F16SAMPLER2DARRAYSHADOW = 478,
 | 
				
			||||||
    TEXTURE1D = 479,
 | 
					    F16SAMPLER2DRECTSHADOW = 479,
 | 
				
			||||||
    TEXTURE2D = 480,
 | 
					    F16SAMPLERCUBESHADOW = 480,
 | 
				
			||||||
    TEXTURE3D = 481,
 | 
					    F16SAMPLERCUBEARRAYSHADOW = 481,
 | 
				
			||||||
    TEXTURECUBE = 482,
 | 
					    SAMPLER = 482,
 | 
				
			||||||
    TEXTURE1DARRAY = 483,
 | 
					    SAMPLERSHADOW = 483,
 | 
				
			||||||
    TEXTURE2DARRAY = 484,
 | 
					    TEXTURE1D = 484,
 | 
				
			||||||
    ITEXTURE1D = 485,
 | 
					    TEXTURE2D = 485,
 | 
				
			||||||
    ITEXTURE2D = 486,
 | 
					    TEXTURE3D = 486,
 | 
				
			||||||
    ITEXTURE3D = 487,
 | 
					    TEXTURECUBE = 487,
 | 
				
			||||||
    ITEXTURECUBE = 488,
 | 
					    TEXTURE1DARRAY = 488,
 | 
				
			||||||
    ITEXTURE1DARRAY = 489,
 | 
					    TEXTURE2DARRAY = 489,
 | 
				
			||||||
    ITEXTURE2DARRAY = 490,
 | 
					    ITEXTURE1D = 490,
 | 
				
			||||||
    UTEXTURE1D = 491,
 | 
					    ITEXTURE2D = 491,
 | 
				
			||||||
    UTEXTURE2D = 492,
 | 
					    ITEXTURE3D = 492,
 | 
				
			||||||
    UTEXTURE3D = 493,
 | 
					    ITEXTURECUBE = 493,
 | 
				
			||||||
    UTEXTURECUBE = 494,
 | 
					    ITEXTURE1DARRAY = 494,
 | 
				
			||||||
    UTEXTURE1DARRAY = 495,
 | 
					    ITEXTURE2DARRAY = 495,
 | 
				
			||||||
    UTEXTURE2DARRAY = 496,
 | 
					    UTEXTURE1D = 496,
 | 
				
			||||||
    TEXTURE2DRECT = 497,
 | 
					    UTEXTURE2D = 497,
 | 
				
			||||||
    ITEXTURE2DRECT = 498,
 | 
					    UTEXTURE3D = 498,
 | 
				
			||||||
    UTEXTURE2DRECT = 499,
 | 
					    UTEXTURECUBE = 499,
 | 
				
			||||||
    TEXTUREBUFFER = 500,
 | 
					    UTEXTURE1DARRAY = 500,
 | 
				
			||||||
    ITEXTUREBUFFER = 501,
 | 
					    UTEXTURE2DARRAY = 501,
 | 
				
			||||||
    UTEXTUREBUFFER = 502,
 | 
					    TEXTURE2DRECT = 502,
 | 
				
			||||||
    TEXTURECUBEARRAY = 503,
 | 
					    ITEXTURE2DRECT = 503,
 | 
				
			||||||
    ITEXTURECUBEARRAY = 504,
 | 
					    UTEXTURE2DRECT = 504,
 | 
				
			||||||
    UTEXTURECUBEARRAY = 505,
 | 
					    TEXTUREBUFFER = 505,
 | 
				
			||||||
    TEXTURE2DMS = 506,
 | 
					    ITEXTUREBUFFER = 506,
 | 
				
			||||||
    ITEXTURE2DMS = 507,
 | 
					    UTEXTUREBUFFER = 507,
 | 
				
			||||||
    UTEXTURE2DMS = 508,
 | 
					    TEXTURECUBEARRAY = 508,
 | 
				
			||||||
    TEXTURE2DMSARRAY = 509,
 | 
					    ITEXTURECUBEARRAY = 509,
 | 
				
			||||||
    ITEXTURE2DMSARRAY = 510,
 | 
					    UTEXTURECUBEARRAY = 510,
 | 
				
			||||||
    UTEXTURE2DMSARRAY = 511,
 | 
					    TEXTURE2DMS = 511,
 | 
				
			||||||
    F16TEXTURE1D = 512,
 | 
					    ITEXTURE2DMS = 512,
 | 
				
			||||||
    F16TEXTURE2D = 513,
 | 
					    UTEXTURE2DMS = 513,
 | 
				
			||||||
    F16TEXTURE3D = 514,
 | 
					    TEXTURE2DMSARRAY = 514,
 | 
				
			||||||
    F16TEXTURE2DRECT = 515,
 | 
					    ITEXTURE2DMSARRAY = 515,
 | 
				
			||||||
    F16TEXTURECUBE = 516,
 | 
					    UTEXTURE2DMSARRAY = 516,
 | 
				
			||||||
    F16TEXTURE1DARRAY = 517,
 | 
					    F16TEXTURE1D = 517,
 | 
				
			||||||
    F16TEXTURE2DARRAY = 518,
 | 
					    F16TEXTURE2D = 518,
 | 
				
			||||||
    F16TEXTURECUBEARRAY = 519,
 | 
					    F16TEXTURE3D = 519,
 | 
				
			||||||
    F16TEXTUREBUFFER = 520,
 | 
					    F16TEXTURE2DRECT = 520,
 | 
				
			||||||
    F16TEXTURE2DMS = 521,
 | 
					    F16TEXTURECUBE = 521,
 | 
				
			||||||
    F16TEXTURE2DMSARRAY = 522,
 | 
					    F16TEXTURE1DARRAY = 522,
 | 
				
			||||||
    SUBPASSINPUT = 523,
 | 
					    F16TEXTURE2DARRAY = 523,
 | 
				
			||||||
    SUBPASSINPUTMS = 524,
 | 
					    F16TEXTURECUBEARRAY = 524,
 | 
				
			||||||
    ISUBPASSINPUT = 525,
 | 
					    F16TEXTUREBUFFER = 525,
 | 
				
			||||||
    ISUBPASSINPUTMS = 526,
 | 
					    F16TEXTURE2DMS = 526,
 | 
				
			||||||
    USUBPASSINPUT = 527,
 | 
					    F16TEXTURE2DMSARRAY = 527,
 | 
				
			||||||
    USUBPASSINPUTMS = 528,
 | 
					    SUBPASSINPUT = 528,
 | 
				
			||||||
    F16SUBPASSINPUT = 529,
 | 
					    SUBPASSINPUTMS = 529,
 | 
				
			||||||
    F16SUBPASSINPUTMS = 530,
 | 
					    ISUBPASSINPUT = 530,
 | 
				
			||||||
    IMAGE1D = 531,
 | 
					    ISUBPASSINPUTMS = 531,
 | 
				
			||||||
    IIMAGE1D = 532,
 | 
					    USUBPASSINPUT = 532,
 | 
				
			||||||
    UIMAGE1D = 533,
 | 
					    USUBPASSINPUTMS = 533,
 | 
				
			||||||
    IMAGE2D = 534,
 | 
					    F16SUBPASSINPUT = 534,
 | 
				
			||||||
    IIMAGE2D = 535,
 | 
					    F16SUBPASSINPUTMS = 535,
 | 
				
			||||||
    UIMAGE2D = 536,
 | 
					    IMAGE1D = 536,
 | 
				
			||||||
    IMAGE3D = 537,
 | 
					    IIMAGE1D = 537,
 | 
				
			||||||
    IIMAGE3D = 538,
 | 
					    UIMAGE1D = 538,
 | 
				
			||||||
    UIMAGE3D = 539,
 | 
					    IMAGE2D = 539,
 | 
				
			||||||
    IMAGE2DRECT = 540,
 | 
					    IIMAGE2D = 540,
 | 
				
			||||||
    IIMAGE2DRECT = 541,
 | 
					    UIMAGE2D = 541,
 | 
				
			||||||
    UIMAGE2DRECT = 542,
 | 
					    IMAGE3D = 542,
 | 
				
			||||||
    IMAGECUBE = 543,
 | 
					    IIMAGE3D = 543,
 | 
				
			||||||
    IIMAGECUBE = 544,
 | 
					    UIMAGE3D = 544,
 | 
				
			||||||
    UIMAGECUBE = 545,
 | 
					    IMAGE2DRECT = 545,
 | 
				
			||||||
    IMAGEBUFFER = 546,
 | 
					    IIMAGE2DRECT = 546,
 | 
				
			||||||
    IIMAGEBUFFER = 547,
 | 
					    UIMAGE2DRECT = 547,
 | 
				
			||||||
    UIMAGEBUFFER = 548,
 | 
					    IMAGECUBE = 548,
 | 
				
			||||||
    IMAGE1DARRAY = 549,
 | 
					    IIMAGECUBE = 549,
 | 
				
			||||||
    IIMAGE1DARRAY = 550,
 | 
					    UIMAGECUBE = 550,
 | 
				
			||||||
    UIMAGE1DARRAY = 551,
 | 
					    IMAGEBUFFER = 551,
 | 
				
			||||||
    IMAGE2DARRAY = 552,
 | 
					    IIMAGEBUFFER = 552,
 | 
				
			||||||
    IIMAGE2DARRAY = 553,
 | 
					    UIMAGEBUFFER = 553,
 | 
				
			||||||
    UIMAGE2DARRAY = 554,
 | 
					    IMAGE1DARRAY = 554,
 | 
				
			||||||
    IMAGECUBEARRAY = 555,
 | 
					    IIMAGE1DARRAY = 555,
 | 
				
			||||||
    IIMAGECUBEARRAY = 556,
 | 
					    UIMAGE1DARRAY = 556,
 | 
				
			||||||
    UIMAGECUBEARRAY = 557,
 | 
					    IMAGE2DARRAY = 557,
 | 
				
			||||||
    IMAGE2DMS = 558,
 | 
					    IIMAGE2DARRAY = 558,
 | 
				
			||||||
    IIMAGE2DMS = 559,
 | 
					    UIMAGE2DARRAY = 559,
 | 
				
			||||||
    UIMAGE2DMS = 560,
 | 
					    IMAGECUBEARRAY = 560,
 | 
				
			||||||
    IMAGE2DMSARRAY = 561,
 | 
					    IIMAGECUBEARRAY = 561,
 | 
				
			||||||
    IIMAGE2DMSARRAY = 562,
 | 
					    UIMAGECUBEARRAY = 562,
 | 
				
			||||||
    UIMAGE2DMSARRAY = 563,
 | 
					    IMAGE2DMS = 563,
 | 
				
			||||||
    F16IMAGE1D = 564,
 | 
					    IIMAGE2DMS = 564,
 | 
				
			||||||
    F16IMAGE2D = 565,
 | 
					    UIMAGE2DMS = 565,
 | 
				
			||||||
    F16IMAGE3D = 566,
 | 
					    IMAGE2DMSARRAY = 566,
 | 
				
			||||||
    F16IMAGE2DRECT = 567,
 | 
					    IIMAGE2DMSARRAY = 567,
 | 
				
			||||||
    F16IMAGECUBE = 568,
 | 
					    UIMAGE2DMSARRAY = 568,
 | 
				
			||||||
    F16IMAGE1DARRAY = 569,
 | 
					    F16IMAGE1D = 569,
 | 
				
			||||||
    F16IMAGE2DARRAY = 570,
 | 
					    F16IMAGE2D = 570,
 | 
				
			||||||
    F16IMAGECUBEARRAY = 571,
 | 
					    F16IMAGE3D = 571,
 | 
				
			||||||
    F16IMAGEBUFFER = 572,
 | 
					    F16IMAGE2DRECT = 572,
 | 
				
			||||||
    F16IMAGE2DMS = 573,
 | 
					    F16IMAGECUBE = 573,
 | 
				
			||||||
    F16IMAGE2DMSARRAY = 574,
 | 
					    F16IMAGE1DARRAY = 574,
 | 
				
			||||||
    STRUCT = 575,
 | 
					    F16IMAGE2DARRAY = 575,
 | 
				
			||||||
    VOID = 576,
 | 
					    F16IMAGECUBEARRAY = 576,
 | 
				
			||||||
    WHILE = 577,
 | 
					    F16IMAGEBUFFER = 577,
 | 
				
			||||||
    IDENTIFIER = 578,
 | 
					    F16IMAGE2DMS = 578,
 | 
				
			||||||
    TYPE_NAME = 579,
 | 
					    F16IMAGE2DMSARRAY = 579,
 | 
				
			||||||
    FLOATCONSTANT = 580,
 | 
					    STRUCT = 580,
 | 
				
			||||||
    DOUBLECONSTANT = 581,
 | 
					    VOID = 581,
 | 
				
			||||||
    INT16CONSTANT = 582,
 | 
					    WHILE = 582,
 | 
				
			||||||
    UINT16CONSTANT = 583,
 | 
					    IDENTIFIER = 583,
 | 
				
			||||||
    INT32CONSTANT = 584,
 | 
					    TYPE_NAME = 584,
 | 
				
			||||||
    UINT32CONSTANT = 585,
 | 
					    FLOATCONSTANT = 585,
 | 
				
			||||||
    INTCONSTANT = 586,
 | 
					    DOUBLECONSTANT = 586,
 | 
				
			||||||
    UINTCONSTANT = 587,
 | 
					    INT16CONSTANT = 587,
 | 
				
			||||||
    INT64CONSTANT = 588,
 | 
					    UINT16CONSTANT = 588,
 | 
				
			||||||
    UINT64CONSTANT = 589,
 | 
					    INT32CONSTANT = 589,
 | 
				
			||||||
    BOOLCONSTANT = 590,
 | 
					    UINT32CONSTANT = 590,
 | 
				
			||||||
    FLOAT16CONSTANT = 591,
 | 
					    INTCONSTANT = 591,
 | 
				
			||||||
    LEFT_OP = 592,
 | 
					    UINTCONSTANT = 592,
 | 
				
			||||||
    RIGHT_OP = 593,
 | 
					    INT64CONSTANT = 593,
 | 
				
			||||||
    INC_OP = 594,
 | 
					    UINT64CONSTANT = 594,
 | 
				
			||||||
    DEC_OP = 595,
 | 
					    BOOLCONSTANT = 595,
 | 
				
			||||||
    LE_OP = 596,
 | 
					    FLOAT16CONSTANT = 596,
 | 
				
			||||||
    GE_OP = 597,
 | 
					    LEFT_OP = 597,
 | 
				
			||||||
    EQ_OP = 598,
 | 
					    RIGHT_OP = 598,
 | 
				
			||||||
    NE_OP = 599,
 | 
					    INC_OP = 599,
 | 
				
			||||||
    AND_OP = 600,
 | 
					    DEC_OP = 600,
 | 
				
			||||||
    OR_OP = 601,
 | 
					    LE_OP = 601,
 | 
				
			||||||
    XOR_OP = 602,
 | 
					    GE_OP = 602,
 | 
				
			||||||
    MUL_ASSIGN = 603,
 | 
					    EQ_OP = 603,
 | 
				
			||||||
    DIV_ASSIGN = 604,
 | 
					    NE_OP = 604,
 | 
				
			||||||
    ADD_ASSIGN = 605,
 | 
					    AND_OP = 605,
 | 
				
			||||||
    MOD_ASSIGN = 606,
 | 
					    OR_OP = 606,
 | 
				
			||||||
    LEFT_ASSIGN = 607,
 | 
					    XOR_OP = 607,
 | 
				
			||||||
    RIGHT_ASSIGN = 608,
 | 
					    MUL_ASSIGN = 608,
 | 
				
			||||||
    AND_ASSIGN = 609,
 | 
					    DIV_ASSIGN = 609,
 | 
				
			||||||
    XOR_ASSIGN = 610,
 | 
					    ADD_ASSIGN = 610,
 | 
				
			||||||
    OR_ASSIGN = 611,
 | 
					    MOD_ASSIGN = 611,
 | 
				
			||||||
    SUB_ASSIGN = 612,
 | 
					    LEFT_ASSIGN = 612,
 | 
				
			||||||
    LEFT_PAREN = 613,
 | 
					    RIGHT_ASSIGN = 613,
 | 
				
			||||||
    RIGHT_PAREN = 614,
 | 
					    AND_ASSIGN = 614,
 | 
				
			||||||
    LEFT_BRACKET = 615,
 | 
					    XOR_ASSIGN = 615,
 | 
				
			||||||
    RIGHT_BRACKET = 616,
 | 
					    OR_ASSIGN = 616,
 | 
				
			||||||
    LEFT_BRACE = 617,
 | 
					    SUB_ASSIGN = 617,
 | 
				
			||||||
    RIGHT_BRACE = 618,
 | 
					    LEFT_PAREN = 618,
 | 
				
			||||||
    DOT = 619,
 | 
					    RIGHT_PAREN = 619,
 | 
				
			||||||
    COMMA = 620,
 | 
					    LEFT_BRACKET = 620,
 | 
				
			||||||
    COLON = 621,
 | 
					    RIGHT_BRACKET = 621,
 | 
				
			||||||
    EQUAL = 622,
 | 
					    LEFT_BRACE = 622,
 | 
				
			||||||
    SEMICOLON = 623,
 | 
					    RIGHT_BRACE = 623,
 | 
				
			||||||
    BANG = 624,
 | 
					    DOT = 624,
 | 
				
			||||||
    DASH = 625,
 | 
					    COMMA = 625,
 | 
				
			||||||
    TILDE = 626,
 | 
					    COLON = 626,
 | 
				
			||||||
    PLUS = 627,
 | 
					    EQUAL = 627,
 | 
				
			||||||
    STAR = 628,
 | 
					    SEMICOLON = 628,
 | 
				
			||||||
    SLASH = 629,
 | 
					    BANG = 629,
 | 
				
			||||||
    PERCENT = 630,
 | 
					    DASH = 630,
 | 
				
			||||||
    LEFT_ANGLE = 631,
 | 
					    TILDE = 631,
 | 
				
			||||||
    RIGHT_ANGLE = 632,
 | 
					    PLUS = 632,
 | 
				
			||||||
    VERTICAL_BAR = 633,
 | 
					    STAR = 633,
 | 
				
			||||||
    CARET = 634,
 | 
					    SLASH = 634,
 | 
				
			||||||
    AMPERSAND = 635,
 | 
					    PERCENT = 635,
 | 
				
			||||||
    QUESTION = 636,
 | 
					    LEFT_ANGLE = 636,
 | 
				
			||||||
    INVARIANT = 637,
 | 
					    RIGHT_ANGLE = 637,
 | 
				
			||||||
    PRECISE = 638,
 | 
					    VERTICAL_BAR = 638,
 | 
				
			||||||
    HIGH_PRECISION = 639,
 | 
					    CARET = 639,
 | 
				
			||||||
    MEDIUM_PRECISION = 640,
 | 
					    AMPERSAND = 640,
 | 
				
			||||||
    LOW_PRECISION = 641,
 | 
					    QUESTION = 641,
 | 
				
			||||||
    PRECISION = 642,
 | 
					    INVARIANT = 642,
 | 
				
			||||||
    PACKED = 643,
 | 
					    PRECISE = 643,
 | 
				
			||||||
    RESOURCE = 644,
 | 
					    HIGH_PRECISION = 644,
 | 
				
			||||||
    SUPERP = 645
 | 
					    MEDIUM_PRECISION = 645,
 | 
				
			||||||
 | 
					    LOW_PRECISION = 646,
 | 
				
			||||||
 | 
					    PRECISION = 647,
 | 
				
			||||||
 | 
					    PACKED = 648,
 | 
				
			||||||
 | 
					    RESOURCE = 649,
 | 
				
			||||||
 | 
					    SUPERP = 650
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Value type.  */
 | 
					/* Value type.  */
 | 
				
			||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 | 
					#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 | 
				
			||||||
typedef union YYSTYPE YYSTYPE;
 | 
					
 | 
				
			||||||
union YYSTYPE
 | 
					union YYSTYPE
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909  */
 | 
					#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909  */
 | 
				
			||||||
@ -476,8 +481,10 @@ union YYSTYPE
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
    } interm;
 | 
					    } interm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#line 480 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909  */
 | 
					#line 485 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909  */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union YYSTYPE YYSTYPE;
 | 
				
			||||||
# define YYSTYPE_IS_TRIVIAL 1
 | 
					# define YYSTYPE_IS_TRIVIAL 1
 | 
				
			||||||
# define YYSTYPE_IS_DECLARED 1
 | 
					# define YYSTYPE_IS_DECLARED 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -871,6 +871,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 | 
				
			|||||||
    case EOpAtomicXor:                  out.debug << "AtomicXor";             break;
 | 
					    case EOpAtomicXor:                  out.debug << "AtomicXor";             break;
 | 
				
			||||||
    case EOpAtomicExchange:             out.debug << "AtomicExchange";        break;
 | 
					    case EOpAtomicExchange:             out.debug << "AtomicExchange";        break;
 | 
				
			||||||
    case EOpAtomicCompSwap:             out.debug << "AtomicCompSwap";        break;
 | 
					    case EOpAtomicCompSwap:             out.debug << "AtomicCompSwap";        break;
 | 
				
			||||||
 | 
					    case EOpAtomicLoad:                 out.debug << "AtomicLoad";            break;
 | 
				
			||||||
 | 
					    case EOpAtomicStore:                out.debug << "AtomicStore";           break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case EOpAtomicCounterAdd:           out.debug << "AtomicCounterAdd";      break;
 | 
					    case EOpAtomicCounterAdd:           out.debug << "AtomicCounterAdd";      break;
 | 
				
			||||||
    case EOpAtomicCounterSubtract:      out.debug << "AtomicCounterSubtract"; break;
 | 
					    case EOpAtomicCounterSubtract:      out.debug << "AtomicCounterSubtract"; break;
 | 
				
			||||||
@ -894,6 +896,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 | 
				
			|||||||
    case EOpImageAtomicXor:             out.debug << "imageAtomicXor";        break;
 | 
					    case EOpImageAtomicXor:             out.debug << "imageAtomicXor";        break;
 | 
				
			||||||
    case EOpImageAtomicExchange:        out.debug << "imageAtomicExchange";   break;
 | 
					    case EOpImageAtomicExchange:        out.debug << "imageAtomicExchange";   break;
 | 
				
			||||||
    case EOpImageAtomicCompSwap:        out.debug << "imageAtomicCompSwap";   break;
 | 
					    case EOpImageAtomicCompSwap:        out.debug << "imageAtomicCompSwap";   break;
 | 
				
			||||||
 | 
					    case EOpImageAtomicLoad:            out.debug << "imageAtomicLoad";       break;
 | 
				
			||||||
 | 
					    case EOpImageAtomicStore:           out.debug << "imageAtomicStore";      break;
 | 
				
			||||||
#ifdef AMD_EXTENSIONS
 | 
					#ifdef AMD_EXTENSIONS
 | 
				
			||||||
    case EOpImageLoadLod:               out.debug << "imageLoadLod";          break;
 | 
					    case EOpImageLoadLod:               out.debug << "imageLoadLod";          break;
 | 
				
			||||||
    case EOpImageStoreLod:              out.debug << "imageStoreLod";         break;
 | 
					    case EOpImageStoreLod:              out.debug << "imageStoreLod";         break;
 | 
				
			||||||
 | 
				
			|||||||
@ -524,11 +524,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Memory...
 | 
					    // Memory...
 | 
				
			||||||
    if (symbol.getQualifier().coherent  != unitSymbol.getQualifier().coherent ||
 | 
					    if (symbol.getQualifier().coherent          != unitSymbol.getQualifier().coherent ||
 | 
				
			||||||
        symbol.getQualifier().volatil   != unitSymbol.getQualifier().volatil ||
 | 
					        symbol.getQualifier().devicecoherent    != unitSymbol.getQualifier().devicecoherent ||
 | 
				
			||||||
        symbol.getQualifier().restrict  != unitSymbol.getQualifier().restrict ||
 | 
					        symbol.getQualifier().queuefamilycoherent  != unitSymbol.getQualifier().queuefamilycoherent ||
 | 
				
			||||||
        symbol.getQualifier().readonly  != unitSymbol.getQualifier().readonly ||
 | 
					        symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
 | 
				
			||||||
        symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
 | 
					        symbol.getQualifier().subgroupcoherent  != unitSymbol.getQualifier().subgroupcoherent ||
 | 
				
			||||||
 | 
					        symbol.getQualifier().nonprivate        != unitSymbol.getQualifier().nonprivate ||
 | 
				
			||||||
 | 
					        symbol.getQualifier().volatil           != unitSymbol.getQualifier().volatil ||
 | 
				
			||||||
 | 
					        symbol.getQualifier().restrict          != unitSymbol.getQualifier().restrict ||
 | 
				
			||||||
 | 
					        symbol.getQualifier().readonly          != unitSymbol.getQualifier().readonly ||
 | 
				
			||||||
 | 
					        symbol.getQualifier().writeonly         != unitSymbol.getQualifier().writeonly) {
 | 
				
			||||||
        error(infoSink, "Memory qualifiers must match:");
 | 
					        error(infoSink, "Memory qualifiers must match:");
 | 
				
			||||||
        writeTypeComparison = true;
 | 
					        writeTypeComparison = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -233,6 +233,7 @@ public:
 | 
				
			|||||||
        useUnknownFormat(false),
 | 
					        useUnknownFormat(false),
 | 
				
			||||||
        hlslOffsets(false),
 | 
					        hlslOffsets(false),
 | 
				
			||||||
        useStorageBuffer(false),
 | 
					        useStorageBuffer(false),
 | 
				
			||||||
 | 
					        useVulkanMemoryModel(false),
 | 
				
			||||||
        hlslIoMapping(false),
 | 
					        hlslIoMapping(false),
 | 
				
			||||||
        textureSamplerTransformMode(EShTexSampTransKeep),
 | 
					        textureSamplerTransformMode(EShTexSampTransKeep),
 | 
				
			||||||
        needToLegalize(false),
 | 
					        needToLegalize(false),
 | 
				
			||||||
@ -365,6 +366,12 @@ public:
 | 
				
			|||||||
            processes.addProcess("hlsl-iomap");
 | 
					            processes.addProcess("hlsl-iomap");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bool usingHlslIoMapping() { return hlslIoMapping; }
 | 
					    bool usingHlslIoMapping() { return hlslIoMapping; }
 | 
				
			||||||
 | 
					    void setUseVulkanMemoryModel()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        useVulkanMemoryModel = true;
 | 
				
			||||||
 | 
					        processes.addProcess("use-vulkan-memory-model");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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 {
 | 
				
			||||||
@ -734,6 +741,7 @@ protected:
 | 
				
			|||||||
    bool useUnknownFormat;
 | 
					    bool useUnknownFormat;
 | 
				
			||||||
    bool hlslOffsets;
 | 
					    bool hlslOffsets;
 | 
				
			||||||
    bool useStorageBuffer;
 | 
					    bool useStorageBuffer;
 | 
				
			||||||
 | 
					    bool useVulkanMemoryModel;
 | 
				
			||||||
    bool hlslIoMapping;
 | 
					    bool hlslIoMapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::set<TString> ioAccessed;           // set of names of statically read/written I/O that might need extra checking
 | 
					    std::set<TString> ioAccessed;           // set of names of statically read/written I/O that might need extra checking
 | 
				
			||||||
 | 
				
			|||||||
@ -286,6 +286,8 @@ INSTANTIATE_TEST_CASE_P(
 | 
				
			|||||||
        "spv.matrix.frag",
 | 
					        "spv.matrix.frag",
 | 
				
			||||||
        "spv.matrix2.frag",
 | 
					        "spv.matrix2.frag",
 | 
				
			||||||
        "spv.memoryQualifier.frag",
 | 
					        "spv.memoryQualifier.frag",
 | 
				
			||||||
 | 
					        "spv.memoryScopeSemantics.comp",
 | 
				
			||||||
 | 
					        "spv.memoryScopeSemantics_Error.comp",
 | 
				
			||||||
        "spv.merge-unreachable.frag",
 | 
					        "spv.merge-unreachable.frag",
 | 
				
			||||||
        "spv.multiStruct.comp",
 | 
					        "spv.multiStruct.comp",
 | 
				
			||||||
        "spv.multiStructFuncall.frag",
 | 
					        "spv.multiStructFuncall.frag",
 | 
				
			||||||
 | 
				
			|||||||
@ -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" : "6d27a8350fbc339909834a6ef339c805cb1ab69b"
 | 
					      "commit" : "7600fc0e19c3a99bd3ef2c24515cc508ca1d3cfb"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "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" : "ff684ffc6a35d2a58f0f63108877d0064ea33feb"
 | 
					      "commit" : "dcf23bdabacc3c54b83b1f9367e7a8adb27f8d87"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user