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