Add new test case for image functions and fix issues caught by this test
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 0154913..72292e6 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1757,11 +1757,10 @@
break;
}
- if (lvalue) {
+ if (lvalue)
arguments.push_back(builder.accessChainGetLValue());
- } else {
+ else
arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
- }
}
}
@@ -1820,16 +1819,37 @@
// Check for image functions other than queries
if (node->isImage()) {
- if (node->getOp() == glslang::EOpImageLoad) {
- return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), arguments);
- }
- else if (node->getOp() == glslang::EOpImageStore) {
- builder.createNoResultOp(spv::OpImageWrite, arguments);
- return spv::NoResult;
- }
- else {
- // Process image atomic operations. 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.
+ // Process image load/store
+ if (node->getOp() == glslang::EOpImageLoad ||
+ node->getOp() == glslang::EOpImageStore) {
+ std::vector<spv::Id> operands;
+ auto opIt = arguments.begin();
+ operands.push_back(*(opIt++));
+ operands.push_back(*(opIt++));
+ if (sampler.ms) {
+ // For MS, image operand mask has to be added to indicate the presence of "sample" operand.
+ spv::Id sample = *(opIt++);
+ for (; opIt != arguments.end(); ++opIt)
+ operands.push_back(*opIt);
+
+ operands.push_back(spv::ImageOperandsSampleMask);
+ operands.push_back(sample);
+ } else {
+ for (; opIt != arguments.end(); ++opIt)
+ operands.push_back(*opIt);
+ }
+
+ if (node->getOp() == glslang::EOpImageLoad)
+ return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
+ else {
+ builder.createNoResultOp(spv::OpImageWrite, operands);
+ return spv::NoResult;
+ }
+ } else {
+ // Process image atomic operations
+
+ // 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.
std::vector<spv::Id> imageParams;
auto opIt = arguments.begin();
imageParams.push_back(*(opIt++));
@@ -1885,8 +1905,8 @@
if (cracked.lod) {
params.lod = arguments[2];
++extraArgs;
- } else if (cracked.sample) {
- params.sample = arguments[2]; // For MS, sample should be specified
+ } else if (sampler.ms) {
+ params.sample = arguments[2]; // For MS, "sample" should be specified
++extraArgs;
}
if (cracked.grad) {
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index cefe7aa..336aa24 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -159,8 +159,9 @@
}
Id getImageType(Id resultId) const
{
- assert(isSampledImageType(getTypeId(resultId)));
- return module.getInstruction(getTypeId(resultId))->getIdOperand(0);
+ Id typeId = getTypeId(resultId);
+ assert(isImageType(typeId) || isSampledImageType(typeId));
+ return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;
}
bool isArrayedImageType(Id typeId) const
{
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index ff0d780..ccc163d 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -1635,10 +1635,12 @@
InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageRead].operands.push(OperandOptionalImage, "");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'");
+ InstructionDesc[OpImageWrite].operands.push(OperandOptionalImage, "");
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'");