summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-emit-spirv.cpp50
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp15
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp2
-rw-r--r--tests/cross-compile/sv-coverage.slang2
-rw-r--r--tests/spirv/flat-builtin.slang12
-rw-r--r--tests/spirv/primitive-id.slang23
6 files changed, 88 insertions, 16 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 1b5747621..1a661920a 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3461,17 +3461,6 @@ struct SPIRVEmitContext
varInst,
builtinVal
);
-
- if (storageClass == SpvStorageClassInput ||
- storageClass == SpvStorageClassOutput)
- {
- switch (builtinVal)
- {
- case SpvBuiltInPrimitiveId:
- _maybeEmitInterpolationModifierDecoration(IRInterpolationMode::NoInterpolation, varInst);
- break;
- }
- }
m_builtinGlobalVars[key] = varInst;
return varInst;
}
@@ -5740,6 +5729,22 @@ struct SPIRVEmitContext
}
};
+bool isInstUsedInStage(SPIRVEmitContext& context, IRInst* inst, Stage s)
+{
+ auto* referencingEntryPoints = context.m_referencingEntryPoints.tryGetValue(inst);
+ if (!referencingEntryPoints)
+ return false;
+ for (auto entryPoint : *referencingEntryPoints)
+ {
+ if (auto entryPointDecor = entryPoint->findDecoration<IREntryPointDecoration>())
+ {
+ if (entryPointDecor->getProfile().getStage() == s)
+ return true;
+ }
+ }
+ return false;
+}
+
SlangResult emitSPIRVFromIR(
CodeGenContext* codeGenContext,
IRModule* irModule,
@@ -5804,6 +5809,29 @@ SlangResult emitSPIRVFromIR(
context.ensureInst(irEntryPoint);
}
+ // Declare integral input builtins as Flat if necessary.
+ for (auto globalInst : context.m_irModule->getGlobalInsts())
+ {
+ if (globalInst->getOp() != kIROp_GlobalVar &&
+ globalInst->getOp() != kIROp_GlobalParam)
+ continue;
+ auto spvVar = context.m_mapIRInstToSpvInst.tryGetValue(globalInst);
+ if (!spvVar)
+ continue;
+ auto ptrType = as<IRPtrType>(globalInst->getDataType());
+ if (!ptrType)
+ continue;
+ auto addrSpace = ptrType->getAddressSpace();
+ if (addrSpace == SpvStorageClassInput)
+ {
+ if (isIntegralScalarOrCompositeType(ptrType->getValueType()))
+ {
+ if (isInstUsedInStage(context, globalInst, Stage::Fragment))
+ context._maybeEmitInterpolationModifierDecoration(IRInterpolationMode::NoInterpolation, *spvVar);
+ }
+ }
+ }
+
// Move forward delcared pointers to the end.
do
{
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index ca9367ea0..d2d09f45a 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -637,12 +637,13 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
if( kind == LayoutResourceKind::VaryingInput )
{
- name = "gl_SampleMaskIn[0]";
+ name = "gl_SampleMaskIn";
}
else
{
- name = "gl_SampleMask[0]";
+ name = "gl_SampleMask";
}
+ arrayIndex = 0;
}
else if(semanticName == "sv_innercoverage")
{
@@ -891,6 +892,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
//
name = "gl_PositionPerViewNV[1]";
+ arrayIndex = 1;
// shared->requiresCopyGLPositionToPositionPerView = true;
}
@@ -1594,7 +1596,12 @@ ScalarizedVal adaptType(
return adaptType(builder, loaded, toType, fromType);
}
break;
-
+ case ScalarizedVal::Flavor::arrayIndex:
+ {
+ auto element = builder->emitElementExtract(val.irValue, as<ScalarizedArrayIndexValImpl>(val.impl)->index);
+ return adaptType(builder, element, toType, fromType);
+ }
+ break;
default:
SLANG_UNEXPECTED("unimplemented");
UNREACHABLE_RETURN(ScalarizedVal());
@@ -1788,7 +1795,7 @@ ScalarizedVal getSubscriptVal(
resultAdapter->val = getSubscriptVal(
builder,
- elementType,
+ inputAdapter->actualType,
inputAdapter->val,
indexVal);
return ScalarizedVal::typeAdapter(resultAdapter);
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index 5589510ed..b387a67f6 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -1934,7 +1934,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
// After legalizing the control flow, we need to sort our blocks to ensure this is true.
sortBlocksInFunc(func);
}
-
+
if (isInlinableGlobalInst(globalInst))
{
for (auto use = globalInst->firstUse; use; use = use->nextUse)
diff --git a/tests/cross-compile/sv-coverage.slang b/tests/cross-compile/sv-coverage.slang
index 3bae3ea8a..b61530e7b 100644
--- a/tests/cross-compile/sv-coverage.slang
+++ b/tests/cross-compile/sv-coverage.slang
@@ -1,6 +1,7 @@
// sv-coverage.slang
//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=CHECK):-target spirv -entry main -stage fragment -emit-spirv-directly
float4 main(
in float4 color : COLOR,
@@ -8,6 +9,7 @@ float4 main(
out uint outputCoverage : SV_Coverage)
: SV_Target
{
+ // CHECK: %gl_SampleMask = OpVariable %_ptr_Input__arr_int_int_1 Input
outputCoverage = inputCoverage ^ 1;
return color;
}
diff --git a/tests/spirv/flat-builtin.slang b/tests/spirv/flat-builtin.slang
new file mode 100644
index 000000000..927c6d045
--- /dev/null
+++ b/tests/spirv/flat-builtin.slang
@@ -0,0 +1,12 @@
+//TEST:SIMPLE(filecheck=CHECK):-target spirv -emit-spirv-directly -entry main -stage fragment
+struct PerPrimitive {
+ int primitive_id : SV_PrimitiveID;
+ int layer : SV_RenderTargetArrayIndex;
+};
+
+// CHECK: OpDecorate %gl_PrimitiveID Flat
+// CHECK: OpDecorate %gl_Layer Flat
+[shader("fragment")]
+uint main(PerPrimitive data) : SV_Target {
+ return data.primitive_id + data.layer;
+} \ No newline at end of file
diff --git a/tests/spirv/primitive-id.slang b/tests/spirv/primitive-id.slang
new file mode 100644
index 000000000..8c354200b
--- /dev/null
+++ b/tests/spirv/primitive-id.slang
@@ -0,0 +1,23 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -entry main -stage mesh
+struct PerVertex {
+ float4 pos : SV_Position;
+};
+
+struct PerPrimitive {
+ uint32_t primitive_id : SV_PrimitiveID;
+ uint32_t layer : SV_RenderTargetArrayIndex;
+};
+
+// CHECK: %gl_PrimitiveID = OpVariable %_ptr_Output__arr_int_int_1 Output
+
+[shader("mesh")]
+[numthreads(1, 1, 1)]
+[outputtopology("triangle")]
+void main(out vertices PerVertex vertices[3], out indices uint3 triangles[1], out primitives PerPrimitive primitive_data[1]) {
+ SetMeshOutputCounts(3, 1);
+
+ vertices[0].pos = vertices[1].pos = vertices[2].pos = 0;
+ triangles[0] = uint3(0, 1, 2);
+ primitive_data[0].primitive_id = 0;
+ primitive_data[0].layer = 0;
+} \ No newline at end of file