diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-11-29 11:45:15 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-29 11:45:15 -0800 |
| commit | b487516880f56fd69ff76bf7cb3f0f1711bc356d (patch) | |
| tree | 0f1464a22ac7f52053ab4f8f768967c1383c597c /source/slang/parameter-binding.cpp | |
| parent | 713938038a87b9e4a69f198f09f1bf231be6f72f (diff) | |
Add API to query stage of varying parameter (#302)
Fixes #301
The problem here is that if you have input GLSL code like:
```glsl
// example.vs
in vec3 pos;
```
and:
```glsl
// example.fs
in vec3 worldPos;
```
Then both `pos` and `worldPos` are reflected as global variables (parameters of the *program*), which both get bound to "varying input" resources, but there is no way to tell through the API that `pos` is a vertex parameter while `worldPos` is a fragment one.
The original request in issue #301 was to expose parameters like this not as a global variables, but rather as parameters of the entry point in their specific file. That is, treat it as if the user had written, e.g.:
```glsl
// example.vs
void vsMain(in vec3 pos) { ... }
```
Doing that would unify the GLSL and HLSL/Slang cases a bit, but would require the Slang reflection API to lie about the structure of code the user wrote. At a more basic level, that would have been hard to implement because the current reflection API just exposes the underlying AST, and the AST *needs* to leave `pos` at the global scope so that when we go and spit GLSL back out we retain the original structure.
This PR implements a more simplistic solution, where the user is allowed to query the stage that a varying parameter "belongs" to. For right now I'm only enabling this to work for varying parameters (but it doesn't care if they are entry-point or global-scope varyings). Despite what I said on #301, this should work for both the top-level parameter's variable layout, *and* any variable layouts for fields within its type reflection.
In terms of implementation, I took the simple but wasteful route: every `VarLayout` now has a `stage` field that is by default initialized to `SLANG_STAGE_NONE`. When collecting varying parameters, I take advantage of the fact that everything bottlenecks through `processEntryPointParameter()` which takes an `EntryPointParameterState` so that I can set the `VarLayout::stage` field for any varying parameter in one place.
While I was making this change, I also did a bit of cleanup so that the "official" names for the varying parameter categories are `VARYING_INPUT` and `VARYING_OUTPUT`, with `VERTEX_INPUT` and `FRAGMENT_OUTPUT` being "deprecated" in principle. I didn't do the bulk rename inside the codebase yet.
Diffstat (limited to 'source/slang/parameter-binding.cpp')
| -rw-r--r-- | source/slang/parameter-binding.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index b97c174fc..66f7d437c 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -627,6 +627,7 @@ struct EntryPointParameterState int* ioSemanticIndex = nullptr; EntryPointParameterDirectionMask directionMask; int semanticSlotCount; + Stage stage = Stage::Unknown; }; @@ -639,7 +640,7 @@ static RefPtr<TypeLayout> processEntryPointParameter( static void collectGlobalScopeGLSLVaryingParameter( ParameterBindingContext* context, RefPtr<VarDeclBase> varDecl, - RefPtr<Type> effectiveType, + RefPtr<Type> effectiveType, EntryPointParameterDirection direction) { int defaultSemanticIndex = 0; @@ -647,6 +648,7 @@ static void collectGlobalScopeGLSLVaryingParameter( EntryPointParameterState state; state.directionMask = direction; state.ioSemanticIndex = &defaultSemanticIndex; + state.stage = context->stage; RefPtr<VarLayout> varLayout = new VarLayout(); varLayout->varDecl = makeDeclRef(varDecl.Ptr()); @@ -1333,6 +1335,10 @@ static RefPtr<TypeLayout> processEntryPointParameter( varLayout->flags |= VarLayoutFlag::HasSemantic; } + if (varLayout) + { + varLayout->stage = state.stage; + } // Scalar and vector types are treated as outputs directly if(auto basicType = type->As<BasicExpressionType>()) @@ -1485,6 +1491,7 @@ static void collectEntryPointParameters( state.ioSemanticIndex = &defaultSemanticIndex; state.optSemanticName = nullptr; state.semanticSlotCount = 0; + state.stage = entryPoint->profile.GetStage(); for( auto m : entryPointFuncDecl->Members ) { @@ -2020,6 +2027,7 @@ RefPtr<ProgramLayout> specializeProgramLayout( RefPtr<VarLayout> newVarLayout = new VarLayout(); RefPtr<ParameterInfo> paramInfo = new ParameterInfo(); newVarLayout->varDecl = varLayout->varDecl; + newVarLayout->stage = varLayout->stage; newVarLayout->typeLayout = newTypeLayout; paramInfo->varLayouts.Add(newVarLayout); completeBindingsForParameter(&context, paramInfo); |
