1 //
2 // Copyright 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/DynamicImage2DHLSL.h"
22 #include "libANGLE/renderer/d3d/RendererD3D.h"
23 
24 namespace sh
25 {
26 struct ShaderVariable;
27 }  // namespace sh
28 
29 namespace gl
30 {
31 class InfoLog;
32 struct VariableLocation;
33 class VaryingPacking;
34 struct VertexAttribute;
35 }  // namespace gl
36 
37 namespace rx
38 {
39 class ProgramD3DMetadata;
40 class ShaderD3D;
41 
42 // This class needs to match OutputHLSL::decorate
43 class DecorateVariable final : angle::NonCopyable
44 {
45   public:
DecorateVariable(const std::string & str)46     explicit DecorateVariable(const std::string &str) : mName(str) {}
getName()47     const std::string &getName() const { return mName; }
48 
49   private:
50     const std::string &mName;
51 };
52 
53 inline std::ostream &operator<<(std::ostream &o, const DecorateVariable &dv)
54 {
55     if (dv.getName().compare(0, 3, "gl_") != 0)
56     {
57         o << "_";
58     }
59     o << dv.getName();
60     return o;
61 }
62 
63 struct PixelShaderOutputVariable
64 {
PixelShaderOutputVariablePixelShaderOutputVariable65     PixelShaderOutputVariable() {}
PixelShaderOutputVariablePixelShaderOutputVariable66     PixelShaderOutputVariable(GLenum typeIn,
67                               const std::string &nameIn,
68                               const std::string &sourceIn,
69                               size_t outputLocationIn,
70                               size_t outputIndexIn)
71         : type(typeIn),
72           name(nameIn),
73           source(sourceIn),
74           outputLocation(outputLocationIn),
75           outputIndex(outputIndexIn)
76     {}
77 
78     GLenum type = GL_NONE;
79     std::string name;
80     std::string source;
81     size_t outputLocation = 0;
82     size_t outputIndex    = 0;
83 };
84 
85 struct BuiltinVarying final : private angle::NonCopyable
86 {
87     BuiltinVarying();
88 
89     std::string str() const;
90     void enableSystem(const std::string &systemValueSemantic);
91     void enable(const std::string &semanticVal, unsigned int indexVal);
92 
93     bool enabled;
94     std::string semantic;
95     unsigned int index;
96     bool systemValue;
97 };
98 
99 struct BuiltinInfo
100 {
101     BuiltinInfo();
102     ~BuiltinInfo();
103 
104     BuiltinVarying dxPosition;
105     BuiltinVarying glPosition;
106     BuiltinVarying glFragCoord;
107     BuiltinVarying glPointCoord;
108     BuiltinVarying glPointSize;
109     BuiltinVarying glViewIDOVR;
110     BuiltinVarying glViewportIndex;
111     BuiltinVarying glLayer;
112 };
113 
GetVaryingSemantic(int majorShaderModel,bool programUsesPointSize)114 inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize)
115 {
116     // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
117     // In D3D11 we manually compute gl_PointCoord in the GS.
118     return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD");
119 }
120 
121 class BuiltinVaryingsD3D
122 {
123   public:
124     BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
125     ~BuiltinVaryingsD3D();
126 
usesPointSize()127     bool usesPointSize() const { return mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled; }
128 
129     const BuiltinInfo &operator[](gl::ShaderType shaderType) const
130     {
131         return mBuiltinInfo[shaderType];
132     }
133     BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
134 
135   private:
136     void updateBuiltins(gl::ShaderType shaderType,
137                         const ProgramD3DMetadata &metadata,
138                         const gl::VaryingPacking &packing);
139 
140     gl::ShaderMap<BuiltinInfo> mBuiltinInfo;
141 };
142 
143 class DynamicHLSL : angle::NonCopyable
144 {
145   public:
146     explicit DynamicHLSL(RendererD3D *const renderer);
147 
148     std::string generateVertexShaderForInputLayout(
149         const std::string &sourceShader,
150         const gl::InputLayout &inputLayout,
151         const std::vector<sh::ShaderVariable> &shaderAttributes) const;
152     std::string generatePixelShaderForOutputSignature(
153         const std::string &sourceShader,
154         const std::vector<PixelShaderOutputVariable> &outputVariables,
155         bool usesFragDepth,
156         const std::vector<GLenum> &outputLayout) const;
157     std::string generateComputeShaderForImage2DBindSignature(
158         const d3d::Context *context,
159         ProgramD3D &programD3D,
160         const gl::ProgramState &programData,
161         std::vector<sh::ShaderVariable> &image2DUniforms,
162         const gl::ImageUnitTextureTypeMap &image2DBindLayout) const;
163     void generateShaderLinkHLSL(const gl::Caps &caps,
164                                 const gl::ProgramState &programData,
165                                 const ProgramD3DMetadata &programMetadata,
166                                 const gl::VaryingPacking &varyingPacking,
167                                 const BuiltinVaryingsD3D &builtinsD3D,
168                                 gl::ShaderMap<std::string> *shaderHLSL) const;
169 
170     std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
171                                                const BuiltinVaryingsD3D &builtinsD3D,
172                                                const bool hasANGLEMultiviewEnabled,
173                                                const bool selectViewInVS) const;
174 
175     std::string generateGeometryShaderHLSL(const gl::Caps &caps,
176                                            gl::PrimitiveMode primitiveType,
177                                            const gl::ProgramState &programData,
178                                            const bool useViewScale,
179                                            const bool hasANGLEMultiviewEnabled,
180                                            const bool selectViewInVS,
181                                            const bool pointSpriteEmulation,
182                                            const std::string &preambleString) const;
183 
184     void getPixelShaderOutputKey(const gl::State &data,
185                                  const gl::ProgramState &programData,
186                                  const ProgramD3DMetadata &metadata,
187                                  std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
188 
189   private:
190     RendererD3D *const mRenderer;
191 
192     void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking,
193                                  const BuiltinInfo &builtins,
194                                  bool programUsesPointSize,
195                                  std::ostringstream &hlslStream) const;
196 
197     static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
198                                                 const sh::ShaderVariable &shaderAttrib,
199                                                 std::ostringstream &outStream);
200 };
201 
202 }  // namespace rx
203 
204 #endif  // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
205