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_DRAW_BATCH_H
25 #define PXR_IMAGING_HD_ST_DRAW_BATCH_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hd/version.h"
30 
31 #include "pxr/imaging/hdSt/resourceBinder.h"
32 #include "pxr/imaging/hd/repr.h"
33 #include "pxr/imaging/hdSt/materialNetworkShader.h"
34 
35 #include <memory>
36 #include <vector>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 class HdStDrawItem;
41 class HdStDrawItemInstance;
42 
43 using HdSt_DrawBatchSharedPtr = std::shared_ptr<class HdSt_DrawBatch>;
44 using HdSt_DrawBatchSharedPtrVector = std::vector<HdSt_DrawBatchSharedPtr>;
45 using HdSt_GeometricShaderSharedPtr =
46     std::shared_ptr<class HdSt_GeometricShader>;
47 using HdStGLSLProgramSharedPtr= std::shared_ptr<class HdStGLSLProgram>;
48 
49 using HdStRenderPassStateSharedPtr = std::shared_ptr<class HdStRenderPassState>;
50 using HdStResourceRegistrySharedPtr =
51     std::shared_ptr<class HdStResourceRegistry>;
52 
53 /// \class HdSt_DrawBatch
54 ///
55 /// A drawing batch.
56 ///
57 /// This is the finest grained element of drawing, representing potentially
58 /// aggregated drawing resources dispatched with a minimal number of draw
59 /// calls.
60 ///
61 class HdSt_DrawBatch
62 {
63 public:
64     HDST_API
65     HdSt_DrawBatch(HdStDrawItemInstance * drawItemInstance);
66 
67     HDST_API
68     virtual ~HdSt_DrawBatch();
69 
70     /// Attempts to append \a drawItemInstance to the batch, returning \a false
71     /// if the item could not be appended, e.g. if there was an aggregation
72     /// conflict.
73     HDST_API
74     bool Append(HdStDrawItemInstance * drawItemInstance);
75 
76     /// Attempt to rebuild the batch in-place, returns false if draw items are
77     /// no longer compatible.
78     HDST_API
79     bool Rebuild();
80 
81     enum class ValidationResult {
82         ValidBatch = 0,
83         RebuildBatch,
84         RebuildAllBatches
85     };
86 
87     /// Validates whether the  batch can be reused (i.e., submitted) as-is, or
88     /// if it needs to be rebuilt, or if all batches need to be rebuilt.
89     virtual ValidationResult Validate(bool deepValidation) = 0;
90 
91     /// Prepare draw commands and apply view frustum culling for this batch.
92     virtual void PrepareDraw(
93         HdStRenderPassStateSharedPtr const &renderPassState,
94         HdStResourceRegistrySharedPtr const &resourceRegistry) = 0;
95 
96     /// Executes the drawing commands for this batch.
97     virtual void ExecuteDraw(
98         HdStRenderPassStateSharedPtr const &renderPassState,
99         HdStResourceRegistrySharedPtr const & resourceRegistry) = 0;
100 
101     /// Let the batch know that one of it's draw item instances has changed
102     /// NOTE: This callback is called from multiple threads, so needs to be
103     /// threadsafe.
104     HDST_API
105     virtual void DrawItemInstanceChanged(HdStDrawItemInstance const* instance);
106 
107     /// Let the batch know whether to use tiny prim culling.
108     HDST_API
109     virtual void SetEnableTinyPrimCulling(bool tinyPrimCulling);
110 
111 protected:
112     HDST_API
113     virtual void _Init(HdStDrawItemInstance * drawItemInstance);
114 
115     /// \class _DrawingProgram
116     ///
117     /// This wraps glsl code generation and keeps track of
118     /// binding assigments for bindable resources.
119     ///
120     class _DrawingProgram {
121     public:
_DrawingProgram()122         _DrawingProgram() {}
123 
124         HDST_API
125         bool CompileShader(
126                 HdStDrawItem const *drawItem,
127                 bool indirect,
128                 HdStResourceRegistrySharedPtr const &resourceRegistry);
129 
GetGLSLProgram()130         HdStGLSLProgramSharedPtr GetGLSLProgram() const {
131             return _glslProgram;
132         }
133 
134         /// Returns the resouce binder, which is used for buffer resource
135         /// bindings at draw time.
GetBinder()136         const HdSt_ResourceBinder &GetBinder() const {
137             return _resourceBinder;
138         }
139 
Reset()140         void Reset() {
141             _glslProgram.reset();
142             _materialNetworkShader.reset();
143             _geometricShader.reset();
144             _resourceBinder = HdSt_ResourceBinder();
145             _shaders.clear();
146         }
147 
SetMaterialNetworkShader(HdSt_MaterialNetworkShaderSharedPtr const & shader)148         void SetMaterialNetworkShader(
149                 HdSt_MaterialNetworkShaderSharedPtr const &shader) {
150             _materialNetworkShader = shader;
151         }
152 
153         const HdSt_MaterialNetworkShaderSharedPtr &
GetMaterialNetworkShader()154         GetMaterialNetworkShader() const {
155             return _materialNetworkShader;
156         }
157 
SetGeometricShader(HdSt_GeometricShaderSharedPtr shader)158         void SetGeometricShader(HdSt_GeometricShaderSharedPtr shader) {
159             _geometricShader = shader;
160         }
161 
GetGeometricShader()162         const HdSt_GeometricShaderSharedPtr &GetGeometricShader() const {
163             return _geometricShader;
164         }
165 
166         /// Set shaders (lighting/renderpass). In the case of Geometric Shaders
167         /// or Surface shaders you can use the specific setters.
SetShaders(HdStShaderCodeSharedPtrVector shaders)168         void SetShaders(HdStShaderCodeSharedPtrVector shaders) {
169             _shaders = shaders;
170         }
171 
172         /// Returns array of shaders, this will not include the
173         /// material network shader passed via SetMaterialNetworkShader
174         /// (or the geometric shader).
GetShaders()175         const HdStShaderCodeSharedPtrVector &GetShaders() const {
176             return _shaders;
177         }
178 
179         /// Returns array of composed shaders, this include the shaders passed
180         /// via SetShaders and the shader passed to SetMaterialNetworkShader.
GetComposedShaders()181         HdStShaderCodeSharedPtrVector GetComposedShaders() const {
182             HdStShaderCodeSharedPtrVector shaders = _shaders;
183             if (_materialNetworkShader) {
184                 shaders.push_back(_materialNetworkShader);
185             }
186             return shaders;
187         }
188 
189     protected:
190         // overrides populate customBindings and enableInstanceDraw which
191         // will be used to determine if glVertexAttribDivisor needs to be
192         // enabled or not.
193         HDST_API
194         virtual void _GetCustomBindings(
195             HdBindingRequestVector *customBindings,
196             bool *enableInstanceDraw) const;
197 
198         HDST_API
199         virtual bool _Link(HdStGLSLProgramSharedPtr const & glslProgram);
200 
201     private:
202         HdStGLSLProgramSharedPtr _glslProgram;
203         HdSt_ResourceBinder _resourceBinder;
204         HdStShaderCodeSharedPtrVector _shaders;
205         HdSt_GeometricShaderSharedPtr _geometricShader;
206         HdSt_MaterialNetworkShaderSharedPtr _materialNetworkShader;
207     };
208 
209     HDST_API
210     _DrawingProgram & _GetDrawingProgram(
211         HdStRenderPassStateSharedPtr const &state,
212         bool indirect,
213         HdStResourceRegistrySharedPtr const &resourceRegistry);
214 
215 protected:
216     HDST_API
217     static bool _IsAggregated(HdStDrawItem const *drawItem0,
218                               HdStDrawItem const *drawItem1);
219 
220     std::vector<HdStDrawItemInstance const*> _drawItemInstances;
221 
222 private:
223     _DrawingProgram _program;
224     HdStShaderCode::ID _shaderHash;
225 };
226 
227 
228 PXR_NAMESPACE_CLOSE_SCOPE
229 
230 #endif // PXR_IMAGING_HD_ST_DRAW_BATCH_H
231