diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-19 09:04:41 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-19 09:04:41 -0700 |
| commit | 5995b7a47b2b65025410b9d558dfe1820e4c42e0 (patch) | |
| tree | 064b0a10e989f78e5f87ea0734a774b1d043dd6e /source/slang/emit.cpp | |
| parent | a12480fe49d5ba7c0a9c2ac63363dc76b599ddbd (diff) | |
Initial work on a pass to scalarize GLSL varying input/output (#223)
There was already a pass in place that transformed parameters and results of an entry-point function into global variables for GLSL, but this pass would just turn a `struct`-type parameter into a `struct`-type global, which has two problems:
- The standard GLSL language doesn't seem to allow `struct` types as vertex shader inputs or fragment shader outputs.
- If there are any members in such a `struct` that represent "system value" inputs or outputs, then these would need to be transformed into the equivalent `gl_*` variables.
This change adds a more complete scalarization process that applies to inputs/outputs during the legalization pass. In order to support this there is a little bit of a data strcuture for abstracting over tuples of values (this same idiom is used in a few other places, so perhaps the implementation could be done once and shared?).
System values are current handled in a painfully ad hoc (and incomplete) fashion during code emit. We need to come up with a better solution for mapping HLSL `SV_*` semantics over to `gl_*` variables.
In some cases this mapping might introduce more code than we can easily deal with during emit time, so it probably needs to be handled back at the IR level.
This implementation has many gaps, but it appears to be enough to get teh `render/cross-compile-entry-point` test working with IR-based cross-compilation.
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index d8d9e13ed..971f0345b 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4060,7 +4060,29 @@ emitDeclImpl(decl, nullptr); return getIRName(declRef.decl); } - String getIRName(IRValue* inst) + String getGLSLSystemValueName( + VarLayout* varLayout) + { + auto semanticName = varLayout->systemValueSemantic; + semanticName = semanticName.ToLower(); + auto semanticIndex = varLayout->systemValueSemanticIndex; + + if(semanticName == "sv_position") + { + return "gl_Position"; + } + else if(semanticName == "sv_target") + { + return ""; + } + else + { + return "gl_Unknown"; + } + } + + String getIRName( + IRValue* inst) { switch(inst->op) { @@ -4075,6 +4097,23 @@ emitDeclImpl(decl, nullptr); break; } + if(getTarget(context) == CodeGenTarget::GLSL) + { + if(auto layoutMod = inst->findDecoration<IRLayoutDecoration>()) + { + auto layout = layoutMod->layout; + if(auto varLayout = layout.As<VarLayout>()) + { + if(varLayout->systemValueSemantic.Length() != 0) + { + auto translated = getGLSLSystemValueName(varLayout); + if(translated.Length()) + return translated; + } + } + } + } + if(auto decoration = inst->findDecoration<IRHighLevelDeclDecoration>()) { auto decl = decoration->decl; @@ -5066,7 +5105,7 @@ emitDeclImpl(decl, nullptr); if (!decoration) return nullptr; - return (VarLayout*) decoration->layout; + return (VarLayout*) decoration->layout.Ptr(); } void emitIRLayoutSemantics( @@ -5490,7 +5529,7 @@ emitDeclImpl(decl, nullptr); { if( auto layoutDecoration = func->findDecoration<IRLayoutDecoration>() ) { - return dynamic_cast<EntryPointLayout*>(layoutDecoration->layout); + return layoutDecoration->layout.As<EntryPointLayout>(); } return nullptr; } @@ -5575,7 +5614,7 @@ emitDeclImpl(decl, nullptr); { if (auto layoutDecoration = func->findDecoration<IRLayoutDecoration>()) { - if (auto entryPointLayout = dynamic_cast<EntryPointLayout*>(layoutDecoration->layout)) + if (auto entryPointLayout = layoutDecoration->layout.As<EntryPointLayout>()) { return entryPointLayout; } |
