From 5b7c254d24653fd1c19157e8d5ef68a7e787ff58 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 10 Jul 2017 09:29:11 -0700 Subject: Start handling system-value semantics during lowering I hadn't been lowering `SV_Position` outputs to `gl_Position`, and had somehow been relying on hidden driver behavior that I guess made things Just Work. This change adds some infrastructure to handle `SV_` semantics during lowering of an entry point (currently only covering `SV_Position` and `SV_Target`, FWIW). As a byproduct, this also means that a `VarLayout` stores semantic info, which could conceivably be exposed through reflection data now. --- source/slang/lower.cpp | 93 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 19 deletions(-) (limited to 'source/slang/lower.cpp') diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 023c63591..165812fae 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -1545,38 +1545,93 @@ struct LoweringVisitor type = arrayType; } - // TODO: if we are declaring an SOA-ized array, - // this is where those array dimensions would need - // to be tacked on. + // We need to create a reference to the global-scope declaration + // of the proper GLSL input/output variable. This might + // be a user-defined input/output, or a system-defined `gl_` one. + RefPtr globalVarExpr; + + // Handle system-value inputs/outputs + assert(varLayout); + auto systemValueSemantic = varLayout->systemValueSemantic; + if (systemValueSemantic.Length() != 0) + { + auto ns = systemValueSemantic.ToLower(); - RefPtr globalVarDecl = new Variable(); - globalVarDecl->Name.Content = info.name; - globalVarDecl->Type.type = type; + if (ns == "sv_target") + { + // Note: we do *not* need to generate some kind of `gl_` + // builtin for fragment-shader outputs: they are just + // ordinary `out` variables, with ordinary `location`s, + // as far as GLSL is concerned. + } + else if (ns == "sv_position") + { + RefPtr globalVarRef = new VarExpressionSyntaxNode(); + globalVarRef->name = "gl_Position"; + globalVarExpr = globalVarRef; + } + else + { + assert(!"unhandled"); + } + } - ensureDeclHasAValidName(globalVarDecl); + // If we didn't match some kind of builtin input/output, + // then declare a user input/output variable instead + if (!globalVarExpr) + { + RefPtr globalVarDecl = new Variable(); + globalVarDecl->Name.Content = info.name; + globalVarDecl->Type.type = type; - addMember(shared->loweredProgram, globalVarDecl); + ensureDeclHasAValidName(globalVarDecl); - // Add the layout information - RefPtr modifier = new ComputedLayoutModifier(); - modifier->layout = varLayout; - addModifier(globalVarDecl, modifier); + addMember(shared->loweredProgram, globalVarDecl); - // Need to generate an assignment in the right direction. + // Add the layout information + RefPtr modifier = new ComputedLayoutModifier(); + modifier->layout = varLayout; + addModifier(globalVarDecl, modifier); + + // Add appropriate in/out modifier + switch (info.direction) + { + case VaryingParameterDirection::Input: + addModifier(globalVarDecl, new InModifier()); + break; + + case VaryingParameterDirection::Output: + addModifier(globalVarDecl, new OutModifier()); + break; + } + + + RefPtr globalVarRef = new VarExpressionSyntaxNode(); + globalVarRef->Position = globalVarDecl->Position; + globalVarRef->declRef = makeDeclRef(globalVarDecl.Ptr()); + globalVarRef->name = globalVarDecl->getName(); + + globalVarExpr = globalVarRef; + } + + // TODO: if we are declaring an SOA-ized array, + // this is where those array dimensions would need + // to be tacked on. // - // TODO: for now I am just dealing with input: + // That is, this logic should be getting collected into a loop, + // and so we need to have a loop variable we can use to + // index into the two different expressions. + + // Need to generate an assignment in the right direction. switch (info.direction) { case VaryingParameterDirection::Input: - addModifier(globalVarDecl, new InModifier()); - assign(varExpr, globalVarDecl); + assign(varExpr, globalVarExpr); break; case VaryingParameterDirection::Output: - addModifier(globalVarDecl, new OutModifier()); - - assign(globalVarDecl, varExpr); + assign(globalVarExpr, varExpr); break; } } -- cgit v1.2.3