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