summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-06-08 05:12:49 -0700
committerGitHub <noreply@github.com>2024-06-08 05:12:49 -0700
commit9a23a9aab3721828526c921db1e779008e133e8f (patch)
treeb49448075cdffe278fd6760e2879bc061eb8e0af
parentbc680e74bd8a0c415cab5ed6fe00b762c26b8b8d (diff)
SPIRV `Block` decoration fixes. (#4303)
* SPIRV `Block` decoration fixes. - SPIRV does not allow duplicate `Block` decorations. So we shouldn't be generating them. - Also fixes duplication of OpName. - SPIRV and HLSL do not allow ConstantBuffer with trailing unsized arrays. Added a check in the front-end against such code. * Convert failing cross-compile tests to filecheck. --------- Co-authored-by: Jay Kwak <82421531+jkwak-work@users.noreply.github.com>
-rw-r--r--source/slang/slang-capability.cpp17
-rw-r--r--source/slang/slang-capability.h3
-rw-r--r--source/slang/slang-check-decl.cpp87
-rw-r--r--source/slang/slang-check-impl.h7
-rw-r--r--source/slang/slang-compiler.cpp38
-rw-r--r--source/slang/slang-diagnostic-defs.h2
-rw-r--r--source/slang/slang-emit-spirv.cpp5
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp2
-rw-r--r--source/slang/slang-ir-specialize-target-switch.cpp4
-rw-r--r--source/slang/slang-options.cpp7
-rw-r--r--source/slang/slang-profile.h2
-rw-r--r--tests/bindings/glsl-parameter-blocks.slang5
-rw-r--r--tests/bugs/gh-941.slang6
-rw-r--r--tests/bugs/vk-image-atomics.slang6
-rw-r--r--tests/bugs/vk-structured-buffer-binding.hlsl6
-rw-r--r--tests/bugs/vk-structured-buffer-binding.hlsl.glsl24
-rw-r--r--tests/cross-compile/barycentrics.slang4
-rw-r--r--tests/cross-compile/barycentrics.slang.glsl12
-rw-r--r--tests/cross-compile/dual-source-blending.slang6
-rw-r--r--tests/cross-compile/early-depth-stencil.hlsl6
-rw-r--r--tests/cross-compile/early-depth-stencil.hlsl.glsl16
-rw-r--r--tests/cross-compile/early-depth-stencil.hlsl.hlsl8
-rw-r--r--tests/cross-compile/glsl-empty-struct-param-field.slang4
-rw-r--r--tests/cross-compile/glsl-empty-struct-param-field.slang.glsl23
-rw-r--r--tests/cross-compile/half-conversion.slang4
-rw-r--r--tests/cross-compile/non-uniform-indexing.slang5
-rw-r--r--tests/cross-compile/non-uniform-indexing.slang.glsl22
-rw-r--r--tests/cross-compile/sign.slang7
-rw-r--r--tests/cross-compile/sign.slang.glsl12
-rw-r--r--tests/cross-compile/sign.slang.hlsl6
-rw-r--r--tests/cross-compile/sv-coverage.slang5
-rw-r--r--tests/cross-compile/sv-coverage.slang.glsl16
-rw-r--r--tests/cross-compile/unknown-image-format.slang7
-rw-r--r--tests/cross-compile/unknown-image-format.slang.glsl66
-rw-r--r--tests/cross-compile/vector-comparison.slang9
-rw-r--r--tests/cross-compile/vector-comparison.slang.glsl26
-rw-r--r--tests/cross-compile/vk-push-constant-set.slang5
-rw-r--r--tests/diagnostics/constant-buffer-unsized.slang21
-rw-r--r--tests/hlsl/raster-order-resource.slang6
-rw-r--r--tests/spirv/block-decoration.slang18
-rw-r--r--tests/spirv/varying-out-index.slang6
41 files changed, 281 insertions, 260 deletions
diff --git a/source/slang/slang-capability.cpp b/source/slang/slang-capability.cpp
index 750026a64..21b2641b4 100644
--- a/source/slang/slang-capability.cpp
+++ b/source/slang/slang-capability.cpp
@@ -252,6 +252,23 @@ void CapabilitySet::addUnexpandedCapabilites(CapabilityName atom)
addConjunction(*cr, CapabilityAtom::Invalid, CapabilityAtom::Invalid);
}
+CapabilityAtom CapabilitySet::getUniquelyImpliedStageAtom() const
+{
+ CapabilityAtom result = CapabilityAtom::Invalid;
+ for (auto& targetKV : m_targetSets)
+ {
+ if (targetKV.second.shaderStageSets.getCount() == 1)
+ {
+ auto thisStage = targetKV.second.shaderStageSets.begin()->first;
+ if (result == CapabilityAtom::Invalid)
+ result = thisStage;
+ else if (result != thisStage)
+ return CapabilityAtom::Invalid;
+ }
+ }
+ return result;
+}
+
CapabilitySet::CapabilitySet()
{}
diff --git a/source/slang/slang-capability.h b/source/slang/slang-capability.h
index 6e123a9a6..8fd9e2bd4 100644
--- a/source/slang/slang-capability.h
+++ b/source/slang/slang-capability.h
@@ -184,6 +184,9 @@ public:
CapabilityTargetSets& getCapabilityTargetSets() { return m_targetSets; }
const CapabilityTargetSets& getCapabilityTargetSets() const { return m_targetSets; }
+ // If this capability set uniquely implies one stage atom, return it. Otherwise returns CapabilityAtom::Invalid.
+ CapabilityAtom getUniquelyImpliedStageAtom() const;
+
struct AtomSets
{
struct Iterator
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 95528b185..bf61a6c2e 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -2101,6 +2101,19 @@ namespace Slang
{
getSink()->diagnose(varDecl->type.exp->loc, Diagnostics::incompleteTypeCannotBeUsedInBuffer, elementType);
}
+ if (doesTypeHaveTag(elementType, TypeTag::Unsized))
+ {
+ // If the element type is unsized, it can only be an array of resource types that we can legalize out.
+ // Ordinary unsized arrays are not allowed in a constant buffer since we cannot translate it to
+ // valid HLSL or SPIRV.
+ ArrayExpressionType* trailingArrayType = nullptr;
+ VarDeclBase* trailingArrayField = getTrailingUnsizedArrayElement(elementType, varDecl, trailingArrayType);
+ if (trailingArrayField && !isOpaqueHandleType(trailingArrayType->getElementType()))
+ {
+ getSink()->diagnose(trailingArrayField->loc, Diagnostics::cannotUseUnsizedTypeInConstantBuffer, trailingArrayType);
+ getSink()->diagnose(varDecl->loc, Diagnostics::seeConstantBufferDefinition);
+ }
+ }
}
else if (varDecl->findModifier<HLSLUniformModifier>())
{
@@ -10420,6 +10433,80 @@ namespace Slang
return defaultVis;
}
+ VarDeclBase* getTrailingUnsizedArrayElement(Type* type, VarDeclBase* parentVar, ArrayExpressionType*& outArrayType)
+ {
+ while (auto modifiedType = as<ModifiedType>(type))
+ type = modifiedType->getBase();
+ HashSet<Type*> seenTypes;
+ for (;;)
+ {
+ if (auto arrayType = as<ArrayExpressionType>(type))
+ {
+ if (arrayType->isUnsized())
+ {
+ outArrayType = arrayType;
+ return parentVar;
+ }
+ else
+ return nullptr;
+ }
+ else if (auto declRefType = as<DeclRefType>(type))
+ {
+ if (auto aggTypeDecl = declRefType->getDeclRef().as<AggTypeDecl>())
+ {
+ auto varDecls = aggTypeDecl.getDecl()->getMembersOfType<VarDeclBase>();
+ if (varDecls.getCount() == 0)
+ return nullptr;
+ VarDeclBase* lastVarDecl = nullptr;
+ for (auto varDecl : varDecls)
+ {
+ if (isEffectivelyStatic(varDecl))
+ continue;
+ lastVarDecl = varDecl;
+ }
+ auto lastMember = _getMemberDeclRef(
+ getCurrentASTBuilder(), aggTypeDecl, lastVarDecl).as<VarDeclBase>();
+ auto varType = getType(getCurrentASTBuilder(), lastMember);
+ if (!varType)
+ return nullptr;
+ if (!seenTypes.add(type))
+ return nullptr;
+ type = varType;
+ parentVar = lastMember.getDecl();
+ continue;
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ bool isOpaqueHandleType(Type* type)
+ {
+ while (auto modifiedType = as<ModifiedType>(type))
+ type = modifiedType->getBase();
+ if (as<ResourceType>(type))
+ return true;
+ if (as<SamplerStateType>(type))
+ return true;
+ if (as<UniformParameterGroupType>(type))
+ return true;
+ if (as<HLSLStructuredBufferTypeBase>(type))
+ return true;
+ if (as<UntypedBufferResourceType>(type))
+ return true;
+ if (as<GLSLShaderStorageBufferType>(type))
+ return true;
+ if (as<FeedbackType>(type))
+ return true;
+ if (as<HLSLPatchType>(type))
+ return true;
+ if (as<HLSLStreamOutputType>(type))
+ return true;
+ if (as<MeshOutputType>(type))
+ return true;
+ return false;
+ }
+
void diagnoseCapabilityProvenance(CompilerOptionSet& optionSet, DiagnosticSink* sink, Decl* decl, CapabilityAtom atomToFind, bool optionallyNeverPrintDecl)
{
HashSet<Decl*> printedDecls;
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 2554d0d85..ab6bc6585 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -2837,6 +2837,13 @@ namespace Slang
DeclVisibility getDeclVisibility(Decl* decl);
+ // If `type` is unsized, return the trailing unsized array field that makes it so.
+ VarDeclBase* getTrailingUnsizedArrayElement(Type* type, VarDeclBase* rootObject, ArrayExpressionType*& outArrayType);
+
+ // Test if `type` can be an opaque handle on certain targets, this includes
+ // texture, buffer, sampler, acceleration structure, etc.
+ bool isOpaqueHandleType(Type* type);
+
void diagnoseCapabilityProvenance(CompilerOptionSet& optionSet, DiagnosticSink* sink, Decl* decl, CapabilityAtom atomToFind, bool optionallyNeverPrintDecl = false);
void _ensureAllDeclsRec(
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 147d4a889..0277bb092 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -433,6 +433,44 @@ namespace Slang
return UnownedStringSlice();
}
+ Stage getStageFromAtom(CapabilityAtom atom)
+ {
+ switch (atom)
+ {
+ case CapabilityAtom::vertex:
+ return Stage::Vertex;
+ case CapabilityAtom::hull:
+ return Stage::Hull;
+ case CapabilityAtom::domain:
+ return Stage::Domain;
+ case CapabilityAtom::geometry:
+ return Stage::Geometry;
+ case CapabilityAtom::fragment:
+ return Stage::Fragment;
+ case CapabilityAtom::compute:
+ return Stage::Compute;
+ case CapabilityAtom::mesh:
+ return Stage::Mesh;
+ case CapabilityAtom::amplification:
+ return Stage::Amplification;
+ case CapabilityAtom::anyhit:
+ return Stage::AnyHit;
+ case CapabilityAtom::closesthit:
+ return Stage::ClosestHit;
+ case CapabilityAtom::intersection:
+ return Stage::Intersection;
+ case CapabilityAtom::raygen:
+ return Stage::RayGeneration;
+ case CapabilityAtom::miss:
+ return Stage::Miss;
+ case CapabilityAtom::callable:
+ return Stage::Callable;
+ default:
+ SLANG_UNEXPECTED("unknown stage atom");
+ UNREACHABLE_RETURN(Stage::Unknown);
+ }
+ }
+
SlangResult checkExternalCompilerSupport(Session* session, PassThroughMode passThrough)
{
// Check if the type is supported on this compile
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index b011227fd..100543864 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -28,6 +28,7 @@ DIAGNOSTIC(-1, Note, implicitParameterMatchingFailedBecauseShaderDoesNotDefineCo
DIAGNOSTIC(-1, Note, implicitParameterMatchingFailedBecauseTypeMismatch, "implicit parameter matching failed because the component of the same name does not match parameter type '$0'.")
DIAGNOSTIC(-1, Note, noteShaderIsTargetingPipeine, "shader '$0' is targeting pipeline '$1'")
DIAGNOSTIC(-1, Note, seeDefinitionOf, "see definition of '$0'")
+DIAGNOSTIC(-1, Note, seeConstantBufferDefinition, "see constant buffer definition.")
DIAGNOSTIC(-1, Note, seeInterfaceDefinitionOf, "see interface definition of '$0'")
DIAGNOSTIC(-1, Note, seeUsingOf, "see using of '$0'")
DIAGNOSTIC(-1, Note, seeDefinitionOfShader, "see definition of shader '$0'")
@@ -459,6 +460,7 @@ DIAGNOSTIC(31211, Error, derivativeGroupLinearMustBeMultiple4ForTotalThreadCount
DIAGNOSTIC(31212, Error, onlyOneOfDerivativeGroupLinearOrQuadCanBeSet, "cannot set compute derivative group linear and compute derivative group quad at the same time")
DIAGNOSTIC(31213, Error, cudaKernelMustReturnVoid, "return type of a CUDA kernel function cannot be non-void.")
DIAGNOSTIC(31214, Error, differentiableKernelEntryPointCannotHaveDifferentiableParams, "differentiable kernel entry point cannot have differentiable parameters. Consider using DiffTensorView to pass differentiable data, or marking this parameter with 'no_diff'")
+DIAGNOSTIC(31215, Error, cannotUseUnsizedTypeInConstantBuffer, "cannot use unsized type '$0' in a constant buffer.")
// Enums
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 769e36861..1ef3a31e0 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1481,7 +1481,8 @@ struct SPIRVEmitContext
if (structSize >= (uint64_t)IRSizeAndAlignment::kIndeterminateSize)
{
IRBuilder builder(inst);
- if (isSpirv14OrLater() || !inst->findDecorationImpl(kIROp_SPIRVBufferBlockDecoration))
+ if ((isSpirv14OrLater() || !inst->findDecorationImpl(kIROp_SPIRVBufferBlockDecoration))
+ && !inst->findDecorationImpl(kIROp_SPIRVBlockDecoration))
{
auto decoration = builder.addDecoration(inst, kIROp_SPIRVBlockDecoration);
emitDecoration(getID(spvStructType), decoration);
@@ -2308,7 +2309,6 @@ struct SPIRVEmitContext
maybeEmitPointerDecoration(varInst, param);
if (auto layout = getVarLayout(param))
emitVarLayout(param, varInst, layout);
- maybeEmitName(varInst, param);
emitDecorations(param, getID(varInst));
return varInst;
}
@@ -2332,7 +2332,6 @@ struct SPIRVEmitContext
maybeEmitPointerDecoration(varInst, globalVar);
if(layout)
emitVarLayout(globalVar, varInst, layout);
- maybeEmitName(varInst, globalVar);
emitDecorations(globalVar, getID(varInst));
return varInst;
}
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index eb5905dfe..9b30b6072 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -1525,6 +1525,8 @@ ScalarizedVal createGLSLGlobalVaryings(
StringBuilder namehintSB;
if (auto nameHint = leafVar->findDecoration<IRNameHintDecoration>())
{
+ if (leafVar->getOp() == kIROp_Func)
+ namehintSB << "entryPointParam_";
namehintSB << nameHint->getName();
}
OuterParamInfoLink outerParamInfo;
diff --git a/source/slang/slang-ir-specialize-target-switch.cpp b/source/slang/slang-ir-specialize-target-switch.cpp
index fac1dd484..46ea51192 100644
--- a/source/slang/slang-ir-specialize-target-switch.cpp
+++ b/source/slang/slang-ir-specialize-target-switch.cpp
@@ -31,7 +31,9 @@ namespace Slang
bool isBetterForTarget = capSet.isBetterForTarget(bestCapSet, target->getTargetCaps(), isEqual);
if (isBetterForTarget)
{
- bool targetImpliesCapSet = (target->getTargetCaps().implies(capSet, true) || capSet.isEmpty());
+ CapabilitySet joinedCapSet = capSet;
+ joinedCapSet.join(target->getTargetCaps());
+ bool targetImpliesCapSet = target->getTargetCaps().implies(joinedCapSet, true);
if (targetImpliesCapSet)
{
// Now check if bestCapSet contains targetCaps. If it does not then this is an invalid target
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 7b4b02f68..4bbd0dcaf 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -1051,6 +1051,13 @@ void OptionsParser::setProfileVersion(RawTarget* rawTarget, ProfileVersion profi
void OptionsParser::addCapabilityAtom(RawTarget* rawTarget, CapabilityName atom)
{
+ CapabilitySet capSet(atom);
+ auto stageAtom = capSet.getUniquelyImpliedStageAtom();
+ if (stageAtom != CapabilityAtom::Invalid)
+ {
+ Stage stage = getStageFromAtom(stageAtom);
+ setStage(getCurrentEntryPoint(), stage);
+ }
rawTarget->optionSet.addCapabilityAtom(atom);
}
diff --git a/source/slang/slang-profile.h b/source/slang/slang-profile.h
index bd6feab23..9a164805b 100644
--- a/source/slang/slang-profile.h
+++ b/source/slang/slang-profile.h
@@ -128,6 +128,8 @@ namespace Slang
Stage findStageByName(String const& name);
UnownedStringSlice getStageText(Stage stage);
+
+ Stage getStageFromAtom(CapabilityAtom atom);
}
#endif
diff --git a/tests/bindings/glsl-parameter-blocks.slang b/tests/bindings/glsl-parameter-blocks.slang
index ee385e158..fd2800e2c 100644
--- a/tests/bindings/glsl-parameter-blocks.slang
+++ b/tests/bindings/glsl-parameter-blocks.slang
@@ -1,4 +1,7 @@
-//TEST:CROSS_COMPILE: -profile ps_5_0 -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK): -profile ps_5_0 -entry main -target spirv-assembly
+
+// CHECK: OpDecorate %gTest Binding 0
+// CHECK: OpDecorate %gTest DescriptorSet 0
struct Test
{
diff --git a/tests/bugs/gh-941.slang b/tests/bugs/gh-941.slang
index f66c25e97..f0e5a7036 100644
--- a/tests/bugs/gh-941.slang
+++ b/tests/bugs/gh-941.slang
@@ -1,7 +1,11 @@
-//TEST:CROSS_COMPILE: -profile ps_5_0 -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK): -profile spirv_1_5+fragment -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=GLSL): -profile spirv_1_5+fragment -entry main -target glsl
// Ensure that we add the `GL_EXT_nonuniform_qualifier` extension for any code that uses unbounded-size arrays of resources.
+// CHECK: OpCapability RuntimeDescriptorArray
+// GLSL: #extension GL_EXT_nonuniform_qualifier : require
+
Texture2D t[];
SamplerState s;
diff --git a/tests/bugs/vk-image-atomics.slang b/tests/bugs/vk-image-atomics.slang
index f846606f9..f5b2821ec 100644
--- a/tests/bugs/vk-image-atomics.slang
+++ b/tests/bugs/vk-image-atomics.slang
@@ -1,7 +1,11 @@
-//TEST:CROSS_COMPILE: -profile ps_5_0 -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK): -profile ps_5_0 -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK): -profile ps_5_0 -entry main -target spirv-assembly -emit-spirv-via-glsl
// Ensure that we can lower to `imageAtomicAdd` correctly.
+// CHECK: OpImageTexelPointer
+// CHECK: OpAtomicIAdd
+
RWTexture2D<uint> t;
float4 main() : SV_Target
diff --git a/tests/bugs/vk-structured-buffer-binding.hlsl b/tests/bugs/vk-structured-buffer-binding.hlsl
index 3ef1bcc8c..da0424543 100644
--- a/tests/bugs/vk-structured-buffer-binding.hlsl
+++ b/tests/bugs/vk-structured-buffer-binding.hlsl
@@ -1,4 +1,8 @@
-//TEST:CROSS_COMPILE:-profile ps_4_0 -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK):-profile ps_4_0 -entry main -target spirv-assembly
+
+// CHECK-DAG: OpDecorate %gDoneGroups{{.*}} DescriptorSet 4
+
+// CHECK-DAG: OpDecorate %gDoneGroups{{.*}} Binding 3
[[vk::binding(3, 4)]]
RWStructuredBuffer<uint> gDoneGroups : register(u3);
diff --git a/tests/bugs/vk-structured-buffer-binding.hlsl.glsl b/tests/bugs/vk-structured-buffer-binding.hlsl.glsl
deleted file mode 100644
index 18ed1a8a7..000000000
--- a/tests/bugs/vk-structured-buffer-binding.hlsl.glsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// vk-structured-buffer-binding.hlsl.glsl
-//TEST_IGNORE_FILE:
-
-#version 450
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-layout(std430, binding = 3, set = 4) buffer StructuredBuffer_uint_t_0 {
- uint _data[];
-} gDoneGroups_0;
-
-layout(location = 0)
-out vec4 main_0;
-
-layout(location = 0)
-in vec3 uv_0;
-
-void main()
-{
- main_0 = vec4(float(gDoneGroups_0._data[uint(int(uv_0.z))]));
- return;
-}
-
-
diff --git a/tests/cross-compile/barycentrics.slang b/tests/cross-compile/barycentrics.slang
index 1f2c27572..c63835ccc 100644
--- a/tests/cross-compile/barycentrics.slang
+++ b/tests/cross-compile/barycentrics.slang
@@ -1,4 +1,6 @@
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment
+
+// CHECK: OpDecorate %{{.*}} BuiltIn BaryCoordKHR
float4 main(float3 bary : SV_Barycentrics) : SV_Target
{
diff --git a/tests/cross-compile/barycentrics.slang.glsl b/tests/cross-compile/barycentrics.slang.glsl
deleted file mode 100644
index ede585db0..000000000
--- a/tests/cross-compile/barycentrics.slang.glsl
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 450
-
-#extension GL_EXT_fragment_shader_barycentric : enable
-
-layout(location = 0)
-out vec4 main_0;
-
-void main()
-{
- main_0 = vec4(gl_BaryCoordEXT, float(0));
- return;
-}
diff --git a/tests/cross-compile/dual-source-blending.slang b/tests/cross-compile/dual-source-blending.slang
index 51af956b2..602f8e20f 100644
--- a/tests/cross-compile/dual-source-blending.slang
+++ b/tests/cross-compile/dual-source-blending.slang
@@ -4,9 +4,13 @@
// `vk::index` attributes to compile
// for dual-source color blending.
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment
//TEST_DISABLED:SIMPLE:-target glsl
+// CHECK: OpDecorate %{{.*}}main_a Location 0
+// CHECK: OpDecorate %{{.*}}main_b Location 0
+// CHECK: OpDecorate %{{.*}}main_b Index 1
+
struct FragmentOutput
{
[[vk::location(0)]]
diff --git a/tests/cross-compile/early-depth-stencil.hlsl b/tests/cross-compile/early-depth-stencil.hlsl
index b40a29aba..931538edb 100644
--- a/tests/cross-compile/early-depth-stencil.hlsl
+++ b/tests/cross-compile/early-depth-stencil.hlsl
@@ -1,5 +1,7 @@
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
-//TEST:CROSS_COMPILE:-profile ps_6_0 -target dxil-assembly -entry main
+//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry main -stage fragment -emit-spirv-via-glsl
+
+// SPIRV: OpExecutionMode %main EarlyFragmentTests
[earlydepthstencil]
float4 main(): SV_Target
diff --git a/tests/cross-compile/early-depth-stencil.hlsl.glsl b/tests/cross-compile/early-depth-stencil.hlsl.glsl
deleted file mode 100644
index 4a723215c..000000000
--- a/tests/cross-compile/early-depth-stencil.hlsl.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-//TEST_IGNORE_FILE:
-#version 450
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-#line 5 0
-layout(location = 0)
-out vec4 main_0;
-
-#line 5
-layout(early_fragment_tests) in;
-void main()
-{
- main_0 = vec4(float(1), float(0), float(0), float(1));
- return;
-}
diff --git a/tests/cross-compile/early-depth-stencil.hlsl.hlsl b/tests/cross-compile/early-depth-stencil.hlsl.hlsl
deleted file mode 100644
index 378c5c0a1..000000000
--- a/tests/cross-compile/early-depth-stencil.hlsl.hlsl
+++ /dev/null
@@ -1,8 +0,0 @@
-//TEST_IGNORE_FILE:
-#pragma pack_matrix(column_major)
-
-[earlydepthstencil]
-vector<float,4> main() : SV_TARGET
-{
- return vector<float,4>((float) 1, (float) 0, (float) 0, (float) 1);
-}
diff --git a/tests/cross-compile/glsl-empty-struct-param-field.slang b/tests/cross-compile/glsl-empty-struct-param-field.slang
index 21b67e325..f146d4684 100644
--- a/tests/cross-compile/glsl-empty-struct-param-field.slang
+++ b/tests/cross-compile/glsl-empty-struct-param-field.slang
@@ -1,5 +1,7 @@
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -profile ps_5_0
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -profile ps_5_0
+// CHECK: OpDecorate %pblock Binding 0
+// CHECK: OpDecorate %pblock DescriptorSet 0
struct E
{
};
diff --git a/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl b/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl
deleted file mode 100644
index bff888233..000000000
--- a/tests/cross-compile/glsl-empty-struct-param-field.slang.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-//TEST_IGNORE_FILE:
-#version 450
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-struct P_0
-{
- vec4 param_0;
-};
-
-layout(binding = 0)
-layout(std140) uniform _S1
-{
- vec4 param_0;
-} pblock_0;
-layout(location = 0)
-out vec4 main_0;
-
-void main()
-{
- main_0 = pblock_0.param_0;
- return;
-} \ No newline at end of file
diff --git a/tests/cross-compile/half-conversion.slang b/tests/cross-compile/half-conversion.slang
index 316629f81..39ba4001c 100644
--- a/tests/cross-compile/half-conversion.slang
+++ b/tests/cross-compile/half-conversion.slang
@@ -1,6 +1,8 @@
// half-conversion.slang
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry main -stage fragment
+
+// SPIRV: OpBitcast
cbuffer C
{
diff --git a/tests/cross-compile/non-uniform-indexing.slang b/tests/cross-compile/non-uniform-indexing.slang
index 22e00a212..73483afae 100644
--- a/tests/cross-compile/non-uniform-indexing.slang
+++ b/tests/cross-compile/non-uniform-indexing.slang
@@ -1,8 +1,9 @@
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment -verify-debug-serial-ir
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment -verify-debug-serial-ir
// Confirm that `NonUniformResourceIndex` translates to SPIR-V as expected
+// CHECK: NonUniform
+
Texture2D t[10];
SamplerState s;
diff --git a/tests/cross-compile/non-uniform-indexing.slang.glsl b/tests/cross-compile/non-uniform-indexing.slang.glsl
deleted file mode 100644
index 35b5fab95..000000000
--- a/tests/cross-compile/non-uniform-indexing.slang.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-#version 450
-#extension GL_EXT_nonuniform_qualifier : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(binding = 0)
-uniform texture2D t_0[10];
-
-layout(binding = 1)
-uniform sampler s_0;
-
-layout(location = 0)
-out vec4 main_0;
-
-layout(location = 0)
-in vec3 uv_0;
-
-void main()
-{
- main_0 = (texture(sampler2D(t_0[nonuniformEXT(int(uv_0.z))],s_0), (uv_0.xy)));
- return;
-}
-
diff --git a/tests/cross-compile/sign.slang b/tests/cross-compile/sign.slang
index 17a51d93d..934bc5c5a 100644
--- a/tests/cross-compile/sign.slang
+++ b/tests/cross-compile/sign.slang
@@ -1,10 +1,13 @@
// sign.slang
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
-//TEST:CROSS_COMPILE:-target dxil-assembly -entry main -stage fragment -profile sm_6_0
+//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=DXIL):-target dxil-assembly -entry main -stage fragment -profile sm_6_0
// Test cross compilation of the sign function
+// SPIRV: FSign
+// DXIL: define void @main
+
float4 main() : SV_Target
{
float4 s = sign(float4(1.5, 1.0, -1.5, -1.0));
diff --git a/tests/cross-compile/sign.slang.glsl b/tests/cross-compile/sign.slang.glsl
deleted file mode 100644
index ec0bfe377..000000000
--- a/tests/cross-compile/sign.slang.glsl
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 450
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-layout(location = 0)
-out vec4 main_0;
-
-void main()
-{
- main_0 = vec4((ivec4(sign((vec4(1.5, 1.0, -1.5, -1.0))))));
- return;
-}
diff --git a/tests/cross-compile/sign.slang.hlsl b/tests/cross-compile/sign.slang.hlsl
deleted file mode 100644
index d7016dde7..000000000
--- a/tests/cross-compile/sign.slang.hlsl
+++ /dev/null
@@ -1,6 +0,0 @@
-//TEST_IGNORE_FILE:
-float4 main() : SV_Target
-{
- float4 s = sign(float4(1.5, 1.0, -1.5, -1.0));
- return s;
-} \ No newline at end of file
diff --git a/tests/cross-compile/sv-coverage.slang b/tests/cross-compile/sv-coverage.slang
index b61530e7b..ab11311a0 100644
--- a/tests/cross-compile/sv-coverage.slang
+++ b/tests/cross-compile/sv-coverage.slang
@@ -1,7 +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
+//TEST:SIMPLE(filecheck=CHECK):-target spirv -entry main -stage fragment -emit-spirv-via-glsl
float4 main(
in float4 color : COLOR,
@@ -9,7 +9,8 @@ float4 main(
out uint outputCoverage : SV_Coverage)
: SV_Target
{
- // CHECK: %gl_SampleMask = OpVariable %_ptr_Input__arr_int_int_1 Input
+ // CHECK: OpDecorate %gl_SampleMask{{.*}} BuiltIn SampleMask
+ // CHECK: %gl_SampleMask{{.*}} = OpVariable %_ptr_Input__arr_int_{{u?}}int_1 Input
outputCoverage = inputCoverage ^ 1;
return color;
}
diff --git a/tests/cross-compile/sv-coverage.slang.glsl b/tests/cross-compile/sv-coverage.slang.glsl
deleted file mode 100644
index a5e0dea47..000000000
--- a/tests/cross-compile/sv-coverage.slang.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-// sv-coverage.slang.glsl
-#version 450
-
-layout(location = 0)
-out vec4 main_0;
-
-layout(location = 0)
-in vec4 color_0;
-
-void main()
-{
- uint _S1 = uint(gl_SampleMaskIn[0]) ^ uint(1);
- main_0 = color_0;
- gl_SampleMask[0] = int(_S1);
- return;
-}
diff --git a/tests/cross-compile/unknown-image-format.slang b/tests/cross-compile/unknown-image-format.slang
index bf937c5fa..27eaee606 100644
--- a/tests/cross-compile/unknown-image-format.slang
+++ b/tests/cross-compile/unknown-image-format.slang
@@ -1,9 +1,14 @@
// unknown-image-format.slang
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment -default-image-format-unknown
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment -default-image-format-unknown
// Ensure that we can emit R/W images with an unknown format, when required.
+// CHECK: OpTypeImage %float 2D 2 0 0 2 Unknown
+// CHECK: OpTypeImage %float 2D 2 0 0 2 R32f
+// CHECK: OpTypeImage %float 2D 2 0 0 2 Rgba8
+// CHECK: OpTypeImage %float 2D 2 0 0 2 Rgba16f
+
// Global Scope:
RWTexture2D<float> gNoFormat;
diff --git a/tests/cross-compile/unknown-image-format.slang.glsl b/tests/cross-compile/unknown-image-format.slang.glsl
deleted file mode 100644
index a39cf3693..000000000
--- a/tests/cross-compile/unknown-image-format.slang.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-// unknown-image-format.slang.glsl
-//TEST_IGNORE_FILE:
-
-#version 450
-#extension GL_EXT_shader_image_load_formatted : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-struct SLANG_ParameterGroup_C_0
-{
- uvec2 index_0;
-};
-
-layout(binding = 2)
-layout(std140) uniform _S1
-{
- uvec2 index_0;
-} C_0;
-
-layout(binding = 0)
-uniform image2D gNoFormat_0;
-
-layout(r32f)
-layout(binding = 1)
-uniform image2D gExplicitFormat_0;
-
-layout(binding = 0, set = 1)
-uniform image2D gBlock_noFormat_0;
-
-layout(rgba8)
-layout(binding = 1, set = 1)
-uniform image2D gBlock_explicitFormat_0;
-
-layout(binding = 3)
-uniform image2D entryPointParams_noFormat_0;
-
-layout(rgba16f)
-layout(binding = 4)
-uniform image2D entryPointParams_explicitFormat_0;
-
-layout(location = 0)
-out vec4 main_0;
-
-void main()
-{
-
- float _S3 = (imageLoad((gNoFormat_0), ivec2((C_0.index_0))).x);
- vec4 _S4 = vec4(_S3);
-
- float _S5 = (imageLoad((gExplicitFormat_0), ivec2((C_0.index_0))).x);
- vec4 result_0 = _S4 + _S5;
-
- vec4 _S6 = (imageLoad((gBlock_noFormat_0), ivec2((C_0.index_0))));
- vec4 result_1 = result_0 + _S6;
-
- vec4 _S7 = (imageLoad((gBlock_explicitFormat_0), ivec2((C_0.index_0))));
- vec4 result_2 = result_1 + _S7;
-
- vec4 _S8 = (imageLoad((entryPointParams_noFormat_0), ivec2((C_0.index_0))));
- vec4 result_3 = result_2 + _S8;
-
- vec4 _S9 = (imageLoad((entryPointParams_explicitFormat_0), ivec2((C_0.index_0))));
- main_0 = result_3 + _S9;
-
- return;
-}
diff --git a/tests/cross-compile/vector-comparison.slang b/tests/cross-compile/vector-comparison.slang
index f363eb40c..a018dc940 100644
--- a/tests/cross-compile/vector-comparison.slang
+++ b/tests/cross-compile/vector-comparison.slang
@@ -1,10 +1,17 @@
// vector-comparison.slang
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment -Wno-use-of-non-short-circuiting-operator
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment -Wno-use-of-non-short-circuiting-operator
// This test ensures that we cross-compile vector comparison operators
// correctly to GLSL
+// CHECK: OpFOrdEqual %v4bool
+// CHECK: OpFOrdLessThan %v4bool
+// CHECK: OpFOrdGreaterThan %v4bool
+// CHECK: OpFOrdLessThanEqual %v4bool
+// CHECK: OpFOrdGreaterThanEqual %v4bool
+// CHECK: OpFUnordNotEqual %v4bool
+
struct Param
{
float4 a, b;
diff --git a/tests/cross-compile/vector-comparison.slang.glsl b/tests/cross-compile/vector-comparison.slang.glsl
deleted file mode 100644
index f3f103678..000000000
--- a/tests/cross-compile/vector-comparison.slang.glsl
+++ /dev/null
@@ -1,26 +0,0 @@
-#version 450
-layout(row_major) uniform;
-layout(row_major) buffer;
-struct Param_0
-{
- vec4 a_0;
- vec4 b_0;
-};
-
-layout(binding = 0)
-layout(std140) uniform _S1
-{
- vec4 a_0;
- vec4 b_0;
-} params_0;
-layout(location = 0)
-out vec4 main_0;
-
-void main()
-{
-
- const vec4 _S3 = vec4(2.0);
- const vec4 _S4 = vec4(3.0);
- main_0 = mix(_S4, _S3, (equal(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (lessThan(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (greaterThan(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (lessThanEqual(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (greaterThanEqual(params_0.a_0,params_0.b_0))) + mix(_S4, _S3, (notEqual(params_0.a_0,params_0.b_0)));
- return;
-}
diff --git a/tests/cross-compile/vk-push-constant-set.slang b/tests/cross-compile/vk-push-constant-set.slang
index ee9c68ed8..362db59ec 100644
--- a/tests/cross-compile/vk-push-constant-set.slang
+++ b/tests/cross-compile/vk-push-constant-set.slang
@@ -5,7 +5,7 @@
// parameters and shifting a parameer block over to
// `space=1`.
-//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+//TEST:SIMPLE(filecheck=CHECK):-target spirv-assembly -entry main -stage fragment
struct S
{
@@ -15,6 +15,9 @@ struct S
[[vk::push_constant]]
ConstantBuffer<S> x;
+// CHECK: OpDecorate %y Binding 0
+// CHECK: OpDecorate %y DescriptorSet 0
+
ParameterBlock<S> y;
float4 main() : SV_Target
diff --git a/tests/diagnostics/constant-buffer-unsized.slang b/tests/diagnostics/constant-buffer-unsized.slang
new file mode 100644
index 000000000..25644e803
--- /dev/null
+++ b/tests/diagnostics/constant-buffer-unsized.slang
@@ -0,0 +1,21 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+struct T2 {
+ float4 _m0;
+};
+
+[[vk::binding(0)]]
+cbuffer ubo : register(b0)
+{
+ int in_val;
+ // CHECK: ([[# @LINE+1]]): error 31215
+ T2 _z0[]; // error 31215: cannot use unsized type 'T2[]' in a constant buffer.
+}
+
+[shader("fragment")]
+float4 main() : SV_TARGET
+{
+ uint x = in_val;
+ float4 data = _z0[x]._m0;
+ return data;
+} \ No newline at end of file
diff --git a/tests/hlsl/raster-order-resource.slang b/tests/hlsl/raster-order-resource.slang
index 2db9f31dc..099234af7 100644
--- a/tests/hlsl/raster-order-resource.slang
+++ b/tests/hlsl/raster-order-resource.slang
@@ -14,7 +14,7 @@ RasterizerOrderedByteAddressBuffer buffer;
[shader("fragment")]
float4 fragMain() : SV_Target
{
- // SPIRV: %fragMain_0 = OpFunction
+ // SPIRV: %fragMain{{.*}} = OpFunction
// SPIRV: OpBeginInvocationInterlockEXT
// SPIRV: OpEndInvocationInterlockEXT
@@ -27,7 +27,7 @@ RasterizerOrderedTexture2D tex;
[shader("fragment")]
float4 fragMain2() : SV_Target
{
- // SPIRV: %fragMain2_0 = OpFunction
+ // SPIRV: %fragMain2{{.*}} = OpFunction
// SPIRV: OpBeginInvocationInterlockEXT
// SPIRV: OpEndInvocationInterlockEXT
@@ -40,7 +40,7 @@ RasterizerOrderedStructuredBuffer<float> buffer2;
[shader("fragment")]
float4 fragMain3() : SV_Target
{
- // SPIRV: %fragMain3_0 = OpFunction
+ // SPIRV: %fragMain3{{.*}} = OpFunction
// SPIRV: OpBeginInvocationInterlockEXT
// SPIRV: OpEndInvocationInterlockEXT
diff --git a/tests/spirv/block-decoration.slang b/tests/spirv/block-decoration.slang
new file mode 100644
index 000000000..e6d350dcd
--- /dev/null
+++ b/tests/spirv/block-decoration.slang
@@ -0,0 +1,18 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+// Check that we don't produce duplicate `Block` decorations.
+
+// CHECK: OpDecorate %RWStructuredBuffer Block
+// CHECK-NOT: OpDecorate %RWStructuredBuffer Block
+
+struct Particle {
+ float4 _m0;
+};
+
+[[vk::binding(0)]]
+RWStructuredBuffer<Particle> particleOut;
+
+[shader("fragment")]
+float4 main() : SV_TARGET {
+ return particleOut[0]._m0;
+} \ No newline at end of file
diff --git a/tests/spirv/varying-out-index.slang b/tests/spirv/varying-out-index.slang
index 6448f2266..e4c4400f5 100644
--- a/tests/spirv/varying-out-index.slang
+++ b/tests/spirv/varying-out-index.slang
@@ -12,9 +12,9 @@ struct PS_OUTPUT
};
-// CHECK: OpDecorate %MainPS_vColor Location 0
-// CHECK: OpDecorate %MainPS_vColor2 Location 0
-// CHECK: OpDecorate %MainPS_vColor2 Index 1
+// CHECK: OpDecorate %{{.*}}MainPS_vColor Location 0
+// CHECK: OpDecorate %{{.*}}MainPS_vColor2 Location 0
+// CHECK: OpDecorate %{{.*}}MainPS_vColor2 Index 1
PS_OUTPUT MainPS()
{