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 enableSystem(const std::string &systemValueSemantic, unsigned int sizeVal);
93 void enable(const std::string &semanticVal, unsigned int indexVal);
94
95 bool enabled;
96 std::string semantic;
97 unsigned int indexOrSize;
98 bool systemValue;
99 };
100
101 struct BuiltinInfo
102 {
103 BuiltinInfo();
104 ~BuiltinInfo();
105
106 BuiltinVarying dxPosition;
107 BuiltinVarying glPosition;
108 BuiltinVarying glClipDistance;
109 BuiltinVarying glCullDistance;
110 BuiltinVarying glFragCoord;
111 BuiltinVarying glPointCoord;
112 BuiltinVarying glPointSize;
113 BuiltinVarying glViewIDOVR;
114 BuiltinVarying glViewportIndex;
115 BuiltinVarying glLayer;
116 };
117
GetVaryingSemantic(int majorShaderModel,bool programUsesPointSize)118 inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize)
119 {
120 // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
121 // In D3D11 we manually compute gl_PointCoord in the GS.
122 return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD");
123 }
124
125 class BuiltinVaryingsD3D
126 {
127 public:
128 BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
129 ~BuiltinVaryingsD3D();
130
usesPointSize()131 bool usesPointSize() const { return mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled; }
132
133 const BuiltinInfo &operator[](gl::ShaderType shaderType) const
134 {
135 return mBuiltinInfo[shaderType];
136 }
137 BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
138
139 private:
140 void updateBuiltins(gl::ShaderType shaderType,
141 const ProgramD3DMetadata &metadata,
142 const gl::VaryingPacking &packing);
143
144 gl::ShaderMap<BuiltinInfo> mBuiltinInfo;
145 };
146
147 class DynamicHLSL : angle::NonCopyable
148 {
149 public:
150 explicit DynamicHLSL(RendererD3D *const renderer);
151
152 std::string generateVertexShaderForInputLayout(
153 const std::string &sourceShader,
154 const gl::InputLayout &inputLayout,
155 const std::vector<sh::ShaderVariable> &shaderAttributes,
156 const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
157 size_t baseUAVRegister) const;
158 std::string generatePixelShaderForOutputSignature(
159 const std::string &sourceShader,
160 const std::vector<PixelShaderOutputVariable> &outputVariables,
161 FragDepthUsage fragDepthUsage,
162 bool usesSampleMask,
163 const std::vector<GLenum> &outputLayout,
164 const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
165 size_t baseUAVRegister) const;
166 std::string generateShaderForImage2DBindSignature(
167 ProgramD3D &programD3D,
168 const gl::ProgramState &programData,
169 gl::ShaderType shaderType,
170 const std::string &shaderHLSL,
171 std::vector<sh::ShaderVariable> &image2DUniforms,
172 const gl::ImageUnitTextureTypeMap &image2DBindLayout,
173 unsigned int baseUAVRegister) const;
174 void generateShaderLinkHLSL(const gl::Context *context,
175 const gl::Caps &caps,
176 const gl::ProgramState &programData,
177 const ProgramD3DMetadata &programMetadata,
178 const gl::VaryingPacking &varyingPacking,
179 const BuiltinVaryingsD3D &builtinsD3D,
180 gl::ShaderMap<std::string> *shaderHLSL) const;
181
182 std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
183 const BuiltinVaryingsD3D &builtinsD3D,
184 const bool hasMultiviewEnabled,
185 const bool selectViewInVS) const;
186
187 std::string generateGeometryShaderHLSL(const gl::Caps &caps,
188 gl::PrimitiveMode primitiveType,
189 const gl::ProgramState &programData,
190 const bool useViewScale,
191 const bool hasMultiviewEnabled,
192 const bool selectViewInVS,
193 const bool pointSpriteEmulation,
194 const std::string &preambleString) const;
195
196 void getPixelShaderOutputKey(const gl::State &data,
197 const gl::ProgramState &programData,
198 const ProgramD3DMetadata &metadata,
199 std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
200
201 private:
202 RendererD3D *const mRenderer;
203
204 void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking,
205 const BuiltinInfo &builtins,
206 bool programUsesPointSize,
207 std::ostringstream &hlslStream) const;
208
209 static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
210 const sh::ShaderVariable &shaderAttrib,
211 std::ostringstream &outStream);
212 };
213
214 } // namespace rx
215
216 #endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
217