1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_ST_GEOMETRIC_SHADER_H
25 #define PXR_IMAGING_HD_ST_GEOMETRIC_SHADER_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/imaging/hd/enums.h"
31 #include "pxr/imaging/hdSt/shaderCode.h"
32 #include "pxr/imaging/hdSt/resourceRegistry.h"
33 #include "pxr/usd/sdf/path.h"
34 #include "pxr/imaging/garch/glApi.h"
35 #include "pxr/imaging/hio/glslfx.h"
36 
37 #include <memory>
38 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
41 using HdSt_GeometricShaderSharedPtr =
42     std::shared_ptr<class HdSt_GeometricShader>;
43 struct HdSt_ShaderKey;
44 
45 /// \class HdSt_GeometricShader
46 ///
47 /// Storm breaks down the concept of a shader program into distinct
48 /// conceptual pieces that are then stitched together during code generation.
49 /// The pieces are:
50 /// (i)   geometric shader
51 /// (ii)  material shader
52 /// (iii) lighting shader
53 /// (iv)  render pass shader
54 ///
55 /// The geometric shader contains the entry points for the relevant shader
56 /// stages and uses geometry opinions (such as cullstyle, double sided, etc)
57 /// to generate shader code variants via mixins.
58 ///
59 class HdSt_GeometricShader : public HdStShaderCode {
60 public:
61     /// Used in HdSt_CodeGen to generate the appropriate shader source
62     enum class PrimitiveType {
63         PRIM_POINTS,
64         PRIM_BASIS_CURVES_LINES,     // when linear (or) non-refined cubic
65         PRIM_BASIS_CURVES_LINEAR_PATCHES,  // refined linear curves
66         PRIM_BASIS_CURVES_CUBIC_PATCHES,   // refined cubic curves
67         PRIM_MESH_COARSE_TRIANGLES,
68         PRIM_MESH_REFINED_TRIANGLES, // e.g: loop subdiv
69         PRIM_MESH_COARSE_QUADS,      // e.g: quadrangulation for ptex
70         PRIM_MESH_REFINED_QUADS,     // e.g: catmark/bilinear subdiv
71         PRIM_MESH_BSPLINE,           // e.g. catmark limit surface patches
72         PRIM_MESH_BOXSPLINETRIANGLE, // e.g. loop limit surface patches
73         PRIM_VOLUME                  // Simply draws triangles of bounding
74                                      // box of a volume.
75     };
76 
77     /// static query functions for PrimitiveType
IsPrimTypePoints(PrimitiveType primType)78     static inline bool IsPrimTypePoints (PrimitiveType primType) {
79         return primType == PrimitiveType::PRIM_POINTS;
80     }
81 
IsPrimTypeBasisCurves(PrimitiveType primType)82     static inline bool IsPrimTypeBasisCurves(PrimitiveType primType) {
83         return (primType == PrimitiveType::PRIM_BASIS_CURVES_LINES ||
84                 primType == PrimitiveType::PRIM_BASIS_CURVES_CUBIC_PATCHES ||
85                 primType == PrimitiveType::PRIM_BASIS_CURVES_LINEAR_PATCHES);
86     }
87 
IsPrimTypeMesh(PrimitiveType primType)88     static inline bool IsPrimTypeMesh(PrimitiveType primType) {
89         return (primType == PrimitiveType::PRIM_MESH_COARSE_TRIANGLES  ||
90                 primType == PrimitiveType::PRIM_MESH_REFINED_TRIANGLES ||
91                 primType == PrimitiveType::PRIM_MESH_COARSE_QUADS      ||
92                 primType == PrimitiveType::PRIM_MESH_REFINED_QUADS     ||
93                 primType == PrimitiveType::PRIM_MESH_BSPLINE   ||
94                 primType == PrimitiveType::PRIM_MESH_BOXSPLINETRIANGLE);
95     }
96 
IsPrimTypeTriangles(PrimitiveType primType)97     static inline bool IsPrimTypeTriangles(PrimitiveType primType) {
98         return (primType == PrimitiveType::PRIM_MESH_COARSE_TRIANGLES ||
99                 primType == PrimitiveType::PRIM_MESH_REFINED_TRIANGLES ||
100                 primType == PrimitiveType::PRIM_VOLUME);
101     }
102 
IsPrimTypeQuads(PrimitiveType primType)103     static inline bool IsPrimTypeQuads(PrimitiveType primType) {
104         return (primType == PrimitiveType::PRIM_MESH_COARSE_QUADS ||
105                 primType == PrimitiveType::PRIM_MESH_REFINED_QUADS);
106     }
107 
IsPrimTypeRefinedMesh(PrimitiveType primType)108     static inline bool IsPrimTypeRefinedMesh(PrimitiveType primType) {
109         return (primType == PrimitiveType::PRIM_MESH_REFINED_TRIANGLES ||
110                 primType == PrimitiveType::PRIM_MESH_REFINED_QUADS ||
111                 primType == PrimitiveType::PRIM_MESH_BSPLINE ||
112                 primType == PrimitiveType::PRIM_MESH_BOXSPLINETRIANGLE);
113     }
114 
IsPrimTypePatches(PrimitiveType primType)115     static inline bool IsPrimTypePatches(PrimitiveType primType) {
116         return primType == PrimitiveType::PRIM_MESH_BSPLINE ||
117                primType == PrimitiveType::PRIM_MESH_BOXSPLINETRIANGLE ||
118                primType == PrimitiveType::PRIM_BASIS_CURVES_CUBIC_PATCHES ||
119                primType == PrimitiveType::PRIM_BASIS_CURVES_LINEAR_PATCHES;
120     }
121 
122     // Face-varying patch type
123     enum class FvarPatchType {
124         PATCH_COARSE_TRIANGLES,
125         PATCH_REFINED_TRIANGLES,
126         PATCH_COARSE_QUADS,
127         PATCH_REFINED_QUADS,
128         PATCH_BSPLINE,
129         PATCH_BOXSPLINETRIANGLE,
130         PATCH_NONE
131     };
132 
133     HDST_API
134     HdSt_GeometricShader(std::string const &glslfxString,
135                        PrimitiveType primType,
136                        HdCullStyle cullStyle,
137                        bool useHardwareFaceCulling,
138                        bool hasMirroredTransform,
139                        bool doubleSided,
140                        HdPolygonMode polygonMode,
141                        bool cullingPass,
142                        FvarPatchType fvarPatchType,
143                        SdfPath const &debugId = SdfPath(),
144                        float lineWidth = 0);
145 
146     HDST_API
147     ~HdSt_GeometricShader() override;
148 
149     // HdShader overrides
150     HDST_API
151     ID ComputeHash() const override;
152     HDST_API
153     std::string GetSource(TfToken const &shaderStageKey) const override;
154     HDST_API
155     void BindResources(int program,
156                                HdSt_ResourceBinder const &binder,
157                                HdRenderPassState const &state) override;
158 
159     HDST_API
160     void UnbindResources(int program,
161                                  HdSt_ResourceBinder const &binder,
162                                  HdRenderPassState const &state) override;
163     HDST_API
164     void AddBindings(HdBindingRequestVector *customBindings) override;
165 
166     /// Returns true if this geometric shader is used for GPU frustum culling.
IsFrustumCullingPass()167     bool IsFrustumCullingPass() const {
168         return _frustumCullingPass;
169     }
170 
GetPrimitiveType()171     PrimitiveType GetPrimitiveType() const {
172         return _primType;
173     }
174 
175     /// member query functions for PrimitiveType
IsPrimTypePoints()176      inline bool IsPrimTypePoints() const {
177         return IsPrimTypePoints(_primType);
178     }
179 
IsPrimTypeBasisCurves()180     inline bool IsPrimTypeBasisCurves() const {
181         return IsPrimTypeBasisCurves(_primType);
182     }
183 
IsPrimTypeMesh()184     inline bool IsPrimTypeMesh() const {
185         return IsPrimTypeMesh(_primType);
186     }
187 
IsPrimTypeTriangles()188     inline bool IsPrimTypeTriangles() const {
189         return IsPrimTypeTriangles(_primType);
190     }
191 
IsPrimTypeQuads()192     inline bool IsPrimTypeQuads() const {
193         return IsPrimTypeQuads(_primType);
194     }
195 
IsPrimTypePatches()196     inline bool IsPrimTypePatches() const {
197         return IsPrimTypePatches(_primType);
198     }
199 
GetFvarPatchType()200     FvarPatchType GetFvarPatchType() const {
201         return _fvarPatchType;
202     }
203 
204     /// Return the GL primitive type of the draw item based on _primType
205     HDST_API
206     GLenum GetPrimitiveMode() const;
207 
208     // Returns the primitive index size based on the primitive mode
209     // 3 for triangles, 4 for quads, 16 for regular b-spline patches etc.
210     HDST_API
211     int GetPrimitiveIndexSize() const;
212 
213     // Returns the number of vertices output for patch evaluation,
214     // i.e. the number of tessellation control shader invocations.
215     HDST_API
216     int GetNumPatchEvalVerts() const;
217 
218     // Returns the primitive index size for the geometry shader shade
219     // 1 for points, 2 for lines, 3 for triangles, 4 for lines_adjacency
220     HDST_API
221     int GetNumPrimitiveVertsForGeometryShader() const;
222 
223     // Factory for convenience.
224     static HdSt_GeometricShaderSharedPtr Create(
225             HdSt_ShaderKey const &shaderKey,
226             HdStResourceRegistrySharedPtr const &resourceRegistry);
227 
228 private:
229     PrimitiveType _primType;
230     HdCullStyle _cullStyle;
231     bool _useHardwareFaceCulling;
232     bool _hasMirroredTransform;
233     bool _doubleSided;
234     HdPolygonMode _polygonMode;
235     float _lineWidth;
236 
237     std::unique_ptr<HioGlslfx> _glslfx;
238     bool _frustumCullingPass;
239     FvarPatchType _fvarPatchType;
240     ID _hash;
241 
242     // No copying
243     HdSt_GeometricShader(const HdSt_GeometricShader &) = delete;
244     HdSt_GeometricShader &operator =(const HdSt_GeometricShader &) = delete;
245 };
246 
247 
248 PXR_NAMESPACE_CLOSE_SCOPE
249 
250 #endif  // PXR_IMAGING_HD_ST_GEOMETRIC_SHADER_H
251