Ver código fonte

Fix SampleLevel lowering for Cube/CubeArray (#2449)

Tex Riddell 6 anos atrás
pai
commit
2bf23d3edf

+ 4 - 0
include/dxc/HLSL/HLOperations.h

@@ -135,6 +135,9 @@ namespace HLOperandIndex {
 // Opcode parameter.
 const unsigned kOpcodeIdx = 0;
 
+// Used to initialize values that have no valid index in the HL overload.
+const unsigned kInvalidIdx = UINT32_MAX;
+
 // Matrix store.
 const unsigned kMatStoreDstPtrOpIdx = 1;
 const unsigned kMatStoreValOpIdx = 2;
@@ -275,6 +278,7 @@ const unsigned kSampleBStatusArgIndex = 7;
 const unsigned kSampleLLevelArgIndex = 4;
 const unsigned kSampleLOffsetArgIndex = 5;
 const unsigned kSampleLStatusArgIndex = 6;
+const unsigned kSampleLCubeStatusArgIndex = 5;  // Cube/CubeArray has no offset arg
 
 // SampleCmpLevelZero.
 const unsigned kSampleCmpLZCmpValArgIndex = 4;

+ 8 - 2
lib/HLSL/HLOperationLower.cpp

@@ -2814,8 +2814,14 @@ SampleHelper::SampleHelper(
     break;
   case OP::OpCode::SampleLevel:
     SetLOD(CI, HLOperandIndex::kSampleLLevelArgIndex);
-    TranslateOffset(CI, HLOperandIndex::kSampleLOffsetArgIndex);
-    SetStatus(CI, HLOperandIndex::kSampleLStatusArgIndex);
+    if (resourceKind == DXIL::ResourceKind::TextureCube ||
+        resourceKind == DXIL::ResourceKind::TextureCubeArray) {
+      TranslateOffset(CI, HLOperandIndex::kInvalidIdx); // Initialize offsets to zero
+      SetStatus(CI, HLOperandIndex::kSampleLCubeStatusArgIndex);
+    } else {
+      TranslateOffset(CI, HLOperandIndex::kSampleLOffsetArgIndex);
+      SetStatus(CI, HLOperandIndex::kSampleLStatusArgIndex);
+    }
     break;
   case OP::OpCode::SampleBias:
     SetBias(CI, HLOperandIndex::kSampleBBiasArgIndex);

+ 12 - 4
tools/clang/test/CodeGenHLSL/batch/misc/sampleL.hlsl

@@ -1,17 +1,25 @@
 // RUN: %dxc -E main -T ps_6_0 %s   | FileCheck %s
 
-// CHECK: sampleLevel
-
-
 SamplerState samp1 : register(s5);
 Texture2D<float4> text1 : register(t3);
+TextureCubeArray<float4> text2 : register(t5);
 int LOD;
 float4 main(float2 a : A) : SV_Target
 {
   uint status;
   float4 r = 0;
+
+  // CHECK: call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62,
   r += text1.SampleLevel(samp1, a, LOD);
+  // CHECK: call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62,
   r += text1.SampleLevel(samp1, a, LOD, uint2(-5, 7));
-  r += text1.SampleLevel(samp1, a, LOD, uint2(-3, 2), status); r += status;
+  // CHECK: call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62,
+  // CHECK: call i1 @dx.op.checkAccessFullyMapped.i32(i32 71,
+  r += text1.SampleLevel(samp1, a, LOD, uint2(-3, 2), status); r += CheckAccessFullyMapped(status);
+  // CHECK: call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62,
+  r += text2.SampleLevel(samp1, a.xyxy, LOD);
+  // CHECK: call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62,
+  // CHECK: call i1 @dx.op.checkAccessFullyMapped.i32(i32 71,
+  r += text2.SampleLevel(samp1, a.xyxy, LOD * 0.5, status); r += CheckAccessFullyMapped(status);
   return r;
 }