From 9e079535a04c284d7edd8ebac10b88729d50317d Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Fri, 2 Sep 2016 20:05:19 -0600 Subject: [PATCH] HLSL: Handle greater/less depth modes. Fixes issue #489. --- Test/baseResults/hlsl.depthGreater.frag.out | 57 ++++++++++++++++++++++++++++ Test/baseResults/hlsl.depthLess.frag.out | 58 +++++++++++++++++++++++++++++ Test/hlsl.depthGreater.frag | 4 ++ Test/hlsl.depthLess.frag | 4 ++ glslang/Include/BaseTypes.h | 5 +++ glslang/Include/revision.h | 2 +- gtests/Hlsl.FromFile.cpp | 2 + hlsl/hlslGrammar.cpp | 10 ++--- hlsl/hlslParseHelper.cpp | 29 +++++++++++---- 9 files changed, 158 insertions(+), 13 deletions(-) create mode 100755 Test/baseResults/hlsl.depthGreater.frag.out create mode 100755 Test/baseResults/hlsl.depthLess.frag.out create mode 100644 Test/hlsl.depthGreater.frag create mode 100644 Test/hlsl.depthLess.frag diff --git a/Test/baseResults/hlsl.depthGreater.frag.out b/Test/baseResults/hlsl.depthGreater.frag.out new file mode 100755 index 0000000..cfd819b --- /dev/null +++ b/Test/baseResults/hlsl.depthGreater.frag.out @@ -0,0 +1,57 @@ +hlsl.depthGreater.frag +Shader version: 450 +gl_FragCoord origin is upper left +using depth_greater +0:? Sequence +0:2 Function Definition: PixelShaderFunction(f1; (global void) +0:2 Function Parameters: +0:2 'depth' (out float FragDepth) +0:? Sequence +0:3 move second child to first child (temp float) +0:3 'depth' (out float FragDepth) +0:3 Constant: +0:3 0.200000 +0:? Linker Objects + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +using depth_greater +0:? Sequence +0:2 Function Definition: PixelShaderFunction(f1; (global void) +0:2 Function Parameters: +0:2 'depth' (out float FragDepth) +0:? Sequence +0:3 move second child to first child (temp float) +0:3 'depth' (out float FragDepth) +0:3 Constant: +0:3 0.200000 +0:? Linker Objects + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 10 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "PixelShaderFunction" 8 + ExecutionMode 4 OriginUpperLeft + ExecutionMode 4 DepthGreater + Name 4 "PixelShaderFunction" + Name 8 "depth" + Decorate 8(depth) BuiltIn FragDepth + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Output 6(float) + 8(depth): 7(ptr) Variable Output + 9: 6(float) Constant 1045220557 +4(PixelShaderFunction): 2 Function None 3 + 5: Label + Store 8(depth) 9 + Return + FunctionEnd diff --git a/Test/baseResults/hlsl.depthLess.frag.out b/Test/baseResults/hlsl.depthLess.frag.out new file mode 100755 index 0000000..66231b3 --- /dev/null +++ b/Test/baseResults/hlsl.depthLess.frag.out @@ -0,0 +1,58 @@ +hlsl.depthLess.frag +Shader version: 450 +gl_FragCoord origin is upper left +using depth_less +0:? Sequence +0:2 Function Definition: PixelShaderFunction( (global float FragDepth) +0:2 Function Parameters: +0:? Sequence +0:3 Sequence +0:3 move second child to first child (temp float) +0:? '@entryPointOutput' (out float unknown built-in variable) +0:3 Constant: +0:3 0.200000 +0:3 Branch: Return +0:? Linker Objects + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +using depth_less +0:? Sequence +0:2 Function Definition: PixelShaderFunction( (global float FragDepth) +0:2 Function Parameters: +0:? Sequence +0:3 Sequence +0:3 move second child to first child (temp float) +0:? '@entryPointOutput' (out float unknown built-in variable) +0:3 Constant: +0:3 0.200000 +0:3 Branch: Return +0:? Linker Objects + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 11 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "PixelShaderFunction" 8 + ExecutionMode 4 OriginUpperLeft + ExecutionMode 4 DepthLess + Name 4 "PixelShaderFunction" + Name 8 "@entryPointOutput" + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Output 6(float) +8(@entryPointOutput): 7(ptr) Variable Output + 9: 6(float) Constant 1045220557 +4(PixelShaderFunction): 2 Function None 3 + 5: Label + Store 8(@entryPointOutput) 9 + Return + FunctionEnd diff --git a/Test/hlsl.depthGreater.frag b/Test/hlsl.depthGreater.frag new file mode 100644 index 0000000..ca41f08 --- /dev/null +++ b/Test/hlsl.depthGreater.frag @@ -0,0 +1,4 @@ +void PixelShaderFunction(out float depth : SV_DepthGreaterEqual) +{ + depth = 0.2; +} diff --git a/Test/hlsl.depthLess.frag b/Test/hlsl.depthLess.frag new file mode 100644 index 0000000..aca7dbb --- /dev/null +++ b/Test/hlsl.depthLess.frag @@ -0,0 +1,4 @@ +float PixelShaderFunction() : SV_DepthLessEqual +{ + return 0.2; +} diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index 7e12c55..bc8f110 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -196,6 +196,11 @@ enum TBuiltInVariable { EbvBaryCoordPullModel, #endif + // HLSL built-ins that live only temporarily, until they get remapped + // to one of the above. + EbvFragDepthGreater, + EbvFragDepthLesser, + EbvLast }; diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 864613e..be71662 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1461" +#define GLSLANG_REVISION "Overload400-PrecQual.1463" #define GLSLANG_DATE "02-Sep-2016" diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 8c9b555..9fb3840 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -81,6 +81,8 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.cast.frag", "PixelShaderFunction"}, {"hlsl.conditional.frag", "PixelShaderFunction"}, {"hlsl.constructexpr.frag", "main"}, + {"hlsl.depthGreater.frag", "PixelShaderFunction"}, + {"hlsl.depthLess.frag", "PixelShaderFunction"}, {"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.doLoop.frag", "PixelShaderFunction"}, {"hlsl.entry-out.frag", "PixelShaderFunction"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index e548e5d..6ddd1bf 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -302,10 +302,10 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) HlslToken idToken; while (acceptIdentifier(idToken)) { // function_parameters - TFunction* function = new TFunction(idToken.string, type); - if (acceptFunctionParameters(*function)) { + TFunction& function = *new TFunction(idToken.string, type); + if (acceptFunctionParameters(function)) { // post_decls - acceptPostDecls(type); + acceptPostDecls(function.getWritableType()); // compound_statement (function body definition) or just a prototype? if (peekTokenClass(EHTokLeftBrace)) { @@ -313,11 +313,11 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) parseContext.error(idToken.loc, "function body can't be in a declarator list", "{", ""); if (typedefDecl) parseContext.error(idToken.loc, "function body can't be in a typedef", "{", ""); - return acceptFunctionDefinition(*function, node); + return acceptFunctionDefinition(function, node); } else { if (typedefDecl) parseContext.error(idToken.loc, "function typedefs not implemented", "{", ""); - parseContext.handleFunctionDeclarator(idToken.loc, *function, true); + parseContext.handleFunctionDeclarator(idToken.loc, function, true); } } else { // a variable declaration diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 96270c8..5f4d8c5 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -819,6 +819,21 @@ void HlslParseContext::remapEntrypointIO(TFunction& function) unsigned int inCount = 0; unsigned int outCount = 0; + const auto remapBuiltInType = [&](TType& type) { + switch (type.getQualifier().builtIn) { + case EbvFragDepthGreater: + intermediate.setDepth(EldGreater); + type.getQualifier().builtIn = EbvFragDepth; + break; + case EbvFragDepthLesser: + intermediate.setDepth(EldLess); + type.getQualifier().builtIn = EbvFragDepth; + break; + default: + break; + } + }; + // return value is actually a shader-scoped output (out) if (function.getType().getBasicType() != EbtVoid) { entryPointOutput = makeInternalVariable("@entryPointOutput", function.getType()); @@ -827,6 +842,7 @@ void HlslParseContext::remapEntrypointIO(TFunction& function) entryPointOutput->getWritableType().getQualifier().layoutLocation = outCount; outCount += intermediate.computeTypeLocationSize(function.getType()); } + remapBuiltInType(function.getWritableType()); } // parameters are actually shader-scoped inputs and outputs (in or out) @@ -844,6 +860,7 @@ void HlslParseContext::remapEntrypointIO(TFunction& function) outCount += intermediate.computeTypeLocationSize(*function[i].type); } } + remapBuiltInType(*function[i].type); } } @@ -2423,13 +2440,11 @@ void HlslParseContext::handleSemantic(TSourceLoc loc, TType& type, const TString type.getQualifier().builtIn = EbvFragDepth; //TODO, these need to get refined to be more specific - else if( semanticUpperCase == "SV_DEPTHGREATEREQUAL") { - type.getQualifier().builtIn = EbvFragDepth; - warn(loc, "depth mode unimplemented", "SV_DEPTHGREATEREQUAL", ""); - } else if( semanticUpperCase == "SV_DEPTHLESSEQUAL") { - type.getQualifier().builtIn = EbvFragDepth; - warn(loc, "depth mode unimplemented", "SV_DEPTHLESSEQUAL", ""); - } else if( semanticUpperCase == "SV_STENCILREF") + else if( semanticUpperCase == "SV_DEPTHGREATEREQUAL") + type.getQualifier().builtIn = EbvFragDepthGreater; + else if( semanticUpperCase == "SV_DEPTHLESSEQUAL") + type.getQualifier().builtIn = EbvFragDepthLesser; + else if( semanticUpperCase == "SV_STENCILREF") error(loc, "unimplemented", "SV_STENCILREF", ""); else if( semanticUpperCase == "SV_COVERAGE") error(loc, "unimplemented", "SV_COVERAGE", ""); -- 2.7.4