summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp26
-rw-r--r--tests/bugs/gh-4456.slang52
2 files changed, 74 insertions, 4 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index dabf0294f..d8c1aa91e 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -1197,13 +1197,15 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
IRType* type = inType;
IRType* peeledRequiredType = nullptr;
-
+ ShortList<IRInst*> peeledRequiredArraySizes;
+ bool peeledRequiredArrayLevelMatchesUserDeclaredType = false;
// A system-value semantic might end up needing to override the type
// that the user specified.
if( systemValueInfo && systemValueInfo->requiredType )
{
type = systemValueInfo->requiredType;
peeledRequiredType = type;
+ peeledRequiredArrayLevelMatchesUserDeclaredType = true;
// Unpeel `type` using declarators so that it matches `inType`.
for (auto dd = declarator; dd; dd = dd->next)
{
@@ -1214,8 +1216,13 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
if (auto arrayType = as<IRArrayTypeBase>(type))
{
type = arrayType->getElementType();
+ peeledRequiredArraySizes.add(arrayType->getElementCount());
peeledRequiredType = type;
}
+ else
+ {
+ peeledRequiredArrayLevelMatchesUserDeclaredType = false;
+ }
break;
}
}
@@ -1305,15 +1312,20 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
// Construct the actual type and type-layout for the global variable
//
IRTypeLayout* typeLayout = inTypeLayout;
+ Index requiredArraySizeIndex = peeledRequiredArraySizes.getCount() - 1;
for( auto dd = declarator; dd; dd = dd->next )
{
switch(dd->flavor)
{
case GlobalVaryingDeclarator::Flavor::array:
{
+ auto elementCount = peeledRequiredArrayLevelMatchesUserDeclaredType
+ ? peeledRequiredArraySizes[requiredArraySizeIndex] : dd->elementCount;
+
auto arrayType = builder->getArrayType(
type,
- dd->elementCount);
+ elementCount);
+ requiredArraySizeIndex--;
IRArrayTypeLayout::Builder arrayTypeLayoutBuilder(builder, typeLayout);
if( auto resInfo = inTypeLayout->findSizeAttr(kind) )
@@ -1321,10 +1333,9 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
// TODO: it is kind of gross to be re-running some
// of the type layout logic here.
- UInt elementCount = (UInt) getIntVal(dd->elementCount);
arrayTypeLayoutBuilder.addResourceUsage(
kind,
- resInfo->getSize() * elementCount);
+ resInfo->getSize() * getIntVal(elementCount));
}
auto arrayTypeLayout = arrayTypeLayoutBuilder.build();
@@ -1774,6 +1785,13 @@ ScalarizedVal adaptType(
val = builder->emitSwizzle(fromVector->getElementType(), val, 1, &index);
}
}
+ else if (auto fromArray = as<IRArrayTypeBase>(fromType))
+ {
+ if (as<IRBasicType>(toType))
+ {
+ val = builder->emitElementExtract(fromArray->getElementType(), val, builder->getIntValue(builder->getIntType(), 0));
+ }
+ }
// TODO: actually consider what needs to go on here...
return ScalarizedVal::value(builder->emitCast(
toType,
diff --git a/tests/bugs/gh-4456.slang b/tests/bugs/gh-4456.slang
new file mode 100644
index 000000000..05b346e77
--- /dev/null
+++ b/tests/bugs/gh-4456.slang
@@ -0,0 +1,52 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -lang slang -D__spirv__ -emit-spirv-directly -profile ds_6_5 -entry main
+
+// CHECK: OpEntryPoint
+
+struct VSSceneIn {
+ float3 pos : POSITION;
+};
+
+struct PSSceneIn {
+ float4 pos : SV_Position;
+};
+
+struct HSPerVertexData {
+ PSSceneIn v;
+};
+
+struct HSPerPatchData {
+ float edges[3] : SV_TessFactor;
+ float inside : SV_InsideTessFactor;
+};
+
+RaytracingAccelerationStructure AccelerationStructure : register(t0);
+RayDesc MakeRayDesc()
+{
+ RayDesc desc;
+ desc.Origin = float3(0,0,0);
+ desc.Direction = float3(1,0,0);
+ desc.TMin = 0.0f;
+ desc.TMax = 9999.0;
+ return desc;
+}
+void doInitialize(out RayQuery<RAY_FLAG_FORCE_OPAQUE> query, RayDesc ray)
+{
+ query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray);
+}
+
+[domain("tri")] PSSceneIn main(
+ const float3 bary : SV_DomainLocation,
+ const OutputPatch<HSPerVertexData, 3> patch,
+ const HSPerPatchData perPatchData)
+{
+ PSSceneIn v;
+ v.pos = patch[0].v.pos * bary.x + patch[1].v.pos * bary.y + patch[2].v.pos * bary.z + perPatchData.edges[1];
+
+ RayQuery<RAY_FLAG_FORCE_OPAQUE> q;
+ RayDesc ray = MakeRayDesc();
+
+ q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray);
+ doInitialize(q, ray);
+
+ return v;
+}