Skip to content

Commit 6dca7e3

Browse files
authored
Fix spirv emit that leads to pathological downstream time. (shader-slang#3546)
1 parent 1476489 commit 6dca7e3

4 files changed

+47
-4
lines changed

source/slang/slang-emit-spirv.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,7 @@ struct SPIRVEmitContext
22622262
SLANG_UNIMPLEMENTED_X(e.getBuffer());
22632263
}
22642264
case kIROp_Specialize:
2265+
case kIROp_MissingReturn:
22652266
return nullptr;
22662267
case kIROp_Var:
22672268
return emitVar(parent, inst);

source/slang/slang-ir-specialize-resources.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct ResourceParameterSpecializationCondition : FunctionCallSpecializeConditio
3838
// our decision.
3939
//
4040
type = unwrapArray(type);
41+
bool isArray = type != param->getDataType();
4142

4243
// On all of our (current) targets, a function that
4344
// takes a `ConstantBuffer<T>` parameter requires
@@ -63,7 +64,7 @@ struct ResourceParameterSpecializationCondition : FunctionCallSpecializeConditio
6364
if( isKhronosTarget(targetRequest) )
6465
{
6566
if (targetRequest->shouldEmitSPIRVDirectly())
66-
return isIllegalSPIRVParameterType(type);
67+
return isIllegalSPIRVParameterType(type, isArray);
6768
else
6869
return isIllegalGLSLParameterType(type);
6970
}
@@ -1212,7 +1213,7 @@ bool specializeResourceUsage(
12121213

12131214
bool isIllegalGLSLParameterType(IRType* type)
12141215
{
1215-
if (as<IRUniformParameterGroupType>(type))
1216+
if (as<IRParameterGroupType>(type))
12161217
return true;
12171218
if (as<IRHLSLStructuredBufferTypeBase>(type))
12181219
return true;
@@ -1236,7 +1237,7 @@ bool isIllegalGLSLParameterType(IRType* type)
12361237
return false;
12371238
}
12381239

1239-
bool isIllegalSPIRVParameterType(IRType* type)
1240+
bool isIllegalSPIRVParameterType(IRType* type, bool isArray)
12401241
{
12411242
if (isIllegalGLSLParameterType(type))
12421243
return true;
@@ -1245,6 +1246,13 @@ bool isIllegalSPIRVParameterType(IRType* type)
12451246
// all Texture types.
12461247
if (as<IRTextureType>(type))
12471248
return true;
1249+
if (isArray)
1250+
{
1251+
if (as<IRSamplerStateTypeBase>(type))
1252+
{
1253+
return true;
1254+
}
1255+
}
12481256
return false;
12491257
}
12501258
} // namespace Slang

source/slang/slang-ir-specialize-resources.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ namespace Slang
3131
IRModule* irModule);
3232

3333
bool isIllegalGLSLParameterType(IRType* type);
34-
bool isIllegalSPIRVParameterType(IRType* type);
34+
bool isIllegalSPIRVParameterType(IRType* type, bool isArray);
3535

3636
}

tests/spirv/array-param-gep.slang

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//TEST:SIMPLE(filecheck=CHECK): -target spirv -entry computeMain -stage compute -emit-spirv-directly
2+
3+
// Check that we are not generating spirv that loads a global resource array into a SSA register,
4+
// instead, these arrays should always be accessed via direct OpAccessChain operations to avoid
5+
// creating a lot of local load/stores in the driver compiler.
6+
7+
struct Scene
8+
{
9+
SamplerState samplers[256];
10+
Texture2D textures[100];
11+
}
12+
13+
ParameterBlock<Scene> scene;
14+
struct Material
15+
{
16+
int sampler;
17+
int texture;
18+
}
19+
20+
RWStructuredBuffer<float4> result;
21+
22+
float4 shade(Scene scene, Material mat)
23+
{
24+
return scene.textures[mat.texture].SampleLevel(scene.samplers[mat.sampler], float2(0,0), 0);
25+
}
26+
27+
[numthreads(1,1,1)]
28+
void computeMain(uniform Material mat)
29+
{
30+
// CHECK: OpEntryPoint
31+
// CHECK-NOT: OpLoad {{.*}} %scene{{.*}}samplers
32+
// CHECK-NOT: OpLoad {{.*}} %scene{{.*}}textures
33+
result[0] = shade(scene, mat);
34+
}

0 commit comments

Comments
 (0)