summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-check-shader.cpp26
-rw-r--r--source/slang/slang-diagnostic-defs.h6
-rw-r--r--tests/shader-resource-return-type-multi.slang11
-rw-r--r--tests/shader-resource-return-type.slang11
4 files changed, 53 insertions, 1 deletions
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index ed62e948d..7b6ed2261 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -341,6 +341,7 @@ bool doStructFieldsHaveSemantic(Type* type)
return doStructFieldsHaveSemanticImpl(type, seenTypes);
}
+
// Validate that an entry point function conforms to any additional
// constraints based on the stage (and profile?) it specifies.
void validateEntryPoint(EntryPoint* entryPoint, DiagnosticSink* sink)
@@ -376,7 +377,30 @@ void validateEntryPoint(EntryPoint* entryPoint, DiagnosticSink* sink)
auto entryPointName = entryPointFuncDecl->getName();
auto module = getModule(entryPointFuncDecl);
- auto linkage = module->getLinkage();
+ auto linkage = entryPoint->getLinkage();
+
+ // Check if the return type is valid for a shader entry point
+ auto returnType = entryPointFuncDecl->returnType.type;
+ if (returnType)
+ {
+ // Use the existing getTypeTags functionality to check for resource types
+ // Create a temporary SemanticsVisitor to access getTypeTags
+ SharedSemanticsContext shared(linkage, module, sink);
+ SemanticsVisitor visitor(&shared);
+
+ auto typeTags = visitor.getTypeTags(returnType);
+ bool hasResourceOrUnsizedTypes = (((int)typeTags & (int)TypeTag::Opaque) != 0) ||
+ (((int)typeTags & (int)TypeTag::Unsized) != 0);
+
+ if (hasResourceOrUnsizedTypes)
+ {
+ sink->diagnose(
+ entryPointFuncDecl,
+ Diagnostics::entryPointCannotReturnResourceType,
+ entryPointName,
+ returnType);
+ }
+ }
// Every entry point needs to have a stage specified either via
// command-line/API options, or via an explicit `[shader("...")]` attribute.
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 6d9f7faab..0b7ce6cf0 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -2083,6 +2083,12 @@ DIAGNOSTIC(
"$0 on parameter '$1' is unsupported on entry point parameters and will be ignored")
DIAGNOSTIC(
+ 38011,
+ Error,
+ entryPointCannotReturnResourceType,
+ "entry point '$0' cannot return type '$1' that contains resource types")
+
+DIAGNOSTIC(
38100,
Error,
typeDoesntImplementInterfaceRequirement,
diff --git a/tests/shader-resource-return-type-multi.slang b/tests/shader-resource-return-type-multi.slang
new file mode 100644
index 000000000..847412549
--- /dev/null
+++ b/tests/shader-resource-return-type-multi.slang
@@ -0,0 +1,11 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry testRWTexture
+
+// Test multiple resource types that should be rejected
+
+//CHECK: error 38011: entry point 'testRWTexture' cannot return type 'RWTexture2D<float>' that contains resource types
+[shader("compute")]
+RWTexture2D<float> testRWTexture(uint3 threadID : SV_DispatchThreadID)
+{
+ RWTexture2D<float> tex;
+ return tex;
+}
diff --git a/tests/shader-resource-return-type.slang b/tests/shader-resource-return-type.slang
new file mode 100644
index 000000000..d053f8173
--- /dev/null
+++ b/tests/shader-resource-return-type.slang
@@ -0,0 +1,11 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry test1
+
+// Test that entry points cannot return resource types
+
+//CHECK: error 38011: entry point 'test1' cannot return type 'Texture2D<int>' that contains resource types
+[shader("compute")]
+Texture2D<int> test1(uint3 threadID : SV_DispatchThreadID)
+{
+ Texture2D<int> tex;
+ return tex;
+}