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