From 3e4b6ff76a7f3a2e96db17a17c5c76027d4b6730 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 8 Aug 2019 01:15:24 -0600 Subject: [PATCH] Web: Tighten up sampling code and interfaces. Saves about 9K. --- SPIRV/GlslangToSpv.cpp | 39 +++-- SPIRV/SpvBuilder.cpp | 2 +- glslang/Include/Types.h | 89 +++++++---- glslang/Include/intermediate.h | 4 +- glslang/MachineIndependent/Initialize.cpp | 158 ++++++++++++-------- glslang/MachineIndependent/Intermediate.cpp | 4 +- glslang/MachineIndependent/ParseHelper.cpp | 36 +++-- glslang/MachineIndependent/SymbolTable.cpp | 24 +-- 8 files changed, 217 insertions(+), 139 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index ddbfb8082..4643c7481 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -1186,9 +1186,9 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getQualifier().hasAttachment()) builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT); - else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isImage() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT); - else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isTexture() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT); else if (baseType.isImage()) builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT); @@ -1206,10 +1206,10 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp if (baseType.getQualifier().hasAttachment()) { builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT); - } else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) { + } else if (baseType.isImage() && baseType.getSampler().isBuffer()) { builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT); - } else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) { + } else if (baseType.isTexture() && baseType.getSampler().isBuffer()) { builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT); } @@ -3369,14 +3369,14 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty case glslang::EbtSampler: { const glslang::TSampler& sampler = type.getSampler(); - if (sampler.sampler) { - // pure sampler + if (sampler.isPureSampler()) { spvType = builder.makeSamplerType(); } else { // an image is present, make its type - spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, - sampler.image ? 2 : 1, TranslateImageFormat(type)); - if (sampler.combined) { + spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), + sampler.isShadow(), sampler.isArrayed(), sampler.isMultiSample(), + sampler.isImageClass() ? 2 : 1, TranslateImageFormat(type)); + if (sampler.isCombined()) { // already has both image and sampler, make the combined type spvType = builder.makeSampledImageType(spvType); } @@ -4455,12 +4455,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO operands.push_back(coord); spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone }; imageOperands.word = imageOperands.word | signExtensionMask(); - if (sampler.ms) { + if (sampler.isMultiSample()) { imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask; } if (imageOperands.word != spv::ImageOperandsMaskNone) { operands.push_back(imageOperands); - if (sampler.ms) { + if (sampler.isMultiSample()) { spv::IdImmediate imageOperand = { true, *(opIt++) }; operands.push_back(imageOperand); } @@ -4474,7 +4474,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO operands.push_back(coord); if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } if (cracked.lod) { @@ -4517,7 +4517,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) { // Push the texel value before the operands - if (sampler.ms || cracked.lod) { + if (sampler.isMultiSample() || cracked.lod) { spv::IdImmediate texel = { true, *(opIt + 1) }; operands.push_back(texel); } else { @@ -4526,7 +4526,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } if (cracked.lod) { @@ -4566,7 +4566,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat); spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; - if (sampler.ms) { + if (sampler.isMultiSample()) { mask = mask | spv::ImageOperandsSampleMask; } if (cracked.lod) { @@ -4612,7 +4612,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer, // as the first source operand, is required by SPIR-V atomic operations. // For non-MS, the sample value should be 0 - spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) }; + spv::IdImmediate sample = { true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0) }; operands.push_back(sample); spv::Id resultTypeId; @@ -4676,7 +4676,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Check for texture functions other than queries bool sparse = node->isSparseTexture(); bool imageFootprint = node->isImageFootprint(); - bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; + bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.isArrayed() && sampler.isShadow(); // check for bias argument bool bias = false; @@ -4763,7 +4763,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } // multisample - if (sampler.ms) { + if (sampler.isMultiSample()) { params.sample = arguments[2 + extraArgs]; // For MS, "sample" should be specified ++extraArgs; } @@ -4784,6 +4784,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } +#ifndef GLSLANG_WEB // lod clamp if (cracked.lodClamp) { params.lodClamp = arguments[2 + extraArgs]; @@ -4794,7 +4795,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO params.texelOut = arguments[2 + extraArgs]; ++extraArgs; } - // gather component if (cracked.gather && ! sampler.shadow) { // default component is 0, if missing, otherwise an argument @@ -4804,7 +4804,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } else params.component = builder.makeIntConstant(0); } -#ifndef GLSLANG_WEB spv::Id resultStruct = spv::NoResult; if (imageFootprint) { //Following three extra arguments diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 52fbc630f..624acf40e 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1908,7 +1908,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, #ifndef GLSLANG_WEB } else if (parameters.granularity && parameters.coarse) { opCode = OpImageSampleFootprintNV; -#endif } else if (gather) { if (parameters.Dref) if (sparse) @@ -1920,6 +1919,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseGather; else opCode = OpImageGather; +#endif } else if (explicitLod) { if (parameters.Dref) { if (proj) diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index a9e4617b5..f985e8ae1 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -84,6 +84,27 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool yuv : 1; // GL_EXT_YUV_target unsigned int vectorSize : 3; // vector return type size. + // Encapsulate getting members' vector sizes packed into the vectorSize bitfield. + unsigned int getVectorSize() const { return vectorSize; } + +#ifdef GLSLANG_WEB + void clearReturnStruct() const { } + bool hasReturnStruct() const { return false; } + unsigned getStructReturnIndex() const { return 0; } + bool is1D() const { return false; } + bool isBuffer() const { return false; } + bool isRect() const { return false; } + bool isSubpass() const { return false; } + bool isCombined() const { return true; } + bool isPureSampler() const { return false; } + bool isTexture() const { return false; } + bool isImage() const { return false; } + bool isImageClass() const { return false; } + bool isMultiSample() const { return false; } + bool isExternal() const { return false; } + void setExternal(bool e) { } + bool isYuv() const { return false; } +#else // 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. @@ -93,18 +114,26 @@ struct TSampler { // misnomer now; includes images, textures without sampler, // Index into a language specific table of texture return structures. unsigned int structReturnIndex : structReturnIndexBits; - // Encapsulate getting members' vector sizes packed into the vectorSize bitfield. - unsigned int getVectorSize() const { return vectorSize; } - - bool isImage() const { return image && dim != EsdSubpass; } + 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; } bool isSubpass() const { return dim == EsdSubpass; } bool isCombined() const { return combined; } bool isPureSampler() const { return sampler; } bool isTexture() const { return !sampler && !image; } + bool isImage() const { return image && !isSubpass(); } + bool isImageClass() const { return image; } + bool isMultiSample() const { return ms; } + bool isExternal() const { return external; } + void setExternal(bool e) { external = e; } + bool isYuv() const { return yuv; } +#endif + void setCombined(bool c) { combined = c; } bool isShadow() const { return shadow; } bool isArrayed() const { return arrayed; } - bool isMultiSample() const { return ms; } - bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; } void clear() { @@ -118,7 +147,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, sampler = false; external = false; yuv = false; - structReturnIndex = noReturnStruct; + clearReturnStruct(); // by default, returns a single vec4; vectorSize = 4; @@ -183,14 +212,14 @@ struct TSampler { // misnomer now; includes images, textures without sampler, dim == right.dim && arrayed == right.arrayed && shadow == right.shadow && - ms == right.ms && - image == right.image && - combined == right.combined && - sampler == right.sampler && - external == right.external && - yuv == right.yuv && + isMultiSample() == right.isMultiSample() && + isImageClass() == right.isImageClass() && + isCombined() == right.isCombined() && + isPureSampler() == right.isPureSampler() && + isExternal() == right.isExternal() && + isYuv() == right.isYuv() && vectorSize == right.vectorSize && - structReturnIndex == right.structReturnIndex; + getStructReturnIndex() == right.getStructReturnIndex(); } bool operator!=(const TSampler& right) const @@ -202,13 +231,12 @@ struct TSampler { // misnomer now; includes images, textures without sampler, { TString s; - if (sampler) { + if (isPureSampler()) { s.append("sampler"); return s; } switch (type) { - case EbtFloat: break; case EbtInt: s.append("i"); break; case EbtUint: s.append("u"); break; #ifndef GLSLANG_WEB @@ -222,34 +250,36 @@ struct TSampler { // misnomer now; includes images, textures without sampler, #endif default: break; } - if (image) { - if (dim == EsdSubpass) + if (isImageClass()) { + if (isSubpass()) s.append("subpass"); else s.append("image"); - } else if (combined) { + } else if (isCombined()) { s.append("sampler"); } else { s.append("texture"); } - if (external) { + if (isExternal()) { s.append("ExternalOES"); return s; } - if (yuv) { + if (isYuv()) { return "__" + s + "External2DY2YEXT"; } switch (dim) { - case Esd1D: s.append("1D"); break; case Esd2D: s.append("2D"); break; case Esd3D: s.append("3D"); break; case EsdCube: s.append("Cube"); break; +#ifndef GLSLANG_WEB + case Esd1D: s.append("1D"); break; case EsdRect: s.append("2DRect"); break; case EsdBuffer: s.append("Buffer"); break; case EsdSubpass: s.append("Input"); break; +#endif default: break; // some compilers want this } - if (ms) + if (isMultiSample()) s.append("MS"); if (arrayed) s.append("Array"); @@ -897,6 +927,7 @@ public: bool isShaderRecordNV() const { return false; } bool hasBufferReference() const { return false; } bool hasBufferReferenceAlign() const { return false; } + bool isNonUniform() const { return false; } #else bool isNonPerspective() const { return nopersp; } bool hasIndex() const @@ -945,6 +976,10 @@ public: { return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd; } + bool isNonUniform() const + { + return nonUniform; + } #endif bool hasSpecConstantId() const { @@ -959,10 +994,6 @@ public: // true front-end constant. return specConstant; } - bool isNonUniform() const - { - return nonUniform; - } bool isFrontEndConstant() const { // True if the front-end knows the final constant value. @@ -998,6 +1029,9 @@ public: default: return "none"; } } +#ifdef GLSLANG_WEB + static const char* getLayoutFormatString(TLayoutFormat f) { return "none"; } +#else static const char* getLayoutFormatString(TLayoutFormat f) { switch (f) { @@ -1132,6 +1166,7 @@ public: default: return "none"; } } +#endif }; // Qualifiers that don't need to be keep per object. They have shader scope, not object scope. diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index eee3eb891..e77cc0ed6 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -1377,14 +1377,14 @@ public: case EOpTextureFetch: case EOpSparseTextureFetch: cracked.fetch = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureFetchOffset: case EOpSparseTextureFetchOffset: cracked.fetch = true; cracked.offset = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureProjOffset: diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 1f012d18b..4b3d26718 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -435,25 +435,30 @@ TBuiltIns::TBuiltIns() // Set up textual representations for making all the permutations // of texturing/imaging functions. prefixes[EbtFloat] = ""; + prefixes[EbtInt] = "i"; + prefixes[EbtUint] = "u"; +#ifndef GLSLANG_WEB prefixes[EbtFloat16] = "f16"; prefixes[EbtInt8] = "i8"; prefixes[EbtUint8] = "u8"; prefixes[EbtInt16] = "i16"; prefixes[EbtUint16] = "u16"; - prefixes[EbtInt] = "i"; - prefixes[EbtUint] = "u"; +#endif + postfixes[2] = "2"; postfixes[3] = "3"; postfixes[4] = "4"; // Map from symbolic class of texturing dimension to numeric dimensions. - dimMap[Esd1D] = 1; dimMap[Esd2D] = 2; - dimMap[EsdRect] = 2; dimMap[Esd3D] = 3; dimMap[EsdCube] = 3; +#ifndef GLSLANG_WEB + dimMap[Esd1D] = 1; + dimMap[EsdRect] = 2; dimMap[EsdBuffer] = 1; dimMap[EsdSubpass] = 2; // potientially unused for now +#endif } TBuiltIns::~TBuiltIns() @@ -6150,18 +6155,18 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // In this function proper, enumerate the types, then calls the next set of functions // to enumerate all the uses for that type. // - TBasicType bTypes[4] = { EbtFloat, EbtFloat16, EbtInt, EbtUint }; bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); // enumerate all the types #ifdef GLSLANG_WEB + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint }; const int image = 0; #else + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 }; for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler #endif { - for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not #ifdef GLSLANG_WEB const int ms = 0; @@ -6169,6 +6174,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c for (int ms = 0; ms <= 1; ++ms) #endif { +#ifndef GLSLANG_WEB if ((ms || image) && shadow) continue; if (ms && profile != EEsProfile && version < 150) @@ -6177,19 +6183,19 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; if (ms && profile == EEsProfile && version < 310) continue; +#endif for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not #ifdef GLSLANG_WEB - for (int dim = Esd2D; dim < EsdCube + 1; ++dim) { // 2D, 3D, and Cube + for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube #else - for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer, subpass + for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) continue; if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) continue; -#endif if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) @@ -6198,32 +6204,34 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; if (dim != Esd2D && dim != EsdSubpass && ms) continue; - if ((dim == Esd3D || dim == EsdRect) && arrayed) - continue; - if (dim == Esd3D && shadow) - continue; - if (dim == EsdCube && arrayed && skipCubeArrayed) - continue; if (dim == EsdBuffer && skipBuffer) continue; if (dim == EsdBuffer && (shadow || arrayed || ms)) continue; if (ms && arrayed && profile == EEsProfile && version < 310) continue; - for (int bType = 0; bType < 4; ++bType) { // float, float16, int, uint results +#endif + if (dim == Esd3D && shadow) + continue; + if (dim == EsdCube && arrayed && skipCubeArrayed) + continue; + if ((dim == Esd3D || dim == EsdRect) && arrayed) + continue; - if (shadow && bType > 1) - continue; - - if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile ||version < 450)) + // Loop over the bTypes + for (int bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) { +#ifndef GLSLANG_WEB + if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450)) continue; if (dim == EsdRect && version < 140 && bType > 0) continue; +#endif + if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint)) + continue; // // Now, make all the function prototypes for the type we just built... // - TSampler sampler; #ifndef GLSLANG_WEB if (dim == EsdSubpass) { @@ -6280,13 +6288,14 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c } } +#ifndef GLSLANG_WEB // // sparseTexelsResidentARB() // - if (profile != EEsProfile && version >= 450) { commonBuiltins.append("bool sparseTexelsResidentARB(int code);\n"); } +#endif } // @@ -6297,14 +6306,25 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { - if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) - return; - // // textureSize() and imageSize() // int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); + +#ifdef GLSLANG_WEB + commonBuiltins.append("highp "); + commonBuiltins.append("ivec"); + commonBuiltins.append(postfixes[sizeDims]); + commonBuiltins.append(" textureSize("); + commonBuiltins.append(typeName); + commonBuiltins.append(",int);\n"); + return; +#endif + + if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) + return; + if (profile == EEsProfile) commonBuiltins.append("highp "); if (sizeDims == 1) @@ -6313,28 +6333,25 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append("ivec"); commonBuiltins.append(postfixes[sizeDims]); } -#ifndef GLSLANG_WEB - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); else -#endif commonBuiltins.append(" textureSize("); commonBuiltins.append(typeName); - if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms) + if (! sampler.isImage() && ! sampler.isRect() && ! sampler.isBuffer() && ! sampler.isMultiSample()) commonBuiltins.append(",int);\n"); else commonBuiltins.append(");\n"); -#ifndef GLSLANG_WEB // // textureSamples() and imageSamples() // // GL_ARB_shader_texture_image_samples // TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? - if (profile != EEsProfile && version >= 430 && sampler.ms) { + if (profile != EEsProfile && version >= 430 && sampler.isMultiSample()) { commonBuiltins.append("int "); - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); else commonBuiltins.append("textureSamples("); @@ -6346,7 +6363,8 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // textureQueryLod(), fragment stage only // - if (profile != EEsProfile && version >= 400 && sampler.combined && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + if (profile != EEsProfile && version >= 400 && sampler.isCombined() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) { if (f16TexAddr && sampler.type != EbtFloat16) continue; @@ -6382,12 +6400,12 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // textureQueryLevels() // - if (profile != EEsProfile && version >= 430 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + if (profile != EEsProfile && version >= 430 && ! sampler.isImage() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { commonBuiltins.append("int textureQueryLevels("); commonBuiltins.append(typeName); commonBuiltins.append(");\n"); } -#endif } // @@ -6410,7 +6428,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int imageParams.append(", ivec"); imageParams.append(postfixes[dims]); } - if (sampler.ms) + if (sampler.isMultiSample()) imageParams.append(", int"); if (profile == EEsProfile) @@ -6426,7 +6444,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D && sampler.dim != EsdBuffer && profile != EEsProfile && version >= 450) { + if (! sampler.is1D() && ! sampler.isBuffer() && profile != EEsProfile && version >= 450) { commonBuiltins.append("int sparseImageLoadARB(readonly volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", out "); @@ -6503,7 +6521,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int } } - if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.ms) + if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.isMultiSample()) return; if (profile == EEsProfile || version < 450) @@ -6529,7 +6547,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D) { + if (! sampler.is1D()) { commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent "); commonBuiltins.append(imageLodParams); commonBuiltins.append(", out "); @@ -6551,7 +6569,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in stageBuiltins[EShLangFragment].append("vec4 subpassLoad"); stageBuiltins[EShLangFragment].append("("); stageBuiltins[EShLangFragment].append(typeName.c_str()); - if (sampler.ms) + if (sampler.isMultiSample()) stageBuiltins[EShLangFragment].append(", int"); stageBuiltins[EShLangFragment].append(");\n"); } @@ -6569,12 +6587,13 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, // for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not - if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms || !sampler.combined)) + if (proj && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.arrayed || sampler.isMultiSample() + || !sampler.isCombined())) continue; for (int lod = 0; lod <= 1; ++lod) { - if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms || !sampler.combined)) + if (lod && (sampler.isBuffer() || sampler.isRect() || sampler.isMultiSample() || !sampler.isCombined())) continue; if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) continue; @@ -6583,18 +6602,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, for (int bias = 0; bias <= 1; ++bias) { - if (bias && (lod || sampler.ms || !sampler.combined)) + if (bias && (lod || sampler.isMultiSample() || !sampler.isCombined())) continue; if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) continue; - if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) + if (bias && (sampler.isRect() || sampler.isBuffer())) continue; for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not if (proj + offset + bias + lod > 3) continue; - if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) + if (offset && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.isMultiSample())) continue; for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not @@ -6605,14 +6624,15 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; if (fetch && (sampler.shadow || sampler.dim == EsdCube)) continue; - if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined)) + if (fetch == 0 && (sampler.isMultiSample() || sampler.isBuffer() + || !sampler.isCombined())) continue; for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not - if (grad && (lod || bias || sampler.ms || !sampler.combined)) + if (grad && (lod || bias || sampler.isMultiSample() || !sampler.isCombined())) continue; - if (grad && sampler.dim == EsdBuffer) + if (grad && sampler.isBuffer()) continue; if (proj + offset + fetch + grad + bias + lod > 3) continue; @@ -6632,29 +6652,46 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, if (extraProj && ! proj) continue; - if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined)) + if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.isCombined())) continue; - for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing + // loop over 16-bit floating-point texel addressing +#ifdef GLSLANG_WEB + const int f16TexAddr = 0; +#else + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) +#endif + { if (f16TexAddr && sampler.type != EbtFloat16) continue; if (f16TexAddr && sampler.shadow && ! compare) { compare = true; // compare argument is always present totalDims--; } - for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp - + // loop over "bool" lod clamp +#ifdef GLSLANG_WEB + const int lodClamp = 0; +#else + for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) +#endif + { if (lodClamp && (profile == EEsProfile || version < 450)) continue; if (lodClamp && (proj || lod || fetch)) continue; - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - + // loop over "bool" sparse or not +#ifdef GLSLANG_WEB + const int sparse = 0; +#else + for (int sparse = 0; sparse <= 1; ++sparse) +#endif + { if (sparse && (profile == EEsProfile || version < 450)) continue; - // Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture - if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) + // Sparse sampling is not for 1D/1D array texture, buffer texture, and + // projective texture + if (sparse && (sampler.is1D() || sampler.isBuffer() || proj)) continue; TString s; @@ -6727,8 +6764,9 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append(",float"); // non-optional lod argument (lod that's not driven by lod loop) or sample - if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || - (sampler.ms && fetch)) + if ((fetch && !sampler.isBuffer() && + !sampler.isRect() && !sampler.isMultiSample()) + || (sampler.isMultiSample() && fetch)) s.append(",int"); // non-optional lod if (lod) { @@ -6833,7 +6871,7 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in return; } - if (sampler.ms) + if (sampler.isMultiSample()) return; if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) @@ -9019,9 +9057,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("textureGradOffset", EOpTextureGradOffset); symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); - symbolTable.relateToOperator("textureGather", EOpTextureGather); #ifndef GLSLANG_WEB + symbolTable.relateToOperator("textureGather", EOpTextureGather); symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index da7b189ee..d852e08ba 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -1975,7 +1975,7 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const op = EOpConstructStruct; break; case EbtSampler: - if (type.getSampler().combined) + if (type.getSampler().isCombined()) op = EOpConstructTextureSampler; break; case EbtFloat: @@ -3835,7 +3835,7 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { void visitSymbol(TIntermSymbol* symbol) override { if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { - symbol->getWritableType().getSampler().combined = true; + symbol->getWritableType().getSampler().setCombined(true); } } bool visitAggregate(TVisit, TIntermAggregate* ag) override { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 8387e8fb1..038d95ab3 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -129,7 +129,7 @@ void TParseContext::setPrecisionDefaults() sampler.set(EbtFloat, EsdCube); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; sampler.set(EbtFloat, Esd2D); - sampler.external = true; + sampler.setExternal(true); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; } @@ -1215,9 +1215,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); } +#ifndef GLSLANG_WEB if (builtIn) nonOpBuiltInCheck(loc, *fnCandidate, *call); else +#endif userFunctionCallCheck(loc, *call); } @@ -1823,6 +1825,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan TString featureString; const char* feature = nullptr; switch (callNode.getOp()) { +#ifndef GLSLANG_WEB case EOpTextureGather: case EOpTextureGatherOffset: case EOpTextureGatherOffsets: @@ -1879,7 +1882,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan error(loc, "must be a compile-time constant:", feature, "component argument"); } -#ifndef GLSLANG_WEB bool bias = false; if (callNode.getOp() == EOpTextureGather) bias = fnCandidate.getParamCount() > 3; @@ -1894,12 +1896,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); } -#endif - break; } - -#ifndef GLSLANG_WEB case EOpSparseTextureGather: case EOpSparseTextureGatherOffset: case EOpSparseTextureGatherOffsets: @@ -1977,7 +1975,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan int arg = -1; switch (callNode.getOp()) { case EOpTextureOffset: arg = 2; break; - case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().dim != EsdRect) ? 3 : 2; break; + case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break; case EOpTextureProjOffset: arg = 2; break; case EOpTextureLodOffset: arg = 3; break; case EOpTextureProjLodOffset: arg = 3; break; @@ -2175,7 +2173,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan const TSampler& sampler = fnCandidate[0].type->getSampler(); const bool isTexture = sampler.isTexture() && !sampler.isCombined(); - const bool isBuffer = sampler.dim == EsdBuffer; + const bool isBuffer = sampler.isBuffer(); const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset; if (isTexture && (!isBuffer || !isFetch)) @@ -2195,6 +2193,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } +#ifndef GLSLANG_WEB + extern bool PureOperatorBuiltins; // Deprecated! Use PureOperatorBuiltins == true instead, in which case this @@ -2321,6 +2321,8 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn } } +#endif + // // Do any extra checking for a user function call. // @@ -3066,7 +3068,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const } // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() TSampler texture = function.getType().getSampler(); - texture.combined = false; + texture.setCombined(false); texture.shadow = false; if (texture != function[0].type->getSampler()) { error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); @@ -3118,14 +3120,14 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const { // Check that the appropriate extension is enabled if external sampler is used. // There are two extensions. The correct one must be used based on GLSL version. - if (type.getBasicType() == EbtSampler && type.getSampler().external) { + if (type.getBasicType() == EbtSampler && type.getSampler().isExternal()) { if (version < 300) { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES"); } else { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); } } - if (type.getSampler().yuv) { + if (type.getSampler().isYuv()) { requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT"); } @@ -3551,11 +3553,11 @@ void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publ // correlates with the declaration of defaultSamplerPrecision[] int TParseContext::computeSamplerTypeIndex(TSampler& sampler) { - int arrayIndex = sampler.arrayed ? 1 : 0; - int shadowIndex = sampler.shadow ? 1 : 0; - int externalIndex = sampler.external? 1 : 0; - int imageIndex = sampler.image ? 1 : 0; - int msIndex = sampler.ms ? 1 : 0; + int arrayIndex = sampler.arrayed ? 1 : 0; + int shadowIndex = sampler.shadow ? 1 : 0; + int externalIndex = sampler.isExternal() ? 1 : 0; + int imageIndex = sampler.isImageClass() ? 1 : 0; + int msIndex = sampler.isMultiSample() ? 1 : 0; int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) + externalIndex) + sampler.type) + sampler.dim; @@ -5916,12 +5918,14 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua { const char* message = "can only apply to a standalone qualifier"; +#ifndef GLSLANG_WEB if (shaderQualifiers.geometry != ElgNone) error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), ""); if (shaderQualifiers.spacing != EvsNone) error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), ""); if (shaderQualifiers.order != EvoNone) error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), ""); +#endif if (shaderQualifiers.pointMode) error(loc, message, "point_mode", ""); if (shaderQualifiers.invocations != TQualifier::layoutNotSet) diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 923856a5d..2f72a3646 100755 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -85,30 +85,32 @@ void TType::buildMangledName(TString& mangledName) const case EbtUint: mangledName += "u"; break; default: break; // some compilers want this } - if (sampler.image) - mangledName += "I"; // a normal image - else if (sampler.sampler) + if (sampler.isImageClass()) + mangledName += "I"; // a normal image or subpass + else if (sampler.isPureSampler()) mangledName += "p"; // a "pure" sampler - else if (!sampler.combined) + else if (!sampler.isCombined()) mangledName += "t"; // a "pure" texture else mangledName += "s"; // traditional combined sampler - if (sampler.arrayed) + if (sampler.isArrayed()) mangledName += "A"; - if (sampler.shadow) + if (sampler.isShadow()) mangledName += "S"; - if (sampler.external) + if (sampler.isExternal()) mangledName += "E"; - if (sampler.yuv) + if (sampler.isYuv()) mangledName += "Y"; switch (sampler.dim) { - case Esd1D: mangledName += "1"; break; case Esd2D: mangledName += "2"; break; case Esd3D: mangledName += "3"; break; case EsdCube: mangledName += "C"; break; +#ifndef GLSLANG_WEB + case Esd1D: mangledName += "1"; break; case EsdRect: mangledName += "R2"; break; case EsdBuffer: mangledName += "B"; break; case EsdSubpass: mangledName += "P"; break; +#endif default: break; // some compilers want this } @@ -117,7 +119,7 @@ void TType::buildMangledName(TString& mangledName) const mangledName += "-tx-struct"; char text[16]; // plenty enough space for the small integers. - snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex); + snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex()); mangledName += text; } else { switch (sampler.getVectorSize()) { @@ -128,7 +130,7 @@ void TType::buildMangledName(TString& mangledName) const } } - if (sampler.ms) + if (sampler.isMultiSample()) mangledName += "M"; break; case EbtStruct: