Web: Make switched methods all be non-virtual, more web-dependent code,
authorJohn Kessenich <cepheus@frii.com>
Sun, 11 Aug 2019 13:41:45 +0000 (07:41 -0600)
committerJohn Kessenich <cepheus@frii.com>
Wed, 21 Aug 2019 05:21:56 +0000 (23:21 -0600)
added a few more HLSL flag tests.  This was mostly focused on the SPV generator.
Saves about 17K.

19 files changed:
SPIRV/GlslangToSpv.cpp
SPIRV/SpvBuilder.cpp
SPIRV/SpvBuilder.h
Test/baseResults/hlsl.depthGreater.frag.out
Test/baseResults/hlsl.depthLess.frag.out
Test/baseResults/hlsl.structIoFourWay.frag.out
Test/baseResults/size
Test/baseResults/spv.depthOut.frag.out
glslang/Include/BaseTypes.h
glslang/Include/Types.h
glslang/Include/intermediate.h
glslang/MachineIndependent/ParseContextBase.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/linkValidate.cpp
glslang/MachineIndependent/localintermediate.h
glslang/MachineIndependent/parseVersions.h
glslang/MachineIndependent/reflection.cpp
glslang/Public/ShaderLang.h
gtests/TestFixture.h

index 33c4db4..4a07323 100644 (file)
@@ -87,9 +87,29 @@ private:
 };
 
 struct OpDecorations {
+    public:
+        OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) :
+            precision(precision)
+#ifndef GLSLANG_WEB
+            ,
+            noContraction(noContraction),
+            nonUniform(nonUniform)
+#endif
+        { }
+
     spv::Decoration precision;
-    spv::Decoration noContraction;
-    spv::Decoration nonUniform;
+
+#ifdef GLSLANG_WEB
+        void addNoContraction(spv::Builder&, spv::Id) const { };
+        void addNonUniform(spv::Builder&, spv::Id) const { };
+#else
+        void addNoContraction(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, noContraction); };
+        void addNonUniform(spv::Builder& builder, spv::Id t)  { builder.addDecoration(t, nonUniform); };
+    protected:
+        spv::Decoration noContraction;
+        spv::Decoration nonUniform;
+#endif
+
 };
 
 } // namespace
@@ -359,6 +379,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
 // Translate glslang type to SPIR-V memory decorations.
 void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
 {
+#ifndef GLSLANG_WEB
     if (!useVulkanMemoryModel) {
         if (qualifier.coherent)
             memory.push_back(spv::DecorationCoherent);
@@ -373,6 +394,7 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector
         memory.push_back(spv::DecorationNonWritable);
     if (qualifier.writeonly)
        memory.push_back(spv::DecorationNonReadable);
+#endif
 }
 
 // Translate glslang type to SPIR-V layout decorations.
@@ -456,15 +478,18 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g
 // should be applied.
 spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier)
 {
-    if (qualifier.patch)
-        return spv::DecorationPatch;
-    else if (qualifier.centroid)
+    if (qualifier.centroid)
         return spv::DecorationCentroid;
+#ifndef GLSLANG_WEB
+    else if (qualifier.patch)
+        return spv::DecorationPatch;
     else if (qualifier.sample) {
         builder.addCapability(spv::CapabilitySampleRateShading);
         return spv::DecorationSample;
-    } else
-        return spv::DecorationMax;
+    }
+#endif
+
+    return spv::DecorationMax;
 }
 
 // If glslang type is invariant, return SPIR-V invariant decoration.
@@ -479,29 +504,36 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie
 // If glslang type is noContraction, return SPIR-V NoContraction decoration.
 spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier)
 {
+#ifndef GLSLANG_WEB
     if (qualifier.isNoContraction())
         return spv::DecorationNoContraction;
     else
+#endif
         return spv::DecorationMax;
 }
 
 // If glslang type is nonUniform, return SPIR-V NonUniform decoration.
 spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier)
 {
+#ifndef GLSLANG_WEB
     if (qualifier.isNonUniform()) {
         builder.addExtension("SPV_EXT_descriptor_indexing");
         builder.addCapability(spv::CapabilityShaderNonUniformEXT);
         return spv::DecorationNonUniformEXT;
     } else
+#endif
         return spv::DecorationMax;
 }
 
-spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
+spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(
+    const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 {
-    if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) {
-        return spv::MemoryAccessMaskNone;
-    }
     spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
+
+#ifndef GLSLANG_WEB
+    if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage)
+        return mask;
+
     if (coherentFlags.volatil ||
         coherentFlags.coherent ||
         coherentFlags.devicecoherent ||
@@ -520,15 +552,20 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::B
     if (mask != spv::MemoryAccessMaskNone) {
         builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
     }
+#endif
+
     return mask;
 }
 
-spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
+spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(
+    const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 {
-    if (!glslangIntermediate->usingVulkanMemoryModel()) {
-        return spv::ImageOperandsMaskNone;
-    }
     spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
+
+#ifndef GLSLANG_WEB
+    if (!glslangIntermediate->usingVulkanMemoryModel())
+        return mask;
+
     if (coherentFlags.volatil ||
         coherentFlags.coherent ||
         coherentFlags.devicecoherent ||
@@ -547,12 +584,15 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv:
     if (mask != spv::ImageOperandsMaskNone) {
         builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
     }
+#endif
+
     return mask;
 }
 
 spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type)
 {
-    spv::Builder::AccessChain::CoherentFlags flags;
+    spv::Builder::AccessChain::CoherentFlags flags = {};
+#ifndef GLSLANG_WEB
     flags.coherent = type.getQualifier().coherent;
     flags.devicecoherent = type.getQualifier().devicecoherent;
     flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
@@ -570,12 +610,16 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere
                        flags.coherent ||
                        flags.volatil;
     flags.isImage = type.getBasicType() == glslang::EbtSampler;
+#endif
     return flags;
 }
 
-spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
+spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(
+    const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
 {
-    spv::Scope scope;
+    spv::Scope scope = spv::ScopeMax;
+
+#ifndef GLSLANG_WEB
     if (coherentFlags.volatil || coherentFlags.coherent) {
         // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
         scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
@@ -587,12 +631,12 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::Acce
         scope = spv::ScopeWorkgroup;
     } else if (coherentFlags.subgroupcoherent) {
         scope = spv::ScopeSubgroup;
-    } else {
-        scope = spv::ScopeMax;
     }
     if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
         builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
     }
+#endif
+
     return scope;
 }
 
@@ -979,6 +1023,10 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
 {
     assert(type.getBasicType() == glslang::EbtSampler);
 
+#ifdef GLSLANG_WEB
+    return spv::ImageFormatUnknown;
+#endif
+
     // Check for capabilities
     switch (type.getQualifier().getFormat()) {
     case glslang::ElfRg32f:
@@ -1186,6 +1234,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
 void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
                                                              const glslang::TType& indexType)
 {
+#ifndef GLSLANG_WEB
     if (indexType.getQualifier().isNonUniform()) {
         // deal with an asserted non-uniform index
         // SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration
@@ -1221,6 +1270,7 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
             }
         }
     }
+#endif
 }
 
 // Return whether or not the given type is something that should be tied to a
@@ -1414,6 +1464,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
             builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
         }
 
+        if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
+            builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
+
+#ifndef GLSLANG_WEB
         switch(glslangIntermediate->getDepth()) {
         case glslang::EldGreater:  mode = spv::ExecutionModeDepthGreater; break;
         case glslang::EldLess:     mode = spv::ExecutionModeDepthLess;    break;
@@ -1421,10 +1475,6 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
         }
         if (mode != spv::ExecutionModeMax)
             builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
-
-        if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
-            builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
-
         switch (glslangIntermediate->getInterlockOrdering()) {
         case glslang::EioPixelInterlockOrdered:         mode = spv::ExecutionModePixelInterlockOrderedEXT;          break;
         case glslang::EioPixelInterlockUnordered:       mode = spv::ExecutionModePixelInterlockUnorderedEXT;          break;
@@ -1447,7 +1497,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
             }
             builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
         }
-
+#endif
         break;
 
 #ifndef GLSLANG_WEB
@@ -1670,7 +1720,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
             builder.setAccessChainLValue(id);
     }
 
-#ifndef GLSLANG_WEB
+#ifdef ENABLE_HLSL
     // Process linkage-only nodes for any special additional interface work.
     if (linkageOnly) {
         if (glslangIntermediate->getHlslFunctionality1()) {
@@ -2104,7 +2154,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
     if (result) {
         if (invertedType) {
             result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
-            builder.addDecoration(result, decorations.nonUniform);
+            decorations.addNonUniform(builder, result);
         }
 
         builder.clearAccessChain();
@@ -2696,6 +2746,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         else
             glslangOperands[arg]->traverse(this);
 
+#ifndef GLSLANG_WEB
         if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
             node->getOp() == glslang::EOpCooperativeMatrixStore) {
 
@@ -2738,6 +2789,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                 continue;
             }
         }
+#endif
 
         if (lvalue) {
             operands.push_back(builder.accessChainGetLValue());
@@ -2750,6 +2802,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     }
 
     builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+#ifndef GLSLANG_WEB
     if (node->getOp() == glslang::EOpCooperativeMatrixLoad) {
         std::vector<spv::IdImmediate> idImmOps;
 
@@ -2779,7 +2832,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     } else if (atomic) {
         // Handle all atomics
         result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
-    } else {
+    } else
+#endif
+    {
         // Pass through to generic operations.
         switch (glslangOperands.size()) {
         case 0:
@@ -3155,11 +3210,13 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
         builder.clearAccessChain();
         break;
 
+#ifndef GLSLANG_WEB
     case glslang::EOpDemote:
         builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
         builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
         builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
         break;
+#endif
 
     default:
         assert(0);
@@ -3185,9 +3242,8 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
     spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType())
                                                 : forcedType;
 
-    const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) ||
-                                   node->getType().containsBasicType(glslang::EbtInt16)   ||
-                                   node->getType().containsBasicType(glslang::EbtUint16);
+    const bool contains16BitType = node->getType().contains16BitFloat() ||
+                                   node->getType().contains16BitInt();
     if (contains16BitType) {
         switch (storageClass) {
         case spv::StorageClassInput:
@@ -3195,10 +3251,6 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
             addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageInputOutput16);
             break;
-        case spv::StorageClassPushConstant:
-            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
-            builder.addCapability(spv::CapabilityStoragePushConstant16);
-            break;
         case spv::StorageClassUniform:
             addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             if (node->getType().getQualifier().storage == glslang::EvqBuffer)
@@ -3206,24 +3258,27 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
             else
                 builder.addCapability(spv::CapabilityStorageUniform16);
             break;
+#ifndef GLSLANG_WEB
+        case spv::StorageClassPushConstant:
+            addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+            builder.addCapability(spv::CapabilityStoragePushConstant16);
+            break;
         case spv::StorageClassStorageBuffer:
         case spv::StorageClassPhysicalStorageBufferEXT:
             addPre13Extension(spv::E_SPV_KHR_16bit_storage);
             builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
             break;
+#endif
         default:
-            if (node->getType().containsBasicType(glslang::EbtFloat16))
+            if (node->getType().contains16BitFloat())
                 builder.addCapability(spv::CapabilityFloat16);
-            if (node->getType().containsBasicType(glslang::EbtInt16) ||
-                node->getType().containsBasicType(glslang::EbtUint16))
+            if (node->getType().contains16BitInt())
                 builder.addCapability(spv::CapabilityInt16);
             break;
         }
     }
 
-    const bool contains8BitType = node->getType().containsBasicType(glslang::EbtInt8)   ||
-                                  node->getType().containsBasicType(glslang::EbtUint8);
-    if (contains8BitType) {
+    if (node->getType().contains8BitInt()) {
         if (storageClass == spv::StorageClassPushConstant) {
             builder.addExtension(spv::E_SPV_KHR_8bit_storage);
             builder.addCapability(spv::CapabilityStoragePushConstant8);
@@ -3482,11 +3537,13 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
         if (type.isSizedArray())
             spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
         else {
+#ifndef GLSLANG_WEB
             if (!lastBufferBlockMember) {
                 builder.addExtension("SPV_EXT_descriptor_indexing");
                 builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
             }
             spvType = builder.makeRuntimeArray(spvType);
+#endif
         }
         if (stride > 0)
             builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
@@ -3642,6 +3699,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
         }
         builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
 
+#ifndef GLSLANG_WEB
         if (type.getBasicType() == glslang::EbtBlock &&
             qualifier.storage == glslang::EvqBuffer) {
             // Add memory decorations only to top-level members of shader storage block
@@ -3650,6 +3708,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
             for (unsigned int i = 0; i < memory.size(); ++i)
                 builder.addMemberDecoration(spvType, member, memory[i]);
         }
+#endif
 
         // Location assignment was already completed correctly by the front end,
         // just track whether a member needs to be decorated.
@@ -3687,6 +3746,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
         if (builtIn != spv::BuiltInMax)
             builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
 
+#ifndef GLSLANG_WEB
         // nonuniform
         builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier()));
 
@@ -3696,7 +3756,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
                                         memberQualifier.semanticName);
         }
 
-#ifndef GLSLANG_WEB
         if (builtIn == spv::BuiltInLayer) {
             // SPV_NV_viewport_array2 extension
             if (glslangMember.getQualifier().layoutViewportRelative){
@@ -4176,13 +4235,11 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
             builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str());
 
             const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
-            if (paramType.containsBasicType(glslang::EbtInt8) ||
-                paramType.containsBasicType(glslang::EbtUint8))
+            if (paramType.contains8BitInt())
                 builder.addCapability(spv::CapabilityInt8);
-            if (paramType.containsBasicType(glslang::EbtInt16) ||
-                paramType.containsBasicType(glslang::EbtUint16))
+            if (paramType.contains16BitInt())
                 builder.addCapability(spv::CapabilityInt16);
-            if (paramType.containsBasicType(glslang::EbtFloat16))
+            if (paramType.contains16BitFloat())
                 builder.addCapability(spv::CapabilityFloat16);
         }
     }
@@ -4771,13 +4828,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
     if (cracked.lod) {
         params.lod = arguments[2 + extraArgs];
         ++extraArgs;
-    } else if (glslangIntermediate->getStage() != EShLangFragment
-#ifndef GLSLANG_WEB
-        // NV_compute_shader_derivatives layout qualifiers allow for implicit LODs
-           && !(glslangIntermediate->getStage() == EShLangCompute &&
-                (glslangIntermediate->getLayoutDerivativeModeNone() != glslang::LayoutDerivativeNone))
-#endif
-        ) {
+    } else if (glslangIntermediate->getStage() != EShLangFragment &&
+               !(glslangIntermediate->getStage() == EShLangCompute &&
+                 glslangIntermediate->hasLayoutDerivativeModeNone())) {
         // we need to invent the default lod for an explicit lod instruction for a non-fragment stage
         noImplicitLod = true;
     }
@@ -5192,8 +5245,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
             builder.promoteScalar(decorations.precision, left, right);
 
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        builder.addDecoration(result, decorations.noContraction);
-        builder.addDecoration(result, decorations.nonUniform);
+        decorations.addNoContraction(builder, result);
+        decorations.addNonUniform(builder, result);
         return builder.setPrecision(result, decorations.precision);
     }
 
@@ -5205,7 +5258,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
     if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual)
                          && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
         spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual);
-        builder.addDecoration(result, decorations.nonUniform);
+        decorations.addNonUniform(builder, result);
         return result;
     }
 
@@ -5266,8 +5319,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
 
     if (binOp != spv::OpNop) {
         spv::Id result = builder.createBinOp(binOp, typeId, left, right);
-        builder.addDecoration(result, decorations.noContraction);
-        builder.addDecoration(result, decorations.nonUniform);
+        decorations.addNoContraction(builder, result);
+        decorations.addNonUniform(builder, result);
         return builder.setPrecision(result, decorations.precision);
     }
 
@@ -5331,8 +5384,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
 
     if (firstClass) {
         spv::Id result = builder.createBinOp(op, typeId, left, right);
-        builder.addDecoration(result, decorations.noContraction);
-        builder.addDecoration(result, decorations.nonUniform);
+        decorations.addNoContraction(builder, result);
+        decorations.addNonUniform(builder, result);
         return builder.setPrecision(result, decorations.precision);
     }
 
@@ -5371,14 +5424,14 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
             spv::Id  leftVec =  leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
             spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
             spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
-            builder.addDecoration(result, decorations.noContraction);
-            builder.addDecoration(result, decorations.nonUniform);
+            decorations.addNoContraction(builder, result);
+            decorations.addNonUniform(builder, result);
             results.push_back(builder.setPrecision(result, decorations.precision));
         }
 
         // put the pieces together
         spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
-        builder.addDecoration(result, decorations.nonUniform);
+        decorations.addNonUniform(builder, result);
         return result;
     }
     default:
@@ -5556,6 +5609,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
     case glslang::EOpUnpackHalf2x16:
         libCall = spv::GLSLstd450UnpackHalf2x16;
         break;
+#ifndef GLSLANG_WEB
     case glslang::EOpPackSnorm4x8:
         libCall = spv::GLSLstd450PackSnorm4x8;
         break;
@@ -5574,6 +5628,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
     case glslang::EOpUnpackDouble2x32:
         libCall = spv::GLSLstd450UnpackDouble2x32;
         break;
+#endif
 
     case glslang::EOpPackInt2x32:
     case glslang::EOpUnpackInt2x32:
@@ -5784,8 +5839,8 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
         id = builder.createUnaryOp(unaryOp, typeId, operand);
     }
 
-    builder.addDecoration(id, decorations.noContraction);
-    builder.addDecoration(id, decorations.nonUniform);
+    decorations.addNoContraction(builder, id);
+    decorations.addNonUniform(builder, id);
     return builder.setPrecision(id, decorations.precision);
 }
 
@@ -5813,14 +5868,14 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat
         indexes.push_back(c);
         spv::Id srcVec  = builder.createCompositeExtract(operand, srcVecType, indexes);
         spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
-        builder.addDecoration(destVec, decorations.noContraction);
-        builder.addDecoration(destVec, decorations.nonUniform);
+        decorations.addNoContraction(builder, destVec);
+        decorations.addNonUniform(builder, destVec);
         results.push_back(builder.setPrecision(destVec, decorations.precision));
     }
 
     // put the pieces together
     spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
-    builder.addDecoration(result, decorations.nonUniform);
+    decorations.addNonUniform(builder, result);
     return result;
 }
 
@@ -5929,30 +5984,32 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
 
     case glslang::EOpConvBoolToInt:
     case glslang::EOpConvBoolToInt64:
-        if (op == glslang::EOpConvBoolToInt64)
+#ifndef GLSLANG_WEB
+        if (op == glslang::EOpConvBoolToInt64) {
             zero = builder.makeInt64Constant(0);
-        else
-            zero = builder.makeIntConstant(0);
-
-        if (op == glslang::EOpConvBoolToInt64)
             one = builder.makeInt64Constant(1);
-        else
+        } else
+#endif
+        {
+            zero = builder.makeIntConstant(0);
             one = builder.makeIntConstant(1);
+        }
 
         convOp = spv::OpSelect;
         break;
 
     case glslang::EOpConvBoolToUint:
     case glslang::EOpConvBoolToUint64:
-        if (op == glslang::EOpConvBoolToUint64)
+#ifndef GLSLANG_WEB
+        if (op == glslang::EOpConvBoolToUint64) {
             zero = builder.makeUint64Constant(0);
-        else
-            zero = builder.makeUintConstant(0);
-
-        if (op == glslang::EOpConvBoolToUint64)
             one = builder.makeUint64Constant(1);
-        else
+        } else
+#endif
+        {
+            zero = builder.makeUintConstant(0);
             one = builder.makeUintConstant(1);
+        }
 
         convOp = spv::OpSelect;
         break;
@@ -6241,7 +6298,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
         result = builder.createUnaryOp(convOp, destType, operand);
 
     result = builder.setPrecision(result, decorations.precision);
-    builder.addDecoration(result, decorations.nonUniform);
+    decorations.addNonUniform(builder, result);
     return result;
 }
 
@@ -6344,7 +6401,9 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
         scopeId = builder.makeUintConstant(spv::ScopeDevice);
     }
     // semantics default to relaxed 
-    spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.volatil ? spv::MemorySemanticsVolatileMask : spv::MemorySemanticsMaskNone);
+    spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() ? 
+                                                    spv::MemorySemanticsVolatileMask :
+                                                    spv::MemorySemanticsMaskNone);
     spv::Id semanticsId2 = semanticsId;
 
     pointerId = operands[0];
@@ -7378,6 +7437,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
         }
     }
 
+#ifndef GLSLANG_WEB
     // Decode the return types that were structures
     switch (op) {
     case glslang::EOpAddCarry:
@@ -7407,6 +7467,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
     default:
         break;
     }
+#endif
 
     return builder.setPrecision(id, precision);
 }
@@ -7589,13 +7650,13 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
 #ifndef GLSLANG_WEB
         addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier());
+        if (symbol->getQualifier().hasComponent())
+            builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
+        if (symbol->getQualifier().hasIndex())
+            builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
 #endif
         if (symbol->getType().getQualifier().hasSpecConstantId())
             builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
-        if (symbol->getQualifier().hasIndex())
-            builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
-        if (symbol->getQualifier().hasComponent())
-            builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
         // atomic counters use this:
         if (symbol->getQualifier().hasOffset())
             builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
@@ -7622,7 +7683,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
     }
     if (symbol->getQualifier().hasAttachment())
         builder.addDecoration(id, spv::DecorationInputAttachmentIndex, symbol->getQualifier().layoutAttachment);
-#ifndef GLSLANG_WEB
     if (glslangIntermediate->getXfbMode()) {
         builder.addCapability(spv::CapabilityTransformFeedback);
         if (symbol->getQualifier().hasXfbBuffer()) {
@@ -7634,8 +7694,13 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         if (symbol->getQualifier().hasXfbOffset())
             builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
     }
-#endif
 
+    // add built-in variable decoration
+    if (builtIn != spv::BuiltInMax) {
+        builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
+    }
+
+#ifndef GLSLANG_WEB
     if (symbol->getType().isImage()) {
         std::vector<spv::Decoration> memory;
         TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
@@ -7643,15 +7708,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
             builder.addDecoration(id, memory[i]);
     }
 
-    // add built-in variable decoration
-    if (builtIn != spv::BuiltInMax) {
-        builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
-    }
-
     // nonuniform
     builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier()));
 
-#ifndef GLSLANG_WEB
     if (builtIn == spv::BuiltInSampleMask) {
           spv::Decoration decoration;
           // GL_NV_sample_mask_override_coverage extension
@@ -7690,7 +7749,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         builder.addCapability(spv::CapabilityFragmentBarycentricNV);
         builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
     }
-#endif
 
     if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
         builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
@@ -7701,6 +7759,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
     if (symbol->isReference()) {
         builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
     }
+#endif
 
     return id;
 }
index b0d56d4..4a6f30b 100644 (file)
@@ -528,6 +528,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
     module.mapInstruction(type);
 
+#ifndef GLSLANG_WEB
     // deal with capabilities
     switch (dim) {
     case DimBuffer:
@@ -573,6 +574,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
                 addCapability(CapabilityImageMSArray);
         }
     }
+#endif
 
     return type->getResultId();
 }
@@ -1018,21 +1020,28 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
 
 Id Builder::makeFpConstant(Id type, double d, bool specConstant)
 {
-        assert(isFloatType(type));
+#ifdef GLSLANG_WEB
+    const int width = 32;
+    assert(width == getScalarTypeWidth(type));
+#else
+    const int width = getScalarTypeWidth(type);
+#endif
 
-        switch (getScalarTypeWidth(type)) {
-        case 16:
-                return makeFloat16Constant((float)d, specConstant);
-        case 32:
-                return makeFloatConstant((float)d, specConstant);
-        case 64:
-                return makeDoubleConstant(d, specConstant);
-        default:
-                break;
-        }
+    assert(isFloatType(type));
 
-        assert(false);
-        return NoResult;
+    switch (width) {
+    case 16:
+            return makeFloat16Constant((float)d, specConstant);
+    case 32:
+            return makeFloatConstant((float)d, specConstant);
+    case 64:
+            return makeDoubleConstant(d, specConstant);
+    default:
+            break;
+    }
+
+    assert(false);
+    return NoResult;
 }
 
 Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps)
@@ -1895,6 +1904,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
         mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
         texArgs[numArgs++] = parameters.offsets;
     }
+#ifndef GLSLANG_WEB
     if (parameters.sample) {
         mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
         texArgs[numArgs++] = parameters.sample;
@@ -1912,6 +1922,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
     if (parameters.volatil) {
         mask = mask | ImageOperandsVolatileTexelKHRMask;
     }
+#endif
     mask = mask | signExtensionMask;
     if (mask == ImageOperandsMaskNone)
         --numArgs;  // undo speculative reservation for the mask argument
@@ -2302,7 +2313,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
     int numRows = getTypeNumRows(resultTypeId);
 
     Instruction* instr = module.getInstruction(componentTypeId);
-    unsigned bitCount = instr->getImmediateOperand(0);
+#ifdef GLSLANG_WEB
+    const unsigned bitCount = 32;
+    assert(bitcount == instr->getImmediateOperand(0));
+#else
+    const unsigned bitCount = instr->getImmediateOperand(0);
+#endif
 
     // Optimize matrix constructed from a bigger matrix
     if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
index faed8e8..a99a0c3 100644 (file)
@@ -201,7 +201,11 @@ public:
     bool isMatrixType(Id typeId)       const { return getTypeClass(typeId) == OpTypeMatrix; }
     bool isStructType(Id typeId)       const { return getTypeClass(typeId) == OpTypeStruct; }
     bool isArrayType(Id typeId)        const { return getTypeClass(typeId) == OpTypeArray; }
+#ifdef GLSLANG_WEB
+    bool isCooperativeMatrixType(Id typeId)const { return false; }
+#else
     bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
+#endif
     bool isAggregateType(Id typeId)    const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
     bool isImageType(Id typeId)        const { return getTypeClass(typeId) == OpTypeImage; }
     bool isSamplerType(Id typeId)      const { return getTypeClass(typeId) == OpTypeSampler; }
@@ -557,6 +561,14 @@ public:
 
         // Accumulate whether anything in the chain of structures has coherent decorations.
         struct CoherentFlags {
+            CoherentFlags() { clear(); }
+#ifdef GLSLANG_WEB
+            void clear() { }
+            bool isVolatile() const { return false; }
+            CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
+#else
+            bool isVolatile() const { return volatil; }
+
             unsigned coherent : 1;
             unsigned devicecoherent : 1;
             unsigned queuefamilycoherent : 1;
@@ -577,7 +589,6 @@ public:
                 isImage = 0;
             }
 
-            CoherentFlags() { clear(); }
             CoherentFlags operator |=(const CoherentFlags &other) {
                 coherent |= other.coherent;
                 devicecoherent |= other.devicecoherent;
@@ -589,6 +600,7 @@ public:
                 isImage |= other.isImage;
                 return *this;
             }
+#endif
         };
         CoherentFlags coherentFlags;
     };
index 9749371..df6311f 100644 (file)
@@ -58,8 +58,8 @@ using depth_greater
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "PixelShaderFunction" 18
                               ExecutionMode 4 OriginUpperLeft
-                              ExecutionMode 4 DepthGreater
                               ExecutionMode 4 DepthReplacing
+                              ExecutionMode 4 DepthGreater
                               Source HLSL 500
                               Name 4  "PixelShaderFunction"
                               Name 10  "@PixelShaderFunction(f1;"
index c3af8ee..d2b9d8e 100644 (file)
@@ -50,8 +50,8 @@ using depth_less
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "PixelShaderFunction" 14
                               ExecutionMode 4 OriginUpperLeft
-                              ExecutionMode 4 DepthLess
                               ExecutionMode 4 DepthReplacing
+                              ExecutionMode 4 DepthLess
                               Source HLSL 500
                               Name 4  "PixelShaderFunction"
                               Name 8  "@PixelShaderFunction("
index 32ac68f..9938be8 100644 (file)
@@ -170,8 +170,8 @@ using depth_greater
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 22 27 31 36 45 48 51 55
                               ExecutionMode 4 OriginUpperLeft
-                              ExecutionMode 4 DepthGreater
                               ExecutionMode 4 DepthReplacing
+                              ExecutionMode 4 DepthGreater
                               Source HLSL 500
                               Name 4  "main"
                               Name 8  "T"
index 68d9adc..c870190 100644 (file)
@@ -1 +1 @@
-598528 ../build/install/bin/glslangValidator.exe
+409600 ../build/install/bin/glslangValidator.exe
index 5da0df0..59afd3e 100644 (file)
@@ -8,8 +8,8 @@ spv.depthOut.frag
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 8 10 14
                               ExecutionMode 4 OriginUpperLeft
-                              ExecutionMode 4 DepthGreater
                               ExecutionMode 4 DepthReplacing
+                              ExecutionMode 4 DepthGreater
                               Source GLSL 450
                               Name 4  "main"
                               Name 8  "gl_FragDepth"
index 7ee58f2..6d4b4ff 100644 (file)
@@ -527,7 +527,8 @@ __inline bool isTypeFloat(TBasicType type)
     }
 }
 
-__inline int getTypeRank(TBasicType type) {
+__inline int getTypeRank(TBasicType type)
+{
     int res = -1;
     switch(type) {
     case EbtInt8:
index 79c9efc..fa26c8c 100644 (file)
@@ -79,18 +79,27 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
     bool         ms : 1;
     bool      image : 1;  // image, combined should be false
     bool   combined : 1;  // true means texture is combined with a sampler, false means texture with no sampler
-    bool    sampler : 1;  // true means a pure sampler, other fields should be clear()
-    bool   external : 1;  // GL_OES_EGL_image_external
-    bool        yuv : 1;  // GL_EXT_YUV_target
+#ifdef ENABLE_HLSL
     unsigned int vectorSize : 3;  // vector return type size.
-
-    // Encapsulate getting members' vector sizes packed into the vectorSize bitfield.
     unsigned int getVectorSize() const { return vectorSize; }
+    void clearReturnStruct() { structReturnIndex = noReturnStruct; }
+    bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
+    unsigned getStructReturnIndex() const { return structReturnIndex; }
 
-#ifdef GLSLANG_WEB
+    static const unsigned structReturnIndexBits = 4;                        // number of index bits to use.
+    static const unsigned structReturnSlots = (1<<structReturnIndexBits)-1; // number of valid values
+    static const unsigned noReturnStruct = structReturnSlots;               // value if no return struct type.
+
+    // Index into a language specific table of texture return structures.
+    unsigned int structReturnIndex : structReturnIndexBits;
+#else
+    unsigned int getVectorSize() const { return 4; }
     void clearReturnStruct() const { }
     bool hasReturnStruct() const { return false; }
     unsigned getStructReturnIndex() const { return 0; }
+#endif
+
+#ifdef GLSLANG_WEB
     bool is1D()          const { return false; }
     bool isBuffer()      const { return false; }
     bool isRect()        const { return false; }
@@ -105,18 +114,12 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
     void setExternal(bool e) { }
     bool isYuv()         const { return false; }
 #else
+    bool    sampler : 1;  // true means a pure sampler, other fields should be clear()
+    bool   external : 1;  // GL_OES_EGL_image_external
+    bool        yuv : 1;  // GL_EXT_YUV_target
     // Some languages support structures as sample results.  Storing the whole structure in the
     // TSampler is too large, so there is an index to a separate table.
-    static const unsigned structReturnIndexBits = 4;                        // number of index bits to use.
-    static const unsigned structReturnSlots = (1<<structReturnIndexBits)-1; // number of valid values
-    static const unsigned noReturnStruct = structReturnSlots;               // value if no return struct type.
-
-    // Index into a language specific table of texture return structures.
-    unsigned int structReturnIndex : structReturnIndexBits;
 
-    void clearReturnStruct() { structReturnIndex = noReturnStruct; }
-    bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
-    unsigned getStructReturnIndex() const { return structReturnIndex; }
     bool is1D()          const { return dim == Esd1D; }
     bool isBuffer()      const { return dim == EsdBuffer; }
     bool isRect()        const { return dim == EsdRect; }
@@ -144,13 +147,17 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
         ms = false;
         image = false;
         combined = false;
+#ifndef GLSLANG_WEB
         sampler = false;
         external = false;
         yuv = false;
-        clearReturnStruct();
+#endif
 
+#ifdef ENABLE_HLSL
+        clearReturnStruct();
         // by default, returns a single vec4;
         vectorSize = 4;
+#endif
     }
 
     // make a combined sampler and texture
@@ -188,6 +195,7 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
         ms = m;
     }
 
+#ifndef GLSLANG_WEB
     // make a subpass input attachment
     void setSubpass(TBasicType t, bool m = false)
     {
@@ -205,6 +213,7 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
         sampler = true;
         shadow = s;
     }
+#endif
 
     bool operator==(const TSampler& right) const
     {
@@ -218,7 +227,7 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
          isPureSampler() == right.isPureSampler() &&
             isExternal() == right.isExternal() &&
                  isYuv() == right.isYuv() &&
-              vectorSize == right.vectorSize &&
+         getVectorSize() == right.getVectorSize() &&
   getStructReturnIndex() == right.getStructReturnIndex();
     }
 
@@ -495,8 +504,10 @@ public:
     void clearInterstage()
     {
         clearInterpolation();
+#ifndef GLSLANG_WEB
         patch = false;
         sample = false;
+#endif
     }
 
     void clearInterpolation()
@@ -552,17 +563,6 @@ public:
     bool centroid     : 1;
     bool smooth       : 1;
     bool flat         : 1;
-#ifndef GLSLANG_WEB
-    bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
-    bool nopersp      : 1;
-    bool explicitInterp : 1;
-    bool pervertexNV  : 1;
-    bool perPrimitiveNV : 1;
-    bool perViewNV : 1;
-    bool perTaskNV : 1;
-#endif
-    bool patch        : 1;
-    bool sample       : 1;
     bool coherent     : 1;
     bool devicecoherent : 1;
     bool queuefamilycoherent : 1;
@@ -573,10 +573,12 @@ public:
     bool restrict     : 1;
     bool readonly     : 1;
     bool writeonly    : 1;
-    bool specConstant : 1;  // having a constant_id is not sufficient: expressions have no id, but are still specConstant
+    // having a constant_id is not sufficient: expressions have no id, but are still specConstant
+    bool specConstant : 1;
     bool nonUniform   : 1;
 
 #ifdef GLSLANG_WEB
+    bool isSample() const { return false; }
     bool isMemory() const { return false; }
     bool isMemoryQualifierImageAndSSBOOnly() const { return false; }
     bool bufferReferenceNeedsVulkanMemoryModel() const { return false; }
@@ -588,6 +590,16 @@ public:
     void setNoContraction() { }
     bool isPervertexNV() const { return false; }
 #else
+    bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
+    bool nopersp      : 1;
+    bool explicitInterp : 1;
+    bool pervertexNV  : 1;
+    bool perPrimitiveNV : 1;
+    bool perViewNV : 1;
+    bool perTaskNV : 1;
+    bool patch        : 1;
+    bool sample       : 1;
+    bool isSample() const { return sample; }
     bool isMemory() const
     {
         return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
@@ -1592,9 +1604,9 @@ public:
     virtual TIntermTyped*  getOuterArrayNode() const { return arraySizes->getOuterNode(); }
     virtual int getCumulativeArraySize()  const { return arraySizes->getCumulativeSize(); }
 #ifdef GLSLANG_WEB
-    virtual bool isArrayOfArrays() const { return false; }
+    bool isArrayOfArrays() const { return false; }
 #else
-    virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
+    bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
 #endif
     virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
     virtual const TArraySizes* getArraySizes() const { return arraySizes; }
@@ -1646,11 +1658,11 @@ public:
     virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
     virtual bool isParameterized()  const { return typeParameters != nullptr; }
 #ifdef GLSLANG_WEB
-    virtual bool isCoopMat() const { return false; }
-    virtual bool isReference() const { return false; }
+    bool isCoopMat() const { return false; }
+    bool isReference() const { return false; }
 #else
-    virtual bool isCoopMat() const { return coopmat; }
-    virtual bool isReference() const { return getBasicType() == EbtReference; }
+    bool isCoopMat() const { return coopmat; }
+    bool isReference() const { return getBasicType() == EbtReference; }
 #endif
 
     // return true if this type contains any subtype which satisfies the given predicate.
@@ -1733,39 +1745,39 @@ public:
     }
 
 #ifdef GLSLANG_WEB
-    virtual bool containsDouble() const { return false; }
-    virtual bool contains16BitFloat() const { return false; }
-    virtual bool contains64BitInt() const { return false; }
-    virtual bool contains16BitInt() const { return false; }
-    virtual bool contains8BitInt() const { return false; }
-    virtual bool containsCoopMat() const { return false; }
-    virtual bool containsReference() const { return false; }
+    bool containsDouble() const { return false; }
+    bool contains16BitFloat() const { return false; }
+    bool contains64BitInt() const { return false; }
+    bool contains16BitInt() const { return false; }
+    bool contains8BitInt() const { return false; }
+    bool containsCoopMat() const { return false; }
+    bool containsReference() const { return false; }
 #else
-    virtual bool containsDouble() const
+    bool containsDouble() const
     {
         return containsBasicType(EbtDouble);
     }
-    virtual bool contains16BitFloat() const
+    bool contains16BitFloat() const
     {
         return containsBasicType(EbtFloat16);
     }
-    virtual bool contains64BitInt() const
+    bool contains64BitInt() const
     {
         return containsBasicType(EbtInt64) || containsBasicType(EbtUint64);
     }
-    virtual bool contains16BitInt() const
+    bool contains16BitInt() const
     {
         return containsBasicType(EbtInt16) || containsBasicType(EbtUint16);
     }
-    virtual bool contains8BitInt() const
+    bool contains8BitInt() const
     {
         return containsBasicType(EbtInt8) || containsBasicType(EbtUint8);
     }
-    virtual bool containsCoopMat() const
+    bool containsCoopMat() const
     {
         return contains([](const TType* t) { return t->coopmat; } );
     }
-    virtual bool containsReference() const
+    bool containsReference() const
     {
         return containsBasicType(EbtReference);
     }
index e77cc0e..f2a015a 100644 (file)
@@ -1354,10 +1354,6 @@ public:
         case EOpTexture:
         case EOpSparseTexture:
             break;
-        case EOpTextureClamp:
-        case EOpSparseTextureClamp:
-            cracked.lodClamp = true;
-            break;
         case EOpTextureProj:
             cracked.proj = true;
             break;
@@ -1369,11 +1365,6 @@ public:
         case EOpSparseTextureOffset:
             cracked.offset = true;
             break;
-        case EOpTextureOffsetClamp:
-        case EOpSparseTextureOffsetClamp:
-            cracked.offset = true;
-            cracked.lodClamp = true;
-            break;
         case EOpTextureFetch:
         case EOpSparseTextureFetch:
             cracked.fetch = true;
@@ -1409,11 +1400,6 @@ public:
         case EOpSparseTextureGrad:
             cracked.grad = true;
             break;
-        case EOpTextureGradClamp:
-        case EOpSparseTextureGradClamp:
-            cracked.grad = true;
-            cracked.lodClamp = true;
-            break;
         case EOpTextureGradOffset:
         case EOpSparseTextureGradOffset:
             cracked.grad = true;
@@ -1428,6 +1414,21 @@ public:
             cracked.offset = true;
             cracked.proj = true;
             break;
+#ifndef GLSLANG_WEB
+        case EOpTextureClamp:
+        case EOpSparseTextureClamp:
+            cracked.lodClamp = true;
+            break;
+        case EOpTextureOffsetClamp:
+        case EOpSparseTextureOffsetClamp:
+            cracked.offset = true;
+            cracked.lodClamp = true;
+            break;
+        case EOpTextureGradClamp:
+        case EOpSparseTextureGradClamp:
+            cracked.grad = true;
+            cracked.lodClamp = true;
+            break;
         case EOpTextureGradOffsetClamp:
         case EOpSparseTextureGradOffsetClamp:
             cracked.grad = true;
@@ -1497,6 +1498,7 @@ public:
         case EOpSubpassLoadMS:
             cracked.subpass = true;
             break;
+#endif
         default:
             break;
         }
index 50bfcdb..ccf010e 100644 (file)
@@ -153,13 +153,13 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
     case EvqConst:          message = "can't modify a const";        break;
     case EvqConstReadOnly:  message = "can't modify a const";        break;
     case EvqUniform:        message = "can't modify a uniform";      break;
+#ifndef GLSLANG_WEB
     case EvqBuffer:
         if (node->getQualifier().readonly)
             message = "can't modify a readonly buffer";
         if (node->getQualifier().isShaderRecordNV())
             message = "can't modify a shaderrecordnv qualified buffer";
         break;
-#ifndef GLSLANG_WEB
     case EvqHitAttrNV:
         if (language != EShLangIntersectNV)
             message = "cannot modify hitAttributeNV in this stage";
index a96320b..1db615a 100644 (file)
@@ -1147,6 +1147,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                             error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
                     }
                     TQualifier& argQualifier = arg->getAsTyped()->getQualifier();
+#ifndef GLSLANG_WEB
                     if (argQualifier.isMemory()) {
                         const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
                         if (argQualifier.volatil && ! formalQualifier.volatil)
@@ -1176,7 +1177,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                                                               argQualifier.getFormat() != ElfNone))
                             error(arguments->getLoc(), "image formats must match", "format", "");
                     }
-
+#endif
                     if (builtIn && arg->getAsTyped()->getType().contains16BitFloat())
                         requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage");
                     if (builtIn && arg->getAsTyped()->getType().contains16BitInt())
@@ -7507,7 +7508,7 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
         error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", "");
     if (qualifier.centroid)
         error(loc, "cannot use centroid qualifier on an interface block", "centroid", "");
-    if (qualifier.sample)
+    if (qualifier.isSample())
         error(loc, "cannot use sample qualifier on an interface block", "sample", "");
     if (qualifier.invariant)
         error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
index ab013bf..45f4509 100644 (file)
@@ -538,13 +538,14 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
     if (symbol.getQualifier().centroid  != unitSymbol.getQualifier().centroid ||
         symbol.getQualifier().smooth    != unitSymbol.getQualifier().smooth ||
         symbol.getQualifier().flat      != unitSymbol.getQualifier().flat ||
-        symbol.getQualifier().sample    != unitSymbol.getQualifier().sample ||
-        symbol.getQualifier().patch     != unitSymbol.getQualifier().patch ||
+        symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
+        symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
         symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) {
         error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
         writeTypeComparison = true;
     }
 
+#ifndef GLSLANG_WEB
     // Memory...
     if (symbol.getQualifier().coherent          != unitSymbol.getQualifier().coherent ||
         symbol.getQualifier().devicecoherent    != unitSymbol.getQualifier().devicecoherent ||
@@ -559,6 +560,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
         error(infoSink, "Memory qualifiers must match:");
         writeTypeComparison = true;
     }
+#endif
 
     // Layouts...
     // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
@@ -608,9 +610,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
             warn(infoSink, "Entry point not found");
     }
 
-    if (getNumPushConstants() > 1)
-        error(infoSink, "Only one push_constant block is allowed per stage");
-
     // recursion and missing body checking
     checkCallGraphCycles(infoSink);
     checkCallGraphBodies(infoSink, keepUncalled);
@@ -619,6 +618,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     inOutLocationCheck(infoSink);
 
 #ifndef GLSLANG_WEB
+    if (getNumPushConstants() > 1)
+        error(infoSink, "Only one push_constant block is allowed per stage");
+
     // invocations
     if (invocations == TQualifier::layoutNotSet)
         invocations = 1;
index affab4b..77ed7c3 100644 (file)
@@ -481,6 +481,8 @@ public:
     bool usingVulkanMemoryModel() const { return false; }
     bool usingPhysicalStorageBuffer() const { return false; }
     bool usingVariablePointers() const { return false; }
+    unsigned getXfbStride(int buffer) const { return 0; }
+    bool hasLayoutDerivativeModeNone() const { return false; }
 #else
     void output(TInfoSink&, bool tree);
 
@@ -544,6 +546,7 @@ public:
     }
     bool getAutoMapLocations() const { return autoMapLocations; }
 
+#ifdef ENABLE_HLSL
     void setFlattenUniformArrays(bool flatten)
     {
         flattenUniformArrays = flatten;
@@ -551,6 +554,7 @@ public:
             processes.addProcess("flatten-uniform-arrays");
     }
     bool getFlattenUniformArrays() const { return flattenUniformArrays; }
+#endif 
     void setNoStorageFormat(bool b)
     {
         useUnknownFormat = b;
@@ -576,12 +580,14 @@ public:
     }
     bool usingVariablePointers() const { return useVariablePointers; }
 
+#ifdef ENABLE_HLSL
     template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
     bool hasCounterBufferName(const TString& name) const {
         size_t len = strlen(implicitCounterName);
         return name.size() > len &&
                name.compare(name.size() - len, len, implicitCounterName) == 0;
     }
+#endif
 
     void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
     int getNumPushConstants() const { return numPushConstants; }
@@ -703,6 +709,7 @@ public:
     void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
     bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
     void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
+    bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
     ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
     bool setPrimitives(int m)
     {
index 993545f..ea34f41 100755 (executable)
@@ -68,30 +68,30 @@ public:
     virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
 #ifdef GLSLANG_WEB
     bool isEsProfile() const { return true; }
-    virtual void initializeExtensionBehavior() { }
-    virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { }
-    virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { }
-    virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
+    void initializeExtensionBehavior() { }
+    void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { }
+    void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { }
+    void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
         const char* featureDesc) { }
-    virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
+    void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
         const char* featureDesc) { }
-    virtual TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
-    virtual bool extensionTurnedOn(const char* const extension) { return false; }
-    virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
-    virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
-    virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
-    virtual void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
-    virtual void fullIntegerCheck(const TSourceLoc&, const char* op) { }
-    virtual void doubleCheck(const TSourceLoc&, const char* op) { }
-    virtual bool float16Arithmetic() { return false; }
-    virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
-    virtual bool int16Arithmetic() { return false; }
-    virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
-    virtual bool int8Arithmetic() { return false; }
-    virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
-    virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
-    virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
-    virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
+    TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
+    bool extensionTurnedOn(const char* const extension) { return false; }
+    bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
+    void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
+    void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
+    void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
+    void fullIntegerCheck(const TSourceLoc&, const char* op) { }
+    void doubleCheck(const TSourceLoc&, const char* op) { }
+    bool float16Arithmetic() { return false; }
+    void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
+    bool int16Arithmetic() { return false; }
+    void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
+    bool int8Arithmetic() { return false; }
+    void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
+    void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
+    void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
+    void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
 #else
     bool isEsProfile() const { return profile == EEsProfile; }
     virtual void initializeExtensionBehavior();
index 043df57..fe36a76 100644 (file)
@@ -1085,6 +1085,7 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
 // build counter block index associations for buffers
 void TReflection::buildCounterIndices(const TIntermediate& intermediate)
 {
+#ifdef ENABLE_HLSL
     // search for ones that have counters
     for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
         const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
@@ -1093,6 +1094,7 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
         if (index >= 0)
             indexToUniformBlock[i].counterIndex = index;
     }
+#endif
 }
 
 // build Shader Stages mask for all uniforms
index 1000e17..4c16c38 100755 (executable)
@@ -434,8 +434,8 @@ public:
     void setInvertY(bool invert);
 #ifdef ENABLE_HLSL
     void setHlslIoMapping(bool hlslIoMap);
-#endif
     void setFlattenUniformArrays(bool flatten);
+#endif
     void setNoStorageFormat(bool useUnknownFormat);
     void setNanMinMaxClamp(bool nanMinMaxClamp);
     void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
index faca801..61a8f23 100755 (executable)
@@ -227,7 +227,9 @@ public:
             shader.setAutoMapBindings(true);
         }
         shader.setTextureSamplerTransformMode(texSampTransMode);
+#ifdef ENABLE_HLSL
         shader.setFlattenUniformArrays(flattenUniformArrays);
+#endif
 
         if (controls & EShMsgSpvRules) {
             if (controls & EShMsgVulkanRules) {
@@ -300,7 +302,9 @@ public:
         shader.setShiftSsboBinding(baseSsboBinding);
         shader.setAutoMapBindings(autoMapBindings);
         shader.setAutoMapLocations(true);
+#ifdef ENABLE_HLSL
         shader.setFlattenUniformArrays(flattenUniformArrays);
+#endif
 
         bool success = compile(&shader, code, entryPointName, controls);