SPV 1.4: Emit SignExtend and ZeroExtend for integer image reads/writes.
This commit is contained in:
parent
61a5ce190a
commit
f43c739ac5
11 changed files with 766 additions and 20 deletions
|
|
@ -4182,15 +4182,26 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
|
||||
// Process a GLSL texturing op (will be SPV image)
|
||||
|
||||
const glslang::TType &imageType = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
|
||||
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
|
||||
const glslang::TType &imageType = node->getAsAggregate()
|
||||
? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
|
||||
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
|
||||
const glslang::TSampler sampler = imageType.getSampler();
|
||||
#ifdef AMD_EXTENSIONS
|
||||
bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
|
||||
? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
|
||||
: false;
|
||||
? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
|
||||
: false;
|
||||
#endif
|
||||
|
||||
const auto signExtensionMask = [&]() {
|
||||
if (builder.getSpvVersion() >= spv::Spv_1_4) {
|
||||
if (sampler.type == glslang::EbtUint)
|
||||
return spv::ImageOperandsZeroExtendMask;
|
||||
else if (sampler.type == glslang::EbtInt)
|
||||
return spv::ImageOperandsSignExtendMask;
|
||||
}
|
||||
return spv::ImageOperandsMaskNone;
|
||||
};
|
||||
|
||||
std::vector<spv::Id> arguments;
|
||||
if (node->getAsAggregate())
|
||||
translateArguments(*node->getAsAggregate(), arguments);
|
||||
|
|
@ -4269,11 +4280,17 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
spv::IdImmediate coord = { true,
|
||||
builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) };
|
||||
operands.push_back(coord);
|
||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone };
|
||||
imageOperands.word = imageOperands.word | signExtensionMask();
|
||||
if (sampler.ms) {
|
||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
|
||||
imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask;
|
||||
}
|
||||
if (imageOperands.word != spv::ImageOperandsMaskNone) {
|
||||
operands.push_back(imageOperands);
|
||||
spv::IdImmediate imageOperand = { true, *(opIt++) };
|
||||
operands.push_back(imageOperand);
|
||||
if (sampler.ms) {
|
||||
spv::IdImmediate imageOperand = { true, *(opIt++) };
|
||||
operands.push_back(imageOperand);
|
||||
}
|
||||
}
|
||||
spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands);
|
||||
builder.setPrecision(result, precision);
|
||||
|
|
@ -4300,7 +4317,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
#endif
|
||||
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
|
||||
if (mask) {
|
||||
mask = mask | signExtensionMask();
|
||||
if (mask != spv::MemoryAccessMaskNone) {
|
||||
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||
operands.push_back(imageOperands);
|
||||
}
|
||||
|
|
@ -4315,7 +4333,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
}
|
||||
#endif
|
||||
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
|
||||
spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||
spv::IdImmediate imageOperand = { true,
|
||||
builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||
operands.push_back(imageOperand);
|
||||
}
|
||||
|
||||
|
|
@ -4362,7 +4381,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
#endif
|
||||
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask);
|
||||
if (mask) {
|
||||
mask = mask | signExtensionMask();
|
||||
if (mask != spv::MemoryAccessMaskNone) {
|
||||
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||
operands.push_back(imageOperands);
|
||||
}
|
||||
|
|
@ -4377,7 +4397,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
}
|
||||
#endif
|
||||
if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) {
|
||||
spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||
spv::IdImmediate imageOperand = { true,
|
||||
builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||
operands.push_back(imageOperand);
|
||||
}
|
||||
|
||||
|
|
@ -4386,7 +4407,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
||||
return spv::NoResult;
|
||||
#ifdef AMD_EXTENSIONS
|
||||
} else if (node->getOp() == glslang::EOpSparseImageLoad || node->getOp() == glslang::EOpSparseImageLoadLod) {
|
||||
} else if (node->getOp() == glslang::EOpSparseImageLoad ||
|
||||
node->getOp() == glslang::EOpSparseImageLoadLod) {
|
||||
#else
|
||||
} else if (node->getOp() == glslang::EOpSparseImageLoad) {
|
||||
#endif
|
||||
|
|
@ -4408,7 +4430,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
#endif
|
||||
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
|
||||
if (mask) {
|
||||
mask = mask | signExtensionMask();
|
||||
if (mask != spv::MemoryAccessMaskNone) {
|
||||
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||
operands.push_back(imageOperands);
|
||||
}
|
||||
|
|
@ -4710,7 +4733,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
spv::Id resType = builder.makeStructType(members, "ResType");
|
||||
|
||||
//call ImageFootprintNV
|
||||
spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params);
|
||||
spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj,
|
||||
cracked.gather, noImplicitLod, params, signExtensionMask());
|
||||
|
||||
//copy resType (SPIR-V type) to resultStructType(OpenGL type)
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
|
@ -4763,7 +4787,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
}
|
||||
|
||||
std::vector<spv::Id> result( 1,
|
||||
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
|
||||
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather,
|
||||
noImplicitLod, params, signExtensionMask())
|
||||
);
|
||||
|
||||
if (components != node->getType().getVectorSize())
|
||||
|
|
|
|||
|
|
@ -1808,7 +1808,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const
|
|||
// Accept all parameters needed to create a texture instruction.
|
||||
// Create the correct instruction based on the inputs, and make the call.
|
||||
Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
|
||||
bool noImplicitLod, const TextureParameters& parameters)
|
||||
bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
|
||||
{
|
||||
static const int maxTextureArgs = 10;
|
||||
Id texArgs[maxTextureArgs] = {};
|
||||
|
|
@ -1835,8 +1835,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
|||
//
|
||||
// Set up the optional arguments
|
||||
//
|
||||
int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments
|
||||
++numArgs; // speculatively make room for the mask operand
|
||||
int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments
|
||||
++numArgs; // speculatively make room for the mask operand
|
||||
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
|
||||
if (parameters.bias) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
|
||||
|
|
@ -1889,6 +1889,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
|||
if (parameters.volatil) {
|
||||
mask = mask | ImageOperandsVolatileTexelKHRMask;
|
||||
}
|
||||
mask = mask | signExtensionMask;
|
||||
if (mask == ImageOperandsMaskNone)
|
||||
--numArgs; // undo speculative reservation for the mask argument
|
||||
else
|
||||
|
|
|
|||
|
|
@ -416,7 +416,8 @@ public:
|
|||
};
|
||||
|
||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&);
|
||||
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
|
||||
bool noImplicit, const TextureParameters&, ImageOperandsMask);
|
||||
|
||||
// Emit the OpTextureQuery* instruction that was passed in.
|
||||
// Figure out the right return value and type, and return it.
|
||||
|
|
|
|||
|
|
@ -575,7 +575,7 @@ const char* ImageChannelDataTypeString(int type)
|
|||
}
|
||||
}
|
||||
|
||||
const int ImageOperandsCeiling = 12;
|
||||
const int ImageOperandsCeiling = 14;
|
||||
|
||||
const char* ImageOperandsString(int format)
|
||||
{
|
||||
|
|
@ -592,6 +592,8 @@ const char* ImageOperandsString(int format)
|
|||
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
|
||||
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
|
||||
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
|
||||
case ImageOperandsSignExtendShift: return "SignExtend";
|
||||
case ImageOperandsZeroExtendShift: return "ZeroExtend";
|
||||
|
||||
case ImageOperandsCeiling:
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue