瀏覽代碼

[spirv] Load() for Texture2DMS & Texture2DMSArray. (#670)

Ehsan 8 年之前
父節點
當前提交
67f14ca00e
共有 2 個文件被更改,包括 65 次插入22 次删除
  1. 20 16
      tools/clang/lib/SPIRV/SPIRVEmitter.cpp
  2. 45 6
      tools/clang/test/CodeGenSPIRV/texture.load.hlsl

+ 20 - 16
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -1999,14 +1999,6 @@ SPIRVEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr,
     //                 [, int SampleIndex,]
     //                 [, int Offset]);
 
-    // SampleIndex is only available when the Object is of Texture2DMS or
-    // Texture2DMSArray types. Under those cases, Offset will be the third
-    // parameter. Otherwise, Offset should be the second parameter.
-    if (expr->getNumArgs() == 3) {
-      emitError("Texture2DMS[Array].Load() not implemented yet");
-      return 0;
-    }
-
     const auto *object = expr->getImplicitObjectArgument();
     const auto *location = expr->getArg(0);
     const auto objectType = object->getType();
@@ -2025,15 +2017,27 @@ SPIRVEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr,
 
     if (TypeTranslator::isTexture(objectType)) {
       // .Load() has a second optional paramter for offset.
-      const uint32_t locationId = doExpr(location);
+      const auto locationId = doExpr(location);
       uint32_t constOffset = 0, varOffset = 0;
-      uint32_t coordinate = 0, lod = 0;
-      // For Texture Load() functions, the location parameter is a vector that
-      // consists of both the coordinate and the mipmap level (via the last
-      // vector element). We need to split it here since the OpImageFetch
-      // SPIR-V instruction encodes them as separate arguments.
-      splitVecLastElement(location->getType(), locationId, &coordinate, &lod);
-      handleOffset(expr, 1, &constOffset, &varOffset);
+      uint32_t coordinate = locationId, lod = 0;
+
+      if (TypeTranslator::isTextureMS(objectType)) {
+        // SampleIndex is only available when the Object is of Texture2DMS or
+        // Texture2DMSArray types. Under those cases, Offset will be the third
+        // parameter (index 2).
+        lod = doExpr(expr->getArg(1));
+        handleOffset(expr, 2, &constOffset, &varOffset);
+      } else {
+        // For Texture Load() functions, the location parameter is a vector
+        // that consists of both the coordinate and the mipmap level (via the
+        // last vector element). We need to split it here since the
+        // OpImageFetch SPIR-V instruction encodes them as separate arguments.
+        splitVecLastElement(location->getType(), locationId, &coordinate, &lod);
+        // For textures other than Texture2DMS(Array), offset should be the
+        // second parameter (index 1).
+        handleOffset(expr, 1, &constOffset, &varOffset);
+      }
+
       return processBufferTextureLoad(object, coordinate, constOffset,
                                       varOffset, lod);
     }

+ 45 - 6
tools/clang/test/CodeGenSPIRV/texture.load.hlsl

@@ -1,13 +1,16 @@
 // Run: %dxc -T ps_6_0 -E main
 
-Texture1D <float4> t1 : register(t1);
-Texture2D <float4> t2 : register(t2);
-Texture3D <float4> t3 : register(t3);
+Texture1D       <float4> t1 : register(t1);
+Texture2D       <float4> t2 : register(t2);
+Texture3D       <float4> t3 : register(t3);
 // .Load() does not support TextureCube.
 
-Texture1D <float> t4 : register(t4);
-Texture2D <int2>  t5 : register(t5);
-Texture3D <uint3> t6 : register(t6);
+Texture1D        <float> t4 : register(t4);
+Texture2D        <int2>  t5 : register(t5);
+Texture3D        <uint3> t6 : register(t6);
+
+Texture2DMS     <float>  t7 : register(t7);
+Texture2DMSArray<float3> t8 : register(t8);
 
 // CHECK: OpCapability ImageGatherExtended
 
@@ -49,5 +52,41 @@ float4 main(int3 location: A, int offset: B) : SV_Target {
 // CHECK-NEXT:    {{%\d+}} = OpVectorShuffle %v3uint [[f6]] [[f6]] 0 1 2
     uint3 val6 = t6.Load(int4(1, 2, 3, 4), 3);
 
+    float val7;
+    float3 val8;
+    int sampleIndex = 7;
+    int2 pos2 = int2(2, 3);
+    int3 pos3 = int3(2, 3, 4);
+    int2 offset2 = int2(1, 2);
+
+// CHECK:     [[pos0:%\d+]] = OpLoad %v2int %pos2
+// CHECK-NEXT: [[si0:%\d+]] = OpLoad %int %sampleIndex
+// CHECK-NEXT: [[t70:%\d+]] = OpLoad %type_2d_image_1 %t7
+// CHECK-NEXT: [[f70:%\d+]] = OpImageFetch %v4float [[t70]] [[pos0]] Sample [[si0]]
+// CHECK-NEXT:     {{%\d+}} = OpCompositeExtract %float [[f70]] 0
+    val7 = t7.Load(pos2, sampleIndex);
+
+// CHECK:        [[pos1:%\d+]] = OpLoad %v2int %pos2
+// CHECK-NEXT:    [[si1:%\d+]] = OpLoad %int %sampleIndex
+// CHECK-NEXT:[[offset2:%\d+]] = OpLoad %v2int %offset2
+// CHECK-NEXT:    [[t71:%\d+]] = OpLoad %type_2d_image_1 %t7
+// CHECK-NEXT:    [[f71:%\d+]] = OpImageFetch %v4float [[t71]] [[pos1]] Offset|Sample [[offset2]] [[si1]]
+// CHECK-NEXT:        {{%\d+}} = OpCompositeExtract %float [[f71]] 0
+    val7 = t7.Load(pos2, sampleIndex, offset2);
+
+// CHECK:     [[pos2:%\d+]] = OpLoad %v3int %pos3
+// CHECK-NEXT: [[si2:%\d+]] = OpLoad %int %sampleIndex
+// CHECK-NEXT: [[t80:%\d+]] = OpLoad %type_2d_image_array %t8
+// CHECK-NEXT: [[f80:%\d+]] = OpImageFetch %v4float [[t80]] [[pos2]] Sample [[si2]]
+// CHECK-NEXT:     {{%\d+}} = OpVectorShuffle %v3float [[f80]] [[f80]] 0 1 2
+    val8 = t8.Load(pos3, sampleIndex);
+
+// CHECK:     [[pos3:%\d+]] = OpLoad %v3int %pos3
+// CHECK-NEXT: [[si3:%\d+]] = OpLoad %int %sampleIndex
+// CHECK-NEXT: [[t81:%\d+]] = OpLoad %type_2d_image_array %t8
+// CHECK-NEXT: [[f81:%\d+]] = OpImageFetch %v4float [[t81]] [[pos3]] ConstOffset|Sample [[v2ic]] [[si3]]
+// CHECK-NEXT:     {{%\d+}} = OpVectorShuffle %v3float [[f81]] [[f81]] 0 1 2
+    val8 = t8.Load(pos3, sampleIndex, int2(1,2));
+
     return 1.0;
 }