SPV: Support the new OpCode - OpImageSparseRead
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 864902c..becb3b4 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2087,7 +2087,7 @@
glslang::TSampler sampler = {};
bool cubeCompare = false;
- if (node.isTexture()) {
+ if (node.isTexture() || node.isImage()) {
sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
}
@@ -2110,6 +2110,10 @@
if (i == 0)
lvalue = true;
break;
+ case glslang::EOpSparseImageLoad:
+ if ((sampler.ms && i == 3) || (! sampler.ms && i == 2))
+ lvalue = true;
+ break;
case glslang::EOpSparseTexture:
if ((cubeCompare && i == 3) || (! cubeCompare && i == 2))
lvalue = true;
@@ -2253,9 +2257,9 @@
operands.push_back(spv::ImageOperandsSampleMask);
operands.push_back(*opIt);
}
- return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
+ return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
} else if (node->getOp() == glslang::EOpImageStore) {
if (sampler.ms) {
operands.push_back(*(opIt + 1));
@@ -2267,9 +2271,27 @@
if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
return spv::NoResult;
- } else if (node->isSparseImage()) {
- spv::MissingFunctionality("sparse image functions");
- return spv::NoResult;
+ } else if (node->getOp() == glslang::EOpSparseImageLoad) {
+ builder.addCapability(spv::CapabilitySparseResidency);
+ if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+ builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
+
+ if (sampler.ms) {
+ operands.push_back(spv::ImageOperandsSampleMask);
+ operands.push_back(*opIt++);
+ }
+
+ // Create the return type that was a special structure
+ spv::Id texelOut = *opIt;
+ spv::Id typeId0 = convertGlslangToSpvType(node->getType());
+ spv::Id typeId1 = builder.getDerefTypeId(texelOut);
+ spv::Id resultTypeId = builder.makeStructResultType(typeId0, typeId1);
+
+ spv::Id resultId = builder.createOp(spv::OpImageSparseRead, resultTypeId, operands);
+
+ // Decode the return type
+ builder.createStore(builder.createCompositeExtract(resultId, typeId1, 1), texelOut);
+ return builder.createCompositeExtract(resultId, typeId0, 0);
} else {
// Process image atomic operations
diff --git a/Test/baseResults/spv.sparseTexture.frag.out b/Test/baseResults/spv.sparseTexture.frag.out
index 8b794a4..315e1bb 100644
--- a/Test/baseResults/spv.sparseTexture.frag.out
+++ b/Test/baseResults/spv.sparseTexture.frag.out
@@ -7,7 +7,7 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 399
+// Id's are bound by 433
Capability Shader
Capability SampledRect
@@ -15,7 +15,7 @@
Capability SampledCubeArray
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 33 48 89 360 384
+ EntryPoint Fragment 4 "main" 33 48 89 360 388 400 418
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_ARB_sparse_texture2"
@@ -44,7 +44,12 @@
Name 256 "sCubeShadow"
Name 289 "s2DRectShadow"
Name 360 "offsets"
- Name 384 "outColor"
+ Name 385 "i2D"
+ Name 388 "ic2"
+ Name 397 "ii3D"
+ Name 400 "ic3"
+ Name 409 "i2DMS"
+ Name 418 "outColor"
Decorate 29(s2D) DescriptorSet 0
Decorate 44(s3D) DescriptorSet 0
Decorate 59(isCube) DescriptorSet 0
@@ -58,6 +63,11 @@
Decorate 256(sCubeShadow) DescriptorSet 0
Decorate 289(s2DRectShadow) DescriptorSet 0
Decorate 360(offsets) Flat
+ Decorate 385(i2D) DescriptorSet 0
+ Decorate 388(ic2) Flat
+ Decorate 397(ii3D) DescriptorSet 0
+ Decorate 400(ic3) Flat
+ Decorate 409(i2DMS) DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -162,16 +172,29 @@
358: TypeArray 143(ivec2) 357
359: TypePointer Input 358
360(offsets): 359(ptr) Variable Input
- 383: TypePointer Output 11(fvec4)
- 384(outColor): 383(ptr) Variable Output
- 387: TypeBool
+ 383: TypeImage 10(float) 2D nonsampled format:Rgba32f
+ 384: TypePointer UniformConstant 383
+ 385(i2D): 384(ptr) Variable UniformConstant
+ 387: TypePointer Input 143(ivec2)
+ 388(ic2): 387(ptr) Variable Input
+ 395: TypeImage 6(int) 3D nonsampled format:Rgba32i
+ 396: TypePointer UniformConstant 395
+ 397(ii3D): 396(ptr) Variable UniformConstant
+ 399: TypePointer Input 129(ivec3)
+ 400(ic3): 399(ptr) Variable Input
+ 407: TypeImage 10(float) 2D multi-sampled nonsampled format:Rgba32f
+ 408: TypePointer UniformConstant 407
+ 409(i2DMS): 408(ptr) Variable UniformConstant
+ 417: TypePointer Output 11(fvec4)
+ 418(outColor): 417(ptr) Variable Output
+ 421: TypeBool
4(main): 2 Function None 3
5: Label
8(resident): 7(ptr) Variable Function
13(texel): 12(ptr) Variable Function
18(itexel): 17(ptr) Variable Function
23(utexel): 22(ptr) Variable Function
- 385: 12(ptr) Variable Function
+ 419: 12(ptr) Variable Function
Store 8(resident) 9
Store 13(texel) 15
Store 18(itexel) 19
@@ -515,24 +538,51 @@
381: 6(int) Load 8(resident)
382: 6(int) BitwiseOr 381 380
Store 8(resident) 382
- 386: 6(int) Load 8(resident)
- 388: 387(bool) ImageSparseTexelsResident 386
- SelectionMerge 390 None
- BranchConditional 388 389 392
- 389: Label
- 391: 11(fvec4) Load 13(texel)
- Store 385 391
- Branch 390
- 392: Label
- 393: 16(ivec4) Load 18(itexel)
- 394: 11(fvec4) ConvertSToF 393
- 395: 21(ivec4) Load 23(utexel)
- 396: 11(fvec4) ConvertUToF 395
- 397: 11(fvec4) FAdd 394 396
- Store 385 397
- Branch 390
- 390: Label
- 398: 11(fvec4) Load 385
- Store 384(outColor) 398
+ 386: 383 Load 385(i2D)
+ 389: 143(ivec2) Load 388(ic2)
+ 390: 35(ResType) ImageSparseRead 386 389
+ 391: 11(fvec4) CompositeExtract 390 1
+ Store 13(texel) 391
+ 392: 6(int) CompositeExtract 390 0
+ 393: 6(int) Load 8(resident)
+ 394: 6(int) BitwiseOr 393 392
+ Store 8(resident) 394
+ 398: 395 Load 397(ii3D)
+ 401: 129(ivec3) Load 400(ic3)
+ 402: 62(ResType) ImageSparseRead 398 401
+ 403: 16(ivec4) CompositeExtract 402 1
+ Store 18(itexel) 403
+ 404: 6(int) CompositeExtract 402 0
+ 405: 6(int) Load 8(resident)
+ 406: 6(int) BitwiseOr 405 404
+ Store 8(resident) 406
+ 410: 407 Load 409(i2DMS)
+ 411: 143(ivec2) Load 388(ic2)
+ 412: 35(ResType) ImageSparseRead 410 411 Sample 144
+ 413: 11(fvec4) CompositeExtract 412 1
+ Store 13(texel) 413
+ 414: 6(int) CompositeExtract 412 0
+ 415: 6(int) Load 8(resident)
+ 416: 6(int) BitwiseOr 415 414
+ Store 8(resident) 416
+ 420: 6(int) Load 8(resident)
+ 422: 421(bool) ImageSparseTexelsResident 420
+ SelectionMerge 424 None
+ BranchConditional 422 423 426
+ 423: Label
+ 425: 11(fvec4) Load 13(texel)
+ Store 419 425
+ Branch 424
+ 426: Label
+ 427: 16(ivec4) Load 18(itexel)
+ 428: 11(fvec4) ConvertSToF 427
+ 429: 21(ivec4) Load 23(utexel)
+ 430: 11(fvec4) ConvertUToF 429
+ 431: 11(fvec4) FAdd 428 430
+ Store 419 431
+ Branch 424
+ 424: Label
+ 432: 11(fvec4) Load 419
+ Store 418(outColor) 432
Return
FunctionEnd
diff --git a/Test/spv.sparseTexture.frag b/Test/spv.sparseTexture.frag
index e4aefc5..c995ee2 100644
--- a/Test/spv.sparseTexture.frag
+++ b/Test/spv.sparseTexture.frag
@@ -16,10 +16,17 @@
uniform usamplerCubeArray usCubeArray;
uniform usampler2DRect us2DRect;
+layout(rgba32f) uniform image2D i2D;
+layout(rgba32i) uniform iimage3D ii3D;
+layout(rgba32f) uniform image2DMS i2DMS;
+
in vec2 c2;
in vec3 c3;
in vec4 c4;
+in flat ivec2 ic2;
+in flat ivec3 ic3;
+
in flat ivec2 offsets[4];
out vec4 outColor;
@@ -70,11 +77,15 @@
resident |= sparseTextureGatherOffsetARB(s2D, c2, ivec2(4), texel);
resident |= sparseTextureGatherOffsetARB(is2DArray, c3, ivec2(5), itexel, 2);
- resident |= sparseTextureGatherOffsetARB(s2DRectShadow, c2, 2.0, ivec2(7), texel);
+ resident |= sparseTextureGatherOffsetARB(s2DRectShadow, c2, 2.0, ivec2(7), texel);
resident |= sparseTextureGatherOffsetsARB(s2D, c2, offsets, texel);
resident |= sparseTextureGatherOffsetsARB(is2DArray, c3, offsets, itexel, 2);
- resident |= sparseTextureGatherOffsetsARB(s2DRectShadow, c2, 2.0, offsets, texel);
+ resident |= sparseTextureGatherOffsetsARB(s2DRectShadow, c2, 2.0, offsets, texel);
+
+ resident |= sparseImageLoadARB(i2D, ic2, texel);
+ resident |= sparseImageLoadARB(ii3D, ic3, itexel);
+ resident |= sparseImageLoadARB(i2DMS, ic2, 3, texel);
outColor = sparseTexelsResidentARB(resident) ? texel : vec4(itexel) + vec4(utexel);
}
\ No newline at end of file