Refactor Builder::createTextureCall() to use std::vector

Use a temporary std::vector to accumulate arguments, rather than a
stack-allocated array with a fixed size. This is safer and more
future-proof.
This commit is contained in:
Arcady Goldmints-Orlov 2023-03-31 17:01:56 -06:00 committed by arcady-lunarg
parent 45405e1d94
commit 2aca6d419c

View File

@ -2758,52 +2758,49 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const
Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask) bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
{ {
static const int maxTextureArgs = 10; std::vector<Id> texArgs;
Id texArgs[maxTextureArgs] = {};
// //
// Set up the fixed arguments // Set up the fixed arguments
// //
int numArgs = 0;
bool explicitLod = false; bool explicitLod = false;
texArgs[numArgs++] = parameters.sampler; texArgs.push_back(parameters.sampler);
texArgs[numArgs++] = parameters.coords; texArgs.push_back(parameters.coords);
if (parameters.Dref != NoResult) if (parameters.Dref != NoResult)
texArgs[numArgs++] = parameters.Dref; texArgs.push_back(parameters.Dref);
if (parameters.component != NoResult) if (parameters.component != NoResult)
texArgs[numArgs++] = parameters.component; texArgs.push_back(parameters.component);
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (parameters.granularity != NoResult) if (parameters.granularity != NoResult)
texArgs[numArgs++] = parameters.granularity; texArgs.push_back(parameters.granularity);
if (parameters.coarse != NoResult) if (parameters.coarse != NoResult)
texArgs[numArgs++] = parameters.coarse; texArgs.push_back(parameters.coarse);
#endif #endif
// //
// Set up the optional arguments // Set up the optional arguments
// //
int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments size_t optArgNum = texArgs.size(); // the position of the mask for the optional arguments, if any.
++numArgs; // speculatively make room for the mask operand
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
if (parameters.bias) { if (parameters.bias) {
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask); mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
texArgs[numArgs++] = parameters.bias; texArgs.push_back(parameters.bias);
} }
if (parameters.lod) { if (parameters.lod) {
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
texArgs[numArgs++] = parameters.lod; texArgs.push_back(parameters.lod);
explicitLod = true; explicitLod = true;
} else if (parameters.gradX) { } else if (parameters.gradX) {
mask = (ImageOperandsMask)(mask | ImageOperandsGradMask); mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
texArgs[numArgs++] = parameters.gradX; texArgs.push_back(parameters.gradX);
texArgs[numArgs++] = parameters.gradY; texArgs.push_back(parameters.gradY);
explicitLod = true; explicitLod = true;
} else if (noImplicitLod && ! fetch && ! gather) { } else if (noImplicitLod && ! fetch && ! gather) {
// have to explicitly use lod of 0 if not allowed to have them be implicit, and // have to explicitly use lod of 0 if not allowed to have them be implicit, and
// we would otherwise be about to issue an implicit instruction // we would otherwise be about to issue an implicit instruction
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
texArgs[numArgs++] = makeFloatConstant(0.0); texArgs.push_back(makeFloatConstant(0.0));
explicitLod = true; explicitLod = true;
} }
if (parameters.offset) { if (parameters.offset) {
@ -2813,24 +2810,24 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
addCapability(CapabilityImageGatherExtended); addCapability(CapabilityImageGatherExtended);
mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask); mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
} }
texArgs[numArgs++] = parameters.offset; texArgs.push_back(parameters.offset);
} }
if (parameters.offsets) { if (parameters.offsets) {
addCapability(CapabilityImageGatherExtended); addCapability(CapabilityImageGatherExtended);
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
texArgs[numArgs++] = parameters.offsets; texArgs.push_back(parameters.offsets);
} }
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (parameters.sample) { if (parameters.sample) {
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
texArgs[numArgs++] = parameters.sample; texArgs.push_back(parameters.sample);
} }
if (parameters.lodClamp) { if (parameters.lodClamp) {
// capability if this bit is used // capability if this bit is used
addCapability(CapabilityMinLod); addCapability(CapabilityMinLod);
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask); mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
texArgs[numArgs++] = parameters.lodClamp; texArgs.push_back(parameters.lodClamp);
} }
if (parameters.nonprivate) { if (parameters.nonprivate) {
mask = mask | ImageOperandsNonPrivateTexelKHRMask; mask = mask | ImageOperandsNonPrivateTexelKHRMask;
@ -2840,10 +2837,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
} }
#endif #endif
mask = mask | signExtensionMask; mask = mask | signExtensionMask;
if (mask == ImageOperandsMaskNone) // insert the operand for the mask, if any bits were set.
--numArgs; // undo speculative reservation for the mask argument if (mask != ImageOperandsMaskNone)
else texArgs.insert(texArgs.begin() + optArgNum, mask);
texArgs[optArgNum] = mask;
// //
// Set up the instruction // Set up the instruction
@ -2947,11 +2943,11 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// Build the SPIR-V instruction // Build the SPIR-V instruction
Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode); Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
for (int op = 0; op < optArgNum; ++op) for (size_t op = 0; op < optArgNum; ++op)
textureInst->addIdOperand(texArgs[op]); textureInst->addIdOperand(texArgs[op]);
if (optArgNum < numArgs) if (optArgNum < texArgs.size())
textureInst->addImmediateOperand(texArgs[optArgNum]); textureInst->addImmediateOperand(texArgs[optArgNum]);
for (int op = optArgNum + 1; op < numArgs; ++op) for (size_t op = optArgNum + 1; op < texArgs.size(); ++op)
textureInst->addIdOperand(texArgs[op]); textureInst->addIdOperand(texArgs[op]);
setPrecision(textureInst->getResultId(), precision); setPrecision(textureInst->getResultId(), precision);
buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst)); buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));