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 static std::string GenerateVertexShaderForInputLayout(
151 RendererD3D *renderer,
152 const std::string &sourceShader,
153 const gl::InputLayout &inputLayout,
154 const std::vector<gl::ProgramInput> &shaderAttributes,
155 const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
156 size_t baseUAVRegister);
157 static std::string GeneratePixelShaderForOutputSignature(
158 RendererD3D *renderer,
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);
166 static std::string GenerateShaderForImage2DBindSignature(
167 ProgramExecutableD3D &executableD3D,
168 gl::ShaderType shaderType,
169 const SharedCompiledShaderStateD3D &shaderData,
170 const std::string &shaderHLSL,
171 std::vector<sh::ShaderVariable> &image2DUniforms,
172 const gl::ImageUnitTextureTypeMap &image2DBindLayout,
173 unsigned int baseUAVRegister);
174 static void GenerateShaderLinkHLSL(
175 RendererD3D *renderer,
176 const gl::Caps &caps,
177 const gl::ShaderMap<gl::SharedCompiledShaderState> &shaderData,
178 const gl::ShaderMap<SharedCompiledShaderStateD3D> &shaderDataD3D,
179 const ProgramD3DMetadata &programMetadata,
180 const gl::VaryingPacking &varyingPacking,
181 const BuiltinVaryingsD3D &builtinsD3D,
182 gl::ShaderMap<std::string> *shaderHLSL);
183
184 static std::string GenerateGeometryShaderPreamble(RendererD3D *renderer,
185 const gl::VaryingPacking &varyingPacking,
186 const BuiltinVaryingsD3D &builtinsD3D,
187 const bool hasMultiviewEnabled,
188 const bool selectViewInVS);
189
190 static std::string GenerateGeometryShaderHLSL(RendererD3D *renderer,
191 const gl::Caps &caps,
192 gl::PrimitiveMode primitiveType,
193 const bool useViewScale,
194 const bool hasMultiviewEnabled,
195 const bool selectViewInVS,
196 const bool pointSpriteEmulation,
197 const std::string &preambleString);
198
199 static void GetPixelShaderOutputKey(RendererD3D *renderer,
200 const gl::Caps &caps,
201 const gl::Version &clientVersion,
202 const gl::ProgramExecutable &executable,
203 const ProgramD3DMetadata &metadata,
204 std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
205
206 private:
207 static void GenerateVaryingLinkHLSL(RendererD3D *renderer,
208 const gl::VaryingPacking &varyingPacking,
209 const BuiltinInfo &builtins,
210 bool programUsesPointSize,
211 std::ostringstream &hlslStream);
212
213 static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
214 const gl::ProgramInput &shaderAttrib,
215 std::ostringstream &outStream);
216 };
217
218 } // namespace rx
219
220 #endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
221