diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-27 09:13:19 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-27 09:13:19 -0700 |
| commit | 996d4dc537272e36dde1d9c1110064d597fa212f (patch) | |
| tree | 8958b8c8848d2b7760a5b71ecef69574e4d9d6ab | |
| parent | 8824b102a5dd5ac1f08daedd897b5994b1bf8b6d (diff) | |
Emit global-scope parameters from imported files.
This fixes up a bug in the earlier change that provided reflection for imported parameters; I'd failed to confirm that the code generation logic can handle imported parameters correctly.
The main fix was to have an `import` declaration automatically use the global-scope layout already determined, sine imported parameters will in general appear there.
| -rw-r--r-- | source/slang/emit.cpp | 15 | ||||
| -rw-r--r-- | tests/render/imported-parameters.hlsl | 134 | ||||
| -rw-r--r-- | tests/render/imported-parameters.slang | 23 |
3 files changed, 171 insertions, 1 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 699294d84..77b0c2fe9 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -35,7 +35,16 @@ struct EmitContext Dictionary<String, int> mapGLSLSourcePathToID; int glslSourceIDCount = 0; + // We only want to emit each `import`ed module one time, so + // we maintain a set of already-emitted modules. HashSet<ProgramSyntaxNode*> modulesAlreadyEmitted; + + // We track the original global-scope layout so that we can + // find layout information for `import`ed parameters. + // + // TODO: This will probably change if we represent imports + // explicitly in the layout data. + StructTypeLayout* globalStructLayout; }; // @@ -2628,6 +2637,8 @@ static void EmitProgram( auto globalScopeLayout = programLayout->globalScopeLayout; if( auto globalStructLayout = globalScopeLayout.As<StructTypeLayout>() ) { + context->globalStructLayout = globalStructLayout.Ptr(); + // The `struct` case is easy enough to handle: we just // emit all the declarations directly, using their layout // information as a guideline. @@ -2657,6 +2668,8 @@ static void EmitProgram( // We expect all constant buffers to contain `struct` types for now assert(elementTypeStructLayout); + context->globalStructLayout = elementTypeStructLayout.Ptr(); + EmitDeclsInContainerUsingLayout( context, program, @@ -2732,7 +2745,7 @@ static void EmitDeclImpl(EmitContext* context, RefPtr<Decl> decl, RefPtr<VarLayo // TODO: do we need to modify the code generation environment at // all when doing this recursive emit? - EmitDeclsInContainer(context, moduleDecl); + EmitDeclsInContainerUsingLayout(context, moduleDecl, context->globalStructLayout); } return; diff --git a/tests/render/imported-parameters.hlsl b/tests/render/imported-parameters.hlsl new file mode 100644 index 000000000..605214fc9 --- /dev/null +++ b/tests/render/imported-parameters.hlsl @@ -0,0 +1,134 @@ +//TEST(smoke,render):COMPARE_HLSL_GLSL_RENDER: + +// This test is trying to ensure that we can +// correctly handle cases where top-level shader +// parameters are declared in an `import`ed file. + +// Pull in Spire code depdendency using extended syntax: +__import imported_parameters; + +#if defined(__HLSL__) + +struct AssembledVertex +{ + float3 position; + float3 color; +}; + +struct CoarseVertex +{ + float3 color; +}; + +struct Fragment +{ + float4 color; +}; + +// Vertex Shader + +struct VertexStageInput +{ + AssembledVertex assembledVertex : A; +}; + +struct VertexStageOutput +{ + CoarseVertex coarseVertex : CoarseVertex; + float4 sv_position : SV_Position; +}; + +VertexStageOutput vertexMain(VertexStageInput input) +{ + VertexStageOutput output; + + float3 position = input.assembledVertex.position; + float3 color = input.assembledVertex.color; + + output.coarseVertex.color = color; + output.sv_position = mul(modelViewProjection, float4(position, 1.0)); + + return output; + +} + +// Fragment Shader + +struct FragmentStageInput +{ + CoarseVertex coarseVertex : CoarseVertex; +}; + +struct FragmentStageOutput +{ + Fragment fragment : SV_Target; +}; + +FragmentStageOutput fragmentMain(FragmentStageInput input) +{ + FragmentStageOutput output; + + float3 color = input.coarseVertex.color; + + color = transformColor(color); + + output.fragment.color = float4(color, 1.0); + + return output; +} + +#elif defined(__GLSL__) + +#version 420 + +#define ASSEMBLED_VERTEX(QUAL) \ + /* */ + +#define V2F(QUAL) \ + QUAL vec3 coarse_color; \ + /* */ + +// Vertex Shader + +#ifdef __GLSL_VERTEX__ + +layout(location = 0) +in vec3 assembled_position; + +layout(location = 1) +in vec3 assembled_color; + +V2F(out) + +void main() +{ + vec3 position = assembled_position; + vec3 color = assembled_color; + + coarse_color = color; +// gl_Position = modelViewProjection * vec4(position, 1.0); + gl_Position = vec4(position, 1.0) * modelViewProjection; +} + +#endif + +#ifdef __GLSL_FRAGMENT__ + +V2F(in) + +layout(location = 0) +out vec4 fragment_color; + +void main() +{ + vec3 color = coarse_color; + + color = transformColor(color); + + fragment_color = vec4(color, 1.0); +} + + +#endif + +#endif diff --git a/tests/render/imported-parameters.slang b/tests/render/imported-parameters.slang new file mode 100644 index 000000000..7c444a67b --- /dev/null +++ b/tests/render/imported-parameters.slang @@ -0,0 +1,23 @@ +//TEST_IGNORE_FILE: + +// We are declaring the uniform shader parameters +// in this imported file, to ensure that they are +// emitted correctly. + +cbuffer Uniforms +{ + float4x4 modelViewProjection; +}; + +float3 transformColor(float3 color) +{ + float3 result; + + result.x = sin(20.0 * (color.x + color.y)); + result.y = saturate(cos(color.z * 30.0)); + result.z = sin(color.x * color.y * color.z * 100.0); + + result = 0.5 * (result + 1); + + return result; +}
\ No newline at end of file |
