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.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

View File

@ -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)

View File

@ -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.

View File

@ -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:

View File

@ -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);

View File

@ -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 {

View File

@ -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)

View File

@ -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: