summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slang.h8
-rw-r--r--source/slang/compiler.cpp26
-rw-r--r--source/slang/emit.cpp16
-rw-r--r--source/slang/lower.cpp43
-rw-r--r--source/slang/reflection.cpp17
-rw-r--r--source/slang/type-layout.h6
-rw-r--r--tests/reflection/image-types.glsl6
-rw-r--r--tests/reflection/multi-file-extra.hlsl4
-rw-r--r--tests/reflection/multi-file.hlsl4
-rw-r--r--tests/reflection/multi-file.hlsl.expected6
-rw-r--r--tests/reflection/sample-rate-input.glsl15
-rw-r--r--tests/reflection/sample-rate-input.glsl.expected55
-rw-r--r--tests/reflection/std430-layout.glsl1
13 files changed, 185 insertions, 22 deletions
diff --git a/slang.h b/slang.h
index 28940fd03..14efc26c7 100644
--- a/slang.h
+++ b/slang.h
@@ -531,6 +531,9 @@ extern "C"
SlangUInt axisCount,
SlangUInt* outSizeAlongAxis);
+ SLANG_API int spReflectionEntryPoint_usesAnySampleRateInput(
+ SlangReflectionEntryPoint* entryPoint);
+
// Shader Reflection
SLANG_API unsigned spReflection_GetParameterCount(SlangReflection* reflection);
@@ -893,6 +896,11 @@ namespace slang
{
return spReflectionEntryPoint_getComputeThreadGroupSize((SlangReflectionEntryPoint*) this, axisCount, outSizeAlongAxis);
}
+
+ bool usesAnySampleRateInput()
+ {
+ return 0 != spReflectionEntryPoint_usesAnySampleRateInput((SlangReflectionEntryPoint*) this);
+ }
};
struct ShaderReflection
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 3155bb75a..7df978707 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -565,13 +565,31 @@ namespace Slang
void generateOutput(
CompileRequest* compileRequest)
{
- // Allow for an "extra" target to verride things first.
+ // Start of with per-translation-unit and per-entry-point lowering
+ for( auto translationUnit : compileRequest->translationUnits )
+ {
+ CompileResult translationUnitResult = emitTranslationUnit(translationUnit.Ptr());
+ translationUnit->result = translationUnitResult;
+ }
+
+
+ // Allow for an "extra" target to verride things before we finish.
switch (compileRequest->extraTarget)
{
case CodeGenTarget::ReflectionJSON:
{
String reflectionJSON = emitReflectionJSON(compileRequest->layout.Ptr());
+ // Clobber existing output so we don't have to deal with it
+ for( auto translationUnit : compileRequest->translationUnits )
+ {
+ translationUnit->result = CompileResult();
+ }
+ for( auto entryPoint : compileRequest->entryPoints )
+ {
+ entryPoint->result = CompileResult();
+ }
+
// HACK(tfoley): just print it out since that is what people probably expect.
// TODO: need a way to control where output gets routed across all possible targets.
fprintf(stdout, "%s", reflectionJSON.begin());
@@ -584,12 +602,6 @@ namespace Slang
break;
}
- // For most targets, we will do things per-translation-unit
- for( auto translationUnit : compileRequest->translationUnits )
- {
- CompileResult translationUnitResult = emitTranslationUnit(translationUnit.Ptr());
- translationUnit->result = translationUnitResult;
- }
}
}
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 0c39a98bd..03cc7d8aa 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2833,7 +2833,10 @@ struct EmitVisitor
// Emit a single `regsiter` semantic, as appropriate for a given resource-type-specific layout info
void emitHLSLRegisterSemantic(
- VarLayout::ResourceInfo const& info)
+ VarLayout::ResourceInfo const& info,
+
+ // Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`)
+ char const* uniformSemanticSpelling = "register")
{
if( info.kind == LayoutResourceKind::Uniform )
{
@@ -2845,7 +2848,9 @@ struct EmitVisitor
// units, and then a "component" within that register, based on 4-byte
// offsets from there. We cannot support more fine-grained offsets than that.
- Emit(": packoffset(c");
+ Emit(": ");
+ Emit(uniformSemanticSpelling);
+ Emit("(c");
// Size of a logical `c` register in bytes
auto registerSize = 16;
@@ -2907,7 +2912,8 @@ struct EmitVisitor
// Emit all the `register` semantics that are appropriate for a particular variable layout
void emitHLSLRegisterSemantics(
- RefPtr<VarLayout> layout)
+ RefPtr<VarLayout> layout,
+ char const* uniformSemanticSpelling = "register")
{
if (!layout) return;
@@ -2922,7 +2928,7 @@ struct EmitVisitor
for( auto rr : layout->resourceInfos )
{
- emitHLSLRegisterSemantic(rr);
+ emitHLSLRegisterSemantic(rr, uniformSemanticSpelling);
}
}
@@ -3026,7 +3032,7 @@ struct EmitVisitor
offsetResource.space += cbufferResource->space;
}
- emitHLSLRegisterSemantic(offsetResource);
+ emitHLSLRegisterSemantic(offsetResource, "packoffset");
}
Emit(";\n");
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index ecf23d9ed..02da47ccb 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -210,7 +210,8 @@ struct SharedLoweringContext
{
CompileRequest* compileRequest;
- ProgramLayout* programLayout;
+ ProgramLayout* programLayout;
+ EntryPointLayout* entryPointLayout;
// The target we are going to generate code for.
//
@@ -607,6 +608,8 @@ struct LoweringVisitor
RefPtr<ExpressionSyntaxNode> visitVarExpressionSyntaxNode(
VarExpressionSyntaxNode* expr)
{
+ doSampleRateInputCheck(expr->name);
+
// If the expression didn't get resolved, we can leave it as-is
if (!expr->declRef)
return expr;
@@ -1019,6 +1022,12 @@ struct LoweringVisitor
RefPtr<UnparsedStmt> loweredStmt = new UnparsedStmt();
lowerStmtFields(loweredStmt, stmt);
+ for (auto token : stmt->tokens)
+ {
+ if (token.Type == TokenType::Identifier)
+ doSampleRateInputCheck(token.Content);
+ }
+
loweredStmt->tokens = stmt->tokens;
addStmt(loweredStmt);
@@ -2052,9 +2061,39 @@ struct LoweringVisitor
return SourceLanguage::Unknown;
}
+ void setSampleRateFlag()
+ {
+ shared->entryPointLayout->flags |= EntryPointLayout::Flag::usesAnySampleRateInput;
+ }
+
+ void doSampleRateInputCheck(VarDeclBase* decl)
+ {
+ if (decl->HasModifier<HLSLSampleModifier>())
+ {
+ setSampleRateFlag();
+ }
+ }
+
+ void doSampleRateInputCheck(String const& name)
+ {
+ if (name == "gl_SampleIndex")
+ {
+ setSampleRateFlag();
+ }
+ }
+
RefPtr<VarDeclBase> visitVariable(
Variable* decl)
{
+ // Global variable? Check if it is a sample-rate input.
+ if (dynamic_cast<ProgramSyntaxNode*>(decl->ParentDecl))
+ {
+ if (decl->HasModifier<InModifier>())
+ {
+ doSampleRateInputCheck(decl);
+ }
+ }
+
auto loweredDecl = lowerVarDeclCommon(decl, getClass<Variable>());
if(!loweredDecl)
return nullptr;
@@ -2905,6 +2944,8 @@ LoweredEntryPoint lowerEntryPoint(
bool isRewrite = isRewriteRequest(translationUnit->sourceLanguage, target);
sharedContext.isRewrite = isRewrite;
+ sharedContext.entryPointLayout = visitor.findEntryPointLayout(entryPoint);
+
LoweredEntryPoint result;
if (isRewrite)
{
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index 8e5044d13..1beacc21b 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -751,6 +751,18 @@ SLANG_API void spReflectionEntryPoint_getComputeThreadGroupSize(
}
}
+SLANG_API int spReflectionEntryPoint_usesAnySampleRateInput(
+ SlangReflectionEntryPoint* inEntryPoint)
+{
+ auto entryPointLayout = convert(inEntryPoint);
+ if(!entryPointLayout)
+ return 0;
+
+ if (entryPointLayout->profile.GetStage() != Stage::Fragment)
+ return 0;
+
+ return (entryPointLayout->flags & EntryPointLayout::Flag::usesAnySampleRateInput) != 0;
+}
// Shader Reflection
@@ -1497,6 +1509,11 @@ static void emitReflectionEntryPointJSON(
write(writer, "\n]");
}
+ if (entryPoint->usesAnySampleRateInput())
+ {
+ write(writer, ",\n\"usesAnySampleRateInput\": true");
+ }
+
dedent(writer);
write(writer, "\n}");
}
diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h
index 1a63a4883..add9930ae 100644
--- a/source/slang/type-layout.h
+++ b/source/slang/type-layout.h
@@ -352,6 +352,12 @@ public:
// Layout for any results of the entry point
RefPtr<VarLayout> resultLayout;
+
+ enum Flag : unsigned
+ {
+ usesAnySampleRateInput = 0x1,
+ };
+ unsigned flags = 0;
};
// Layout information for the global scope of a program
diff --git a/tests/reflection/image-types.glsl b/tests/reflection/image-types.glsl
index 21cd2b629..73ecdaa82 100644
--- a/tests/reflection/image-types.glsl
+++ b/tests/reflection/image-types.glsl
@@ -2,9 +2,11 @@
// Confirm that we expose GLSL `image` types through reflection
-uniform imageBuffer iBuffer;
+layout(rgba32f)
+uniform writeonly imageBuffer iBuffer;
-uniform image2D i2D;
+layout(rgba32f)
+uniform writeonly image2D i2D;
void main()
{}
diff --git a/tests/reflection/multi-file-extra.hlsl b/tests/reflection/multi-file-extra.hlsl
index 569ec2ce9..a5da70635 100644
--- a/tests/reflection/multi-file-extra.hlsl
+++ b/tests/reflection/multi-file-extra.hlsl
@@ -18,7 +18,7 @@ float4 use(float val) { return val; };
float4 use(float2 val) { return float4(val,0.0,0.0); };
float4 use(float3 val) { return float4(val,0.0); };
float4 use(float4 val) { return val; };
-float4 use(Texture2D t, SamplerState s) { return t.Sample(s, 0.0); }
+float4 use(Texture2D t, SamplerState s) { return t.SampleLevel(s, 0.0, 0.0); }
// Start with some parameters that will appear in both shaders
Texture2D sharedT;
@@ -51,7 +51,7 @@ Texture2D sharedTV;
Texture2D sharedTF;
-float4 main() : SV_Target
+float4 mainVS() : SV_Position
{
// Go ahead and use everything here, just to make sure things got placed correctly
return use(sharedT, sharedS)
diff --git a/tests/reflection/multi-file.hlsl b/tests/reflection/multi-file.hlsl
index b263a6b71..7f79f08c9 100644
--- a/tests/reflection/multi-file.hlsl
+++ b/tests/reflection/multi-file.hlsl
@@ -1,4 +1,4 @@
-//TEST:SIMPLE:-profile ps_4_0 -target reflection-json Tests/bindings/multi-file-extra.hlsl
+//TEST:SIMPLE:-profile ps_4_0 -entry mainFS -target reflection-json tests/reflection/multi-file-extra.hlsl -profile vs_4_0 -entry mainVS
// Here we are testing the case where multiple translation units are provided
// at once, so that we want combined reflection information for the resulting
@@ -44,7 +44,7 @@ Texture2D sharedTV;
Texture2D sharedTF;
-float4 main() : SV_Position
+float4 mainFS() : SV_Target
{
// Go ahead and use everything here, just to make sure things got placed correctly
return use(sharedT, sharedS)
diff --git a/tests/reflection/multi-file.hlsl.expected b/tests/reflection/multi-file.hlsl.expected
index 3dc23c11c..4ad95fb35 100644
--- a/tests/reflection/multi-file.hlsl.expected
+++ b/tests/reflection/multi-file.hlsl.expected
@@ -236,12 +236,12 @@ standard output = {
],
"entryPoints": [
{
- "name": "main",
+ "name": "mainFS",
"stage:": "fragment"
},
{
- "name": "main",
- "stage:": "fragment"
+ "name": "mainVS",
+ "stage:": "vertex"
}
]
}
diff --git a/tests/reflection/sample-rate-input.glsl b/tests/reflection/sample-rate-input.glsl
new file mode 100644
index 000000000..66763f45d
--- /dev/null
+++ b/tests/reflection/sample-rate-input.glsl
@@ -0,0 +1,15 @@
+//TEST(smoke):SIMPLE:-profile ps_4_0 -no-checking -target reflection-json
+
+// Check that we report sample-rate entry point input correctly
+
+uniform texture2D t;
+uniform sampler s;
+
+sample in vec2 uv;
+
+out vec4 c;
+
+void main()
+{
+ c = texture(sampler2D(t,s), uv);
+}
diff --git a/tests/reflection/sample-rate-input.glsl.expected b/tests/reflection/sample-rate-input.glsl.expected
new file mode 100644
index 000000000..5800a3630
--- /dev/null
+++ b/tests/reflection/sample-rate-input.glsl.expected
@@ -0,0 +1,55 @@
+result code = 0
+standard error = {
+}
+standard output = {
+{
+ "parameters": [
+ {
+ "name": "t",
+ "binding": {"kind": "descriptorTableSlot", "index": 0},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D"
+ }
+ },
+ {
+ "name": "s",
+ "binding": {"kind": "descriptorTableSlot", "index": 1},
+ "type": {
+ "kind": "samplerState"
+ }
+ },
+ {
+ "name": "uv",
+ "binding": {"kind": "vertexInput", "index": 0},
+ "type": {
+ "kind": "vector",
+ "elementCount": 2,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ }
+ }
+ },
+ {
+ "name": "c",
+ "binding": {"kind": "fragmentOutput", "index": 0},
+ "type": {
+ "kind": "vector",
+ "elementCount": 4,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ }
+ }
+ }
+ ],
+ "entryPoints": [
+ {
+ "name": "main",
+ "stage:": "fragment",
+ "usesAnySampleRateInput": true
+ }
+ ]
+}
+}
diff --git a/tests/reflection/std430-layout.glsl b/tests/reflection/std430-layout.glsl
index 5d4dee88f..0e61556fc 100644
--- a/tests/reflection/std430-layout.glsl
+++ b/tests/reflection/std430-layout.glsl
@@ -1,3 +1,4 @@
+#version 450
//TEST(smoke):SIMPLE:-profile ps_4_0 -target reflection-json
// Confirm fix for GitHub issue #55