diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 864902cc..becb3b43 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2087,7 +2087,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& 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 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& 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 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO 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 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO 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 8b794a45..315e1bb4 100644 --- a/Test/baseResults/spv.sparseTexture.frag.out +++ b/Test/baseResults/spv.sparseTexture.frag.out @@ -7,7 +7,7 @@ Linked fragment stage: // 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 @@ Linked fragment stage: 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 @@ Linked fragment stage: 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 @@ Linked fragment stage: 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 @@ Linked fragment stage: 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 @@ Linked fragment stage: 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 e4aefc53..c995ee2a 100644 --- a/Test/spv.sparseTexture.frag +++ b/Test/spv.sparseTexture.frag @@ -16,10 +16,17 @@ uniform isampler2DArray is2DArray; 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 @@ void main() 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