Web: Tighten up sampling code and interfaces.

Saves about 9K.
This commit is contained in:
John Kessenich 2019-08-08 01:15:24 -06:00
parent eaf4496312
commit 3e4b6ff76a
8 changed files with 217 additions and 139 deletions

View File

@ -1186,9 +1186,9 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getBasicType() == glslang::EbtSampler) {
if (baseType.getQualifier().hasAttachment()) if (baseType.getQualifier().hasAttachment())
builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT); builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT);
else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) else if (baseType.isImage() && baseType.getSampler().isBuffer())
builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT); builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT);
else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) else if (baseType.isTexture() && baseType.getSampler().isBuffer())
builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT); builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT);
else if (baseType.isImage()) else if (baseType.isImage())
builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT); builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT);
@ -1206,10 +1206,10 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
if (baseType.getQualifier().hasAttachment()) { if (baseType.getQualifier().hasAttachment()) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addExtension("SPV_EXT_descriptor_indexing");
builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT); 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.addExtension("SPV_EXT_descriptor_indexing");
builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT); 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.addExtension("SPV_EXT_descriptor_indexing");
builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT); builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);
} }
@ -3369,14 +3369,14 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case glslang::EbtSampler: case glslang::EbtSampler:
{ {
const glslang::TSampler& sampler = type.getSampler(); const glslang::TSampler& sampler = type.getSampler();
if (sampler.sampler) { if (sampler.isPureSampler()) {
// pure sampler
spvType = builder.makeSamplerType(); spvType = builder.makeSamplerType();
} else { } else {
// an image is present, make its type // an image is present, make its type
spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler),
sampler.image ? 2 : 1, TranslateImageFormat(type)); sampler.isShadow(), sampler.isArrayed(), sampler.isMultiSample(),
if (sampler.combined) { sampler.isImageClass() ? 2 : 1, TranslateImageFormat(type));
if (sampler.isCombined()) {
// already has both image and sampler, make the combined type // already has both image and sampler, make the combined type
spvType = builder.makeSampledImageType(spvType); spvType = builder.makeSampledImageType(spvType);
} }
@ -4455,12 +4455,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
operands.push_back(coord); operands.push_back(coord);
spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone }; spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone };
imageOperands.word = imageOperands.word | signExtensionMask(); imageOperands.word = imageOperands.word | signExtensionMask();
if (sampler.ms) { if (sampler.isMultiSample()) {
imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask; imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask;
} }
if (imageOperands.word != spv::ImageOperandsMaskNone) { if (imageOperands.word != spv::ImageOperandsMaskNone) {
operands.push_back(imageOperands); operands.push_back(imageOperands);
if (sampler.ms) { if (sampler.isMultiSample()) {
spv::IdImmediate imageOperand = { true, *(opIt++) }; spv::IdImmediate imageOperand = { true, *(opIt++) };
operands.push_back(imageOperand); operands.push_back(imageOperand);
} }
@ -4474,7 +4474,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
operands.push_back(coord); operands.push_back(coord);
if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) {
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
if (sampler.ms) { if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask; mask = mask | spv::ImageOperandsSampleMask;
} }
if (cracked.lod) { if (cracked.lod) {
@ -4517,7 +4517,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) { } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) {
// Push the texel value before the operands // Push the texel value before the operands
if (sampler.ms || cracked.lod) { if (sampler.isMultiSample() || cracked.lod) {
spv::IdImmediate texel = { true, *(opIt + 1) }; spv::IdImmediate texel = { true, *(opIt + 1) };
operands.push_back(texel); operands.push_back(texel);
} else { } else {
@ -4526,7 +4526,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} }
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
if (sampler.ms) { if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask; mask = mask | spv::ImageOperandsSampleMask;
} }
if (cracked.lod) { if (cracked.lod) {
@ -4566,7 +4566,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat); builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
if (sampler.ms) { if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask; mask = mask | spv::ImageOperandsSampleMask;
} }
if (cracked.lod) { 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, // 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. // as the first source operand, is required by SPIR-V atomic operations.
// For non-MS, the sample value should be 0 // 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); operands.push_back(sample);
spv::Id resultTypeId; spv::Id resultTypeId;
@ -4676,7 +4676,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
// Check for texture functions other than queries // Check for texture functions other than queries
bool sparse = node->isSparseTexture(); bool sparse = node->isSparseTexture();
bool imageFootprint = node->isImageFootprint(); 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 // check for bias argument
bool bias = false; bool bias = false;
@ -4763,7 +4763,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} }
// multisample // multisample
if (sampler.ms) { if (sampler.isMultiSample()) {
params.sample = arguments[2 + extraArgs]; // For MS, "sample" should be specified params.sample = arguments[2 + extraArgs]; // For MS, "sample" should be specified
++extraArgs; ++extraArgs;
} }
@ -4784,6 +4784,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
++extraArgs; ++extraArgs;
} }
#ifndef GLSLANG_WEB
// lod clamp // lod clamp
if (cracked.lodClamp) { if (cracked.lodClamp) {
params.lodClamp = arguments[2 + extraArgs]; params.lodClamp = arguments[2 + extraArgs];
@ -4794,7 +4795,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
params.texelOut = arguments[2 + extraArgs]; params.texelOut = arguments[2 + extraArgs];
++extraArgs; ++extraArgs;
} }
// gather component // gather component
if (cracked.gather && ! sampler.shadow) { if (cracked.gather && ! sampler.shadow) {
// default component is 0, if missing, otherwise an argument // default component is 0, if missing, otherwise an argument
@ -4804,7 +4804,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} else } else
params.component = builder.makeIntConstant(0); params.component = builder.makeIntConstant(0);
} }
#ifndef GLSLANG_WEB
spv::Id resultStruct = spv::NoResult; spv::Id resultStruct = spv::NoResult;
if (imageFootprint) { if (imageFootprint) {
//Following three extra arguments //Following three extra arguments

View File

@ -1908,7 +1908,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
} else if (parameters.granularity && parameters.coarse) { } else if (parameters.granularity && parameters.coarse) {
opCode = OpImageSampleFootprintNV; opCode = OpImageSampleFootprintNV;
#endif
} else if (gather) { } else if (gather) {
if (parameters.Dref) if (parameters.Dref)
if (sparse) if (sparse)
@ -1920,6 +1919,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
opCode = OpImageSparseGather; opCode = OpImageSparseGather;
else else
opCode = OpImageGather; opCode = OpImageGather;
#endif
} else if (explicitLod) { } else if (explicitLod) {
if (parameters.Dref) { if (parameters.Dref) {
if (proj) if (proj)

View File

@ -84,6 +84,27 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool yuv : 1; // GL_EXT_YUV_target bool yuv : 1; // GL_EXT_YUV_target
unsigned int vectorSize : 3; // vector return type size. 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 // 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. // 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 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. // Index into a language specific table of texture return structures.
unsigned int structReturnIndex : structReturnIndexBits; unsigned int structReturnIndex : structReturnIndexBits;
// Encapsulate getting members' vector sizes packed into the vectorSize bitfield. void clearReturnStruct() { structReturnIndex = noReturnStruct; }
unsigned int getVectorSize() const { return vectorSize; } bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
unsigned getStructReturnIndex() const { return structReturnIndex; }
bool isImage() const { return image && dim != EsdSubpass; } 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 isSubpass() const { return dim == EsdSubpass; }
bool isCombined() const { return combined; } bool isCombined() const { return combined; }
bool isPureSampler() const { return sampler; } bool isPureSampler() const { return sampler; }
bool isTexture() const { return !sampler && !image; } 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 isShadow() const { return shadow; }
bool isArrayed() const { return arrayed; } bool isArrayed() const { return arrayed; }
bool isMultiSample() const { return ms; }
bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
void clear() void clear()
{ {
@ -118,7 +147,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
sampler = false; sampler = false;
external = false; external = false;
yuv = false; yuv = false;
structReturnIndex = noReturnStruct; clearReturnStruct();
// by default, returns a single vec4; // by default, returns a single vec4;
vectorSize = 4; vectorSize = 4;
@ -183,14 +212,14 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
dim == right.dim && dim == right.dim &&
arrayed == right.arrayed && arrayed == right.arrayed &&
shadow == right.shadow && shadow == right.shadow &&
ms == right.ms && isMultiSample() == right.isMultiSample() &&
image == right.image && isImageClass() == right.isImageClass() &&
combined == right.combined && isCombined() == right.isCombined() &&
sampler == right.sampler && isPureSampler() == right.isPureSampler() &&
external == right.external && isExternal() == right.isExternal() &&
yuv == right.yuv && isYuv() == right.isYuv() &&
vectorSize == right.vectorSize && vectorSize == right.vectorSize &&
structReturnIndex == right.structReturnIndex; getStructReturnIndex() == right.getStructReturnIndex();
} }
bool operator!=(const TSampler& right) const bool operator!=(const TSampler& right) const
@ -202,13 +231,12 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
{ {
TString s; TString s;
if (sampler) { if (isPureSampler()) {
s.append("sampler"); s.append("sampler");
return s; return s;
} }
switch (type) { switch (type) {
case EbtFloat: break;
case EbtInt: s.append("i"); break; case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); break; case EbtUint: s.append("u"); break;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
@ -222,34 +250,36 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
#endif #endif
default: break; default: break;
} }
if (image) { if (isImageClass()) {
if (dim == EsdSubpass) if (isSubpass())
s.append("subpass"); s.append("subpass");
else else
s.append("image"); s.append("image");
} else if (combined) { } else if (isCombined()) {
s.append("sampler"); s.append("sampler");
} else { } else {
s.append("texture"); s.append("texture");
} }
if (external) { if (isExternal()) {
s.append("ExternalOES"); s.append("ExternalOES");
return s; return s;
} }
if (yuv) { if (isYuv()) {
return "__" + s + "External2DY2YEXT"; return "__" + s + "External2DY2YEXT";
} }
switch (dim) { switch (dim) {
case Esd1D: s.append("1D"); break;
case Esd2D: s.append("2D"); break; case Esd2D: s.append("2D"); break;
case Esd3D: s.append("3D"); break; case Esd3D: s.append("3D"); break;
case EsdCube: s.append("Cube"); break; case EsdCube: s.append("Cube"); break;
#ifndef GLSLANG_WEB
case Esd1D: s.append("1D"); break;
case EsdRect: s.append("2DRect"); break; case EsdRect: s.append("2DRect"); break;
case EsdBuffer: s.append("Buffer"); break; case EsdBuffer: s.append("Buffer"); break;
case EsdSubpass: s.append("Input"); break; case EsdSubpass: s.append("Input"); break;
#endif
default: break; // some compilers want this default: break; // some compilers want this
} }
if (ms) if (isMultiSample())
s.append("MS"); s.append("MS");
if (arrayed) if (arrayed)
s.append("Array"); s.append("Array");
@ -897,6 +927,7 @@ public:
bool isShaderRecordNV() const { return false; } bool isShaderRecordNV() const { return false; }
bool hasBufferReference() const { return false; } bool hasBufferReference() const { return false; }
bool hasBufferReferenceAlign() const { return false; } bool hasBufferReferenceAlign() const { return false; }
bool isNonUniform() const { return false; }
#else #else
bool isNonPerspective() const { return nopersp; } bool isNonPerspective() const { return nopersp; }
bool hasIndex() const bool hasIndex() const
@ -945,6 +976,10 @@ public:
{ {
return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd; return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd;
} }
bool isNonUniform() const
{
return nonUniform;
}
#endif #endif
bool hasSpecConstantId() const bool hasSpecConstantId() const
{ {
@ -959,10 +994,6 @@ public:
// true front-end constant. // true front-end constant.
return specConstant; return specConstant;
} }
bool isNonUniform() const
{
return nonUniform;
}
bool isFrontEndConstant() const bool isFrontEndConstant() const
{ {
// True if the front-end knows the final constant value. // True if the front-end knows the final constant value.
@ -998,6 +1029,9 @@ public:
default: return "none"; default: return "none";
} }
} }
#ifdef GLSLANG_WEB
static const char* getLayoutFormatString(TLayoutFormat f) { return "none"; }
#else
static const char* getLayoutFormatString(TLayoutFormat f) static const char* getLayoutFormatString(TLayoutFormat f)
{ {
switch (f) { switch (f) {
@ -1132,6 +1166,7 @@ public:
default: return "none"; default: return "none";
} }
} }
#endif
}; };
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope. // Qualifiers that don't need to be keep per object. They have shader scope, not object scope.

View File

@ -1377,14 +1377,14 @@ public:
case EOpTextureFetch: case EOpTextureFetch:
case EOpSparseTextureFetch: case EOpSparseTextureFetch:
cracked.fetch = true; 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; cracked.lod = true;
break; break;
case EOpTextureFetchOffset: case EOpTextureFetchOffset:
case EOpSparseTextureFetchOffset: case EOpSparseTextureFetchOffset:
cracked.fetch = true; cracked.fetch = true;
cracked.offset = 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; cracked.lod = true;
break; break;
case EOpTextureProjOffset: case EOpTextureProjOffset:

View File

@ -435,25 +435,30 @@ TBuiltIns::TBuiltIns()
// Set up textual representations for making all the permutations // Set up textual representations for making all the permutations
// of texturing/imaging functions. // of texturing/imaging functions.
prefixes[EbtFloat] = ""; prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u";
#ifndef GLSLANG_WEB
prefixes[EbtFloat16] = "f16"; prefixes[EbtFloat16] = "f16";
prefixes[EbtInt8] = "i8"; prefixes[EbtInt8] = "i8";
prefixes[EbtUint8] = "u8"; prefixes[EbtUint8] = "u8";
prefixes[EbtInt16] = "i16"; prefixes[EbtInt16] = "i16";
prefixes[EbtUint16] = "u16"; prefixes[EbtUint16] = "u16";
prefixes[EbtInt] = "i"; #endif
prefixes[EbtUint] = "u";
postfixes[2] = "2"; postfixes[2] = "2";
postfixes[3] = "3"; postfixes[3] = "3";
postfixes[4] = "4"; postfixes[4] = "4";
// Map from symbolic class of texturing dimension to numeric dimensions. // Map from symbolic class of texturing dimension to numeric dimensions.
dimMap[Esd1D] = 1;
dimMap[Esd2D] = 2; dimMap[Esd2D] = 2;
dimMap[EsdRect] = 2;
dimMap[Esd3D] = 3; dimMap[Esd3D] = 3;
dimMap[EsdCube] = 3; dimMap[EsdCube] = 3;
#ifndef GLSLANG_WEB
dimMap[Esd1D] = 1;
dimMap[EsdRect] = 2;
dimMap[EsdBuffer] = 1; dimMap[EsdBuffer] = 1;
dimMap[EsdSubpass] = 2; // potientially unused for now dimMap[EsdSubpass] = 2; // potientially unused for now
#endif
} }
TBuiltIns::~TBuiltIns() 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 // In this function proper, enumerate the types, then calls the next set of functions
// to enumerate all the uses for that type. // 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 skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
// enumerate all the types // enumerate all the types
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint };
const int image = 0; const int image = 0;
#else #else
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 };
for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler
#endif #endif
{ {
for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
const int ms = 0; const int ms = 0;
@ -6169,6 +6174,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
for (int ms = 0; ms <= 1; ++ms) for (int ms = 0; ms <= 1; ++ms)
#endif #endif
{ {
#ifndef GLSLANG_WEB
if ((ms || image) && shadow) if ((ms || image) && shadow)
continue; continue;
if (ms && profile != EEsProfile && version < 150) if (ms && profile != EEsProfile && version < 150)
@ -6177,19 +6183,19 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
continue; continue;
if (ms && profile == EEsProfile && version < 310) if (ms && profile == EEsProfile && version < 310)
continue; continue;
#endif
for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not
#ifdef GLSLANG_WEB #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 #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) if (dim == EsdSubpass && spvVersion.vulkan == 0)
continue; continue;
if (dim == EsdSubpass && (image || shadow || arrayed)) if (dim == EsdSubpass && (image || shadow || arrayed))
continue; continue;
if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile)
continue; continue;
#endif
if (dim == EsdSubpass && spvVersion.vulkan == 0) if (dim == EsdSubpass && spvVersion.vulkan == 0)
continue; continue;
if (dim == EsdSubpass && (image || shadow || arrayed)) if (dim == EsdSubpass && (image || shadow || arrayed))
@ -6198,32 +6204,34 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
continue; continue;
if (dim != Esd2D && dim != EsdSubpass && ms) if (dim != Esd2D && dim != EsdSubpass && ms)
continue; continue;
if ((dim == Esd3D || dim == EsdRect) && arrayed)
continue;
if (dim == Esd3D && shadow)
continue;
if (dim == EsdCube && arrayed && skipCubeArrayed)
continue;
if (dim == EsdBuffer && skipBuffer) if (dim == EsdBuffer && skipBuffer)
continue; continue;
if (dim == EsdBuffer && (shadow || arrayed || ms)) if (dim == EsdBuffer && (shadow || arrayed || ms))
continue; continue;
if (ms && arrayed && profile == EEsProfile && version < 310) if (ms && arrayed && profile == EEsProfile && version < 310)
continue; 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) // Loop over the bTypes
continue; for (int bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) {
#ifndef GLSLANG_WEB
if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile ||version < 450)) if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450))
continue; continue;
if (dim == EsdRect && version < 140 && bType > 0) if (dim == EsdRect && version < 140 && bType > 0)
continue; continue;
#endif
if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint))
continue;
// //
// Now, make all the function prototypes for the type we just built... // Now, make all the function prototypes for the type we just built...
// //
TSampler sampler; TSampler sampler;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (dim == EsdSubpass) { if (dim == EsdSubpass) {
@ -6280,13 +6288,14 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
} }
} }
#ifndef GLSLANG_WEB
// //
// sparseTexelsResidentARB() // sparseTexelsResidentARB()
// //
if (profile != EEsProfile && version >= 450) { if (profile != EEsProfile && version >= 450) {
commonBuiltins.append("bool sparseTexelsResidentARB(int code);\n"); 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) 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() // textureSize() and imageSize()
// //
int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); 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) if (profile == EEsProfile)
commonBuiltins.append("highp "); commonBuiltins.append("highp ");
if (sizeDims == 1) if (sizeDims == 1)
@ -6313,28 +6333,25 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
commonBuiltins.append("ivec"); commonBuiltins.append("ivec");
commonBuiltins.append(postfixes[sizeDims]); commonBuiltins.append(postfixes[sizeDims]);
} }
#ifndef GLSLANG_WEB if (sampler.isImage())
if (sampler.image)
commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); commonBuiltins.append(" imageSize(readonly writeonly volatile coherent ");
else else
#endif
commonBuiltins.append(" textureSize("); commonBuiltins.append(" textureSize(");
commonBuiltins.append(typeName); 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"); commonBuiltins.append(",int);\n");
else else
commonBuiltins.append(");\n"); commonBuiltins.append(");\n");
#ifndef GLSLANG_WEB
// //
// textureSamples() and imageSamples() // textureSamples() and imageSamples()
// //
// GL_ARB_shader_texture_image_samples // GL_ARB_shader_texture_image_samples
// TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? // 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 "); commonBuiltins.append("int ");
if (sampler.image) if (sampler.isImage())
commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); commonBuiltins.append("imageSamples(readonly writeonly volatile coherent ");
else else
commonBuiltins.append("textureSamples("); commonBuiltins.append("textureSamples(");
@ -6346,7 +6363,8 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
// textureQueryLod(), fragment stage only // 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) { for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
if (f16TexAddr && sampler.type != EbtFloat16) if (f16TexAddr && sampler.type != EbtFloat16)
continue; continue;
@ -6382,12 +6400,12 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
// textureQueryLevels() // 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("int textureQueryLevels(");
commonBuiltins.append(typeName); commonBuiltins.append(typeName);
commonBuiltins.append(");\n"); commonBuiltins.append(");\n");
} }
#endif
} }
// //
@ -6410,7 +6428,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
imageParams.append(", ivec"); imageParams.append(", ivec");
imageParams.append(postfixes[dims]); imageParams.append(postfixes[dims]);
} }
if (sampler.ms) if (sampler.isMultiSample())
imageParams.append(", int"); imageParams.append(", int");
if (profile == EEsProfile) if (profile == EEsProfile)
@ -6426,7 +6444,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append(prefixes[sampler.type]);
commonBuiltins.append("vec4);\n"); 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("int sparseImageLoadARB(readonly volatile coherent ");
commonBuiltins.append(imageParams); commonBuiltins.append(imageParams);
commonBuiltins.append(", out "); 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; return;
if (profile == EEsProfile || version < 450) 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(prefixes[sampler.type]);
commonBuiltins.append("vec4);\n"); commonBuiltins.append("vec4);\n");
if (sampler.dim != Esd1D) { if (! sampler.is1D()) {
commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent "); commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent ");
commonBuiltins.append(imageLodParams); commonBuiltins.append(imageLodParams);
commonBuiltins.append(", out "); commonBuiltins.append(", out ");
@ -6551,7 +6569,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in
stageBuiltins[EShLangFragment].append("vec4 subpassLoad"); stageBuiltins[EShLangFragment].append("vec4 subpassLoad");
stageBuiltins[EShLangFragment].append("("); stageBuiltins[EShLangFragment].append("(");
stageBuiltins[EShLangFragment].append(typeName.c_str()); stageBuiltins[EShLangFragment].append(typeName.c_str());
if (sampler.ms) if (sampler.isMultiSample())
stageBuiltins[EShLangFragment].append(", int"); stageBuiltins[EShLangFragment].append(", int");
stageBuiltins[EShLangFragment].append(");\n"); 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 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; continue;
for (int lod = 0; lod <= 1; ++lod) { 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; continue;
if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow)
continue; continue;
@ -6583,18 +6602,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
for (int bias = 0; bias <= 1; ++bias) { for (int bias = 0; bias <= 1; ++bias) {
if (bias && (lod || sampler.ms || !sampler.combined)) if (bias && (lod || sampler.isMultiSample() || !sampler.isCombined()))
continue; continue;
if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed)
continue; continue;
if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) if (bias && (sampler.isRect() || sampler.isBuffer()))
continue; continue;
for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not
if (proj + offset + bias + lod > 3) if (proj + offset + bias + lod > 3)
continue; continue;
if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) if (offset && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.isMultiSample()))
continue; continue;
for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not 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; continue;
if (fetch && (sampler.shadow || sampler.dim == EsdCube)) if (fetch && (sampler.shadow || sampler.dim == EsdCube))
continue; continue;
if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined)) if (fetch == 0 && (sampler.isMultiSample() || sampler.isBuffer()
|| !sampler.isCombined()))
continue; continue;
for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not 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; continue;
if (grad && sampler.dim == EsdBuffer) if (grad && sampler.isBuffer())
continue; continue;
if (proj + offset + fetch + grad + bias + lod > 3) if (proj + offset + fetch + grad + bias + lod > 3)
continue; continue;
@ -6632,29 +6652,46 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
if (extraProj && ! proj) if (extraProj && ! proj)
continue; continue;
if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined)) if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.isCombined()))
continue; 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) if (f16TexAddr && sampler.type != EbtFloat16)
continue; continue;
if (f16TexAddr && sampler.shadow && ! compare) { if (f16TexAddr && sampler.shadow && ! compare) {
compare = true; // compare argument is always present compare = true; // compare argument is always present
totalDims--; 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)) if (lodClamp && (profile == EEsProfile || version < 450))
continue; continue;
if (lodClamp && (proj || lod || fetch)) if (lodClamp && (proj || lod || fetch))
continue; 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)) if (sparse && (profile == EEsProfile || version < 450))
continue; continue;
// Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture // Sparse sampling is not for 1D/1D array texture, buffer texture, and
if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) // projective texture
if (sparse && (sampler.is1D() || sampler.isBuffer() || proj))
continue; continue;
TString s; TString s;
@ -6727,8 +6764,9 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
s.append(",float"); s.append(",float");
// non-optional lod argument (lod that's not driven by lod loop) or sample // non-optional lod argument (lod that's not driven by lod loop) or sample
if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || if ((fetch && !sampler.isBuffer() &&
(sampler.ms && fetch)) !sampler.isRect() && !sampler.isMultiSample())
|| (sampler.isMultiSample() && fetch))
s.append(",int"); s.append(",int");
// non-optional lod // non-optional lod
if (lod) { if (lod) {
@ -6833,7 +6871,7 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in
return; return;
} }
if (sampler.ms) if (sampler.isMultiSample())
return; return;
if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) 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("textureGradOffset", EOpTextureGradOffset);
symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad);
symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset);
symbolTable.relateToOperator("textureGather", EOpTextureGather);
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
symbolTable.relateToOperator("textureGather", EOpTextureGather);
symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset);
symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets);

View File

@ -1975,7 +1975,7 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
op = EOpConstructStruct; op = EOpConstructStruct;
break; break;
case EbtSampler: case EbtSampler:
if (type.getSampler().combined) if (type.getSampler().isCombined())
op = EOpConstructTextureSampler; op = EOpConstructTextureSampler;
break; break;
case EbtFloat: case EbtFloat:
@ -3835,7 +3835,7 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
void visitSymbol(TIntermSymbol* symbol) override { void visitSymbol(TIntermSymbol* symbol) override {
if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
symbol->getWritableType().getSampler().combined = true; symbol->getWritableType().getSampler().setCombined(true);
} }
} }
bool visitAggregate(TVisit, TIntermAggregate* ag) override { bool visitAggregate(TVisit, TIntermAggregate* ag) override {

View File

@ -129,7 +129,7 @@ void TParseContext::setPrecisionDefaults()
sampler.set(EbtFloat, EsdCube); sampler.set(EbtFloat, EsdCube);
defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
sampler.set(EbtFloat, Esd2D); sampler.set(EbtFloat, Esd2D);
sampler.external = true; sampler.setExternal(true);
defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
} }
@ -1215,9 +1215,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
} }
#ifndef GLSLANG_WEB
if (builtIn) if (builtIn)
nonOpBuiltInCheck(loc, *fnCandidate, *call); nonOpBuiltInCheck(loc, *fnCandidate, *call);
else else
#endif
userFunctionCallCheck(loc, *call); userFunctionCallCheck(loc, *call);
} }
@ -1823,6 +1825,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
TString featureString; TString featureString;
const char* feature = nullptr; const char* feature = nullptr;
switch (callNode.getOp()) { switch (callNode.getOp()) {
#ifndef GLSLANG_WEB
case EOpTextureGather: case EOpTextureGather:
case EOpTextureGatherOffset: case EOpTextureGatherOffset:
case EOpTextureGatherOffsets: 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"); error(loc, "must be a compile-time constant:", feature, "component argument");
} }
#ifndef GLSLANG_WEB
bool bias = false; bool bias = false;
if (callNode.getOp() == EOpTextureGather) if (callNode.getOp() == EOpTextureGather)
bias = fnCandidate.getParamCount() > 3; bias = fnCandidate.getParamCount() > 3;
@ -1894,12 +1896,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
profileRequires(loc, ~EEsProfile, 450, nullptr, feature); profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
} }
#endif
break; break;
} }
#ifndef GLSLANG_WEB
case EOpSparseTextureGather: case EOpSparseTextureGather:
case EOpSparseTextureGatherOffset: case EOpSparseTextureGatherOffset:
case EOpSparseTextureGatherOffsets: case EOpSparseTextureGatherOffsets:
@ -1977,7 +1975,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
int arg = -1; int arg = -1;
switch (callNode.getOp()) { switch (callNode.getOp()) {
case EOpTextureOffset: arg = 2; break; 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 EOpTextureProjOffset: arg = 2; break;
case EOpTextureLodOffset: arg = 3; break; case EOpTextureLodOffset: arg = 3; break;
case EOpTextureProjLodOffset: 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 TSampler& sampler = fnCandidate[0].type->getSampler();
const bool isTexture = sampler.isTexture() && !sampler.isCombined(); 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; const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset;
if (isTexture && (!isBuffer || !isFetch)) if (isTexture && (!isBuffer || !isFetch))
@ -2195,6 +2193,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
} }
} }
#ifndef GLSLANG_WEB
extern bool PureOperatorBuiltins; extern bool PureOperatorBuiltins;
// Deprecated! Use PureOperatorBuiltins == true instead, in which case this // 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. // 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!=() // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
TSampler texture = function.getType().getSampler(); TSampler texture = function.getType().getSampler();
texture.combined = false; texture.setCombined(false);
texture.shadow = false; texture.shadow = false;
if (texture != function[0].type->getSampler()) { if (texture != function[0].type->getSampler()) {
error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); 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. // 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. // 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) { if (version < 300) {
requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES"); requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES");
} else { } else {
requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); 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"); 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[] // correlates with the declaration of defaultSamplerPrecision[]
int TParseContext::computeSamplerTypeIndex(TSampler& sampler) int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
{ {
int arrayIndex = sampler.arrayed ? 1 : 0; int arrayIndex = sampler.arrayed ? 1 : 0;
int shadowIndex = sampler.shadow ? 1 : 0; int shadowIndex = sampler.shadow ? 1 : 0;
int externalIndex = sampler.external? 1 : 0; int externalIndex = sampler.isExternal() ? 1 : 0;
int imageIndex = sampler.image ? 1 : 0; int imageIndex = sampler.isImageClass() ? 1 : 0;
int msIndex = sampler.ms ? 1 : 0; int msIndex = sampler.isMultiSample() ? 1 : 0;
int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) + int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) +
externalIndex) + sampler.type) + sampler.dim; 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"; const char* message = "can only apply to a standalone qualifier";
#ifndef GLSLANG_WEB
if (shaderQualifiers.geometry != ElgNone) if (shaderQualifiers.geometry != ElgNone)
error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), ""); error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
if (shaderQualifiers.spacing != EvsNone) if (shaderQualifiers.spacing != EvsNone)
error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), ""); error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), "");
if (shaderQualifiers.order != EvoNone) if (shaderQualifiers.order != EvoNone)
error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), ""); error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), "");
#endif
if (shaderQualifiers.pointMode) if (shaderQualifiers.pointMode)
error(loc, message, "point_mode", ""); error(loc, message, "point_mode", "");
if (shaderQualifiers.invocations != TQualifier::layoutNotSet) if (shaderQualifiers.invocations != TQualifier::layoutNotSet)

View File

@ -85,30 +85,32 @@ void TType::buildMangledName(TString& mangledName) const
case EbtUint: mangledName += "u"; break; case EbtUint: mangledName += "u"; break;
default: break; // some compilers want this default: break; // some compilers want this
} }
if (sampler.image) if (sampler.isImageClass())
mangledName += "I"; // a normal image mangledName += "I"; // a normal image or subpass
else if (sampler.sampler) else if (sampler.isPureSampler())
mangledName += "p"; // a "pure" sampler mangledName += "p"; // a "pure" sampler
else if (!sampler.combined) else if (!sampler.isCombined())
mangledName += "t"; // a "pure" texture mangledName += "t"; // a "pure" texture
else else
mangledName += "s"; // traditional combined sampler mangledName += "s"; // traditional combined sampler
if (sampler.arrayed) if (sampler.isArrayed())
mangledName += "A"; mangledName += "A";
if (sampler.shadow) if (sampler.isShadow())
mangledName += "S"; mangledName += "S";
if (sampler.external) if (sampler.isExternal())
mangledName += "E"; mangledName += "E";
if (sampler.yuv) if (sampler.isYuv())
mangledName += "Y"; mangledName += "Y";
switch (sampler.dim) { switch (sampler.dim) {
case Esd1D: mangledName += "1"; break;
case Esd2D: mangledName += "2"; break; case Esd2D: mangledName += "2"; break;
case Esd3D: mangledName += "3"; break; case Esd3D: mangledName += "3"; break;
case EsdCube: mangledName += "C"; break; case EsdCube: mangledName += "C"; break;
#ifndef GLSLANG_WEB
case Esd1D: mangledName += "1"; break;
case EsdRect: mangledName += "R2"; break; case EsdRect: mangledName += "R2"; break;
case EsdBuffer: mangledName += "B"; break; case EsdBuffer: mangledName += "B"; break;
case EsdSubpass: mangledName += "P"; break; case EsdSubpass: mangledName += "P"; break;
#endif
default: break; // some compilers want this default: break; // some compilers want this
} }
@ -117,7 +119,7 @@ void TType::buildMangledName(TString& mangledName) const
mangledName += "-tx-struct"; mangledName += "-tx-struct";
char text[16]; // plenty enough space for the small integers. 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; mangledName += text;
} else { } else {
switch (sampler.getVectorSize()) { switch (sampler.getVectorSize()) {
@ -128,7 +130,7 @@ void TType::buildMangledName(TString& mangledName) const
} }
} }
if (sampler.ms) if (sampler.isMultiSample())
mangledName += "M"; mangledName += "M";
break; break;
case EbtStruct: case EbtStruct: