1 //
2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DynamicHLSL.h: Interface for link and run-time HLSL generation
7 //
8 
9 #ifndef LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
10 #define LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
11 
12 #include <map>
13 #include <vector>
14 
15 #include "angle_gl.h"
16 #include "common/angleutils.h"
17 #include "libANGLE/Constants.h"
18 #include "libANGLE/Program.h"
19 #include "libANGLE/angletypes.h"
20 #include "libANGLE/formatutils.h"
21 #include "libANGLE/renderer/d3d/RendererD3D.h"
22 
23 namespace sh
24 {
25 struct Attribute;
26 struct ShaderVariable;
27 }
28 
29 namespace gl
30 {
31 class InfoLog;
32 struct VariableLocation;
33 class VaryingPacking;
34 struct VertexAttribute;
35 }
36 
37 namespace rx
38 {
39 class ProgramD3DMetadata;
40 class ShaderD3D;
41 
42 struct PixelShaderOutputVariable
43 {
PixelShaderOutputVariablePixelShaderOutputVariable44     PixelShaderOutputVariable() {}
PixelShaderOutputVariablePixelShaderOutputVariable45     PixelShaderOutputVariable(GLenum typeIn,
46                               const std::string &nameIn,
47                               const std::string &sourceIn,
48                               size_t outputIndexIn)
49         : type(typeIn), name(nameIn), source(sourceIn), outputIndex(outputIndexIn)
50     {
51     }
52 
53     GLenum type = GL_NONE;
54     std::string name;
55     std::string source;
56     size_t outputIndex = 0;
57 };
58 
59 struct BuiltinVarying final : private angle::NonCopyable
60 {
61     BuiltinVarying();
62 
63     std::string str() const;
64     void enableSystem(const std::string &systemValueSemantic);
65     void enable(const std::string &semanticVal, unsigned int indexVal);
66 
67     bool enabled;
68     std::string semantic;
69     unsigned int index;
70     bool systemValue;
71 };
72 
73 struct BuiltinInfo
74 {
75     BuiltinInfo();
76     ~BuiltinInfo();
77 
78     BuiltinVarying dxPosition;
79     BuiltinVarying glPosition;
80     BuiltinVarying glFragCoord;
81     BuiltinVarying glPointCoord;
82     BuiltinVarying glPointSize;
83     BuiltinVarying glViewIDOVR;
84     BuiltinVarying glViewportIndex;
85     BuiltinVarying glLayer;
86 };
87 
GetVaryingSemantic(int majorShaderModel,bool programUsesPointSize)88 inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize)
89 {
90     // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
91     // In D3D11 we manually compute gl_PointCoord in the GS.
92     return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD");
93 }
94 
95 class BuiltinVaryingsD3D
96 {
97   public:
98     BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
99     ~BuiltinVaryingsD3D();
100 
usesPointSize()101     bool usesPointSize() const { return mBuiltinInfo[gl::SHADER_VERTEX].glPointSize.enabled; }
102 
103     const BuiltinInfo &operator[](gl::ShaderType shaderType) const
104     {
105         return mBuiltinInfo[shaderType];
106     }
107     BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
108 
109   private:
110     void updateBuiltins(gl::ShaderType shaderType,
111                         const ProgramD3DMetadata &metadata,
112                         const gl::VaryingPacking &packing);
113 
114     std::array<BuiltinInfo, gl::SHADER_TYPE_MAX> mBuiltinInfo;
115 };
116 
117 class DynamicHLSL : angle::NonCopyable
118 {
119   public:
120     explicit DynamicHLSL(RendererD3D *const renderer);
121 
122     std::string generateVertexShaderForInputLayout(
123         const std::string &sourceShader,
124         const gl::InputLayout &inputLayout,
125         const std::vector<sh::Attribute> &shaderAttributes) const;
126     std::string generatePixelShaderForOutputSignature(
127         const std::string &sourceShader,
128         const std::vector<PixelShaderOutputVariable> &outputVariables,
129         bool usesFragDepth,
130         const std::vector<GLenum> &outputLayout) const;
131     void generateShaderLinkHLSL(const gl::Context *context,
132                                 const gl::ProgramState &programData,
133                                 const ProgramD3DMetadata &programMetadata,
134                                 const gl::VaryingPacking &varyingPacking,
135                                 const BuiltinVaryingsD3D &builtinsD3D,
136                                 std::string *pixelHLSL,
137                                 std::string *vertexHLSL) const;
138     std::string generateComputeShaderLinkHLSL(const gl::Context *context,
139                                               const gl::ProgramState &programData) const;
140 
141     std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
142                                                const BuiltinVaryingsD3D &builtinsD3D,
143                                                const bool hasANGLEMultiviewEnabled,
144                                                const bool selectViewInVS) const;
145 
146     std::string generateGeometryShaderHLSL(const gl::Context *context,
147                                            gl::PrimitiveType primitiveType,
148                                            const gl::ProgramState &programData,
149                                            const bool useViewScale,
150                                            const bool hasANGLEMultiviewEnabled,
151                                            const bool selectViewInVS,
152                                            const bool pointSpriteEmulation,
153                                            const std::string &preambleString) const;
154 
155     void getPixelShaderOutputKey(const gl::ContextState &data,
156                                  const gl::ProgramState &programData,
157                                  const ProgramD3DMetadata &metadata,
158                                  std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
159 
160   private:
161     RendererD3D *const mRenderer;
162 
163     void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking,
164                                  const BuiltinInfo &builtins,
165                                  bool programUsesPointSize,
166                                  std::ostringstream &hlslStream) const;
167 
168     static void GenerateAttributeConversionHLSL(gl::VertexFormatType vertexFormatType,
169                                                 const sh::ShaderVariable &shaderAttrib,
170                                                 std::ostringstream &outStream);
171 };
172 
173 }  // namespace rx
174 
175 #endif  // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
176