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_SHADER_CODE_H
25 #define PXR_IMAGING_HD_ST_SHADER_CODE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdSt/api.h"
29 #include "pxr/imaging/hdSt/resourceRegistry.h"
30 #include "pxr/imaging/hd/version.h"
31 #include "pxr/imaging/hd/enums.h"
32 
33 #include "pxr/usd/sdf/path.h"
34 
35 #include "pxr/base/tf/token.h"
36 
37 #include <memory>
38 #include <string>
39 #include <vector>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
43 
44 using HdBindingRequestVector = std::vector<class HdBindingRequest>;
45 
46 using HdStShaderCodeSharedPtr =
47     std::shared_ptr<class HdStShaderCode>;
48 using HdStShaderCodeSharedPtrVector =
49     std::vector<HdStShaderCodeSharedPtr>;
50 
51 using HdSt_MaterialParamVector =
52     std::vector<class HdSt_MaterialParam>;
53 using HdBufferSourceSharedPtr =
54     std::shared_ptr<class HdBufferSource>;
55 using HdBufferSourceSharedPtrVector =
56     std::vector<HdBufferSourceSharedPtr>;
57 using HdBufferArrayRangeSharedPtr =
58     std::shared_ptr<class HdBufferArrayRange>;
59 using HdStTextureHandleSharedPtr =
60     std::shared_ptr<class HdStTextureHandle>;
61 using HdComputationSharedPtr =
62     std::shared_ptr<class HdComputation>;
63 
64 class HdRenderPassState;
65 class HdSt_ResourceBinder;
66 class HdStResourceRegistry;
67 
68 /// \class HdStShaderCode
69 ///
70 /// A base class representing the implementation (code) of a shader,
71 /// used in conjunction with HdRenderPass.
72 ///
73 /// This interface provides a simple way for clients to affect the
74 /// composition of shading programs used for a render pass.
75 class HdStShaderCode : public std::enable_shared_from_this<HdStShaderCode>
76 {
77 public:
78     typedef size_t ID;
79 
80     HDST_API
81     HdStShaderCode();
82     HDST_API
83     virtual ~HdStShaderCode();
84 
85     /// Returns the hash value of the shader code and configuration.
86     ///
87     /// It is computed from the the GLSL code as well as the resource
88     /// signature of the shader (as determined from its parameters).
89     /// If two shaders have the same hash, the GLSL code as expanded
90     /// by codegen should also be the same.
91     ///
92     virtual ID ComputeHash() const = 0;
93 
94     /// Returns the combined hash values of multiple shaders.
95     HDST_API
96     static ID ComputeHash(HdStShaderCodeSharedPtrVector const &shaders);
97 
98     /// Returns the hash value of the paths of the texture prims
99     /// consumed by this shader.
100     ///
101     /// Unless textures are bindless, shaders using different textures
102     /// cannot be used in the same draw batch. Since textures can be
103     /// animated, it can happen that two texture prims use the same
104     /// texture at some time but different textures at other times. To
105     /// avoid re-computing the draw batches over time, we use the this
106     /// hash when grouping the draw batches.
107     ///
108     virtual ID ComputeTextureSourceHash() const;
109 
110     /// Returns the shader source provided by this shader
111     /// for \a shaderStageKey
112     virtual std::string GetSource(TfToken const &shaderStageKey) const = 0;
113 
114     // XXX: Should be pure-virtual
115     /// Returns the shader parameters for this shader.
116     HDST_API
117     virtual HdSt_MaterialParamVector const& GetParams() const;
118 
119     /// Returns whether primvar filtering is enabled for this shader.
120     HDST_API
121     virtual bool IsEnabledPrimvarFiltering() const;
122 
123     /// Returns the names of primvar that are used by this shader.
124     HDST_API
125     virtual TfTokenVector const& GetPrimvarNames() const;
126 
127     /// @}
128 
129     ///
130     /// \name Texture system
131     /// @{
132 
133     /// Information necessary to bind textures and create accessor
134     /// for the texture.
135     ///
136     struct NamedTextureHandle {
137         /// Name by which the texture will be accessed, i.e., the name
138         /// of the accesor for thexture will be HdGet_name(...).
139         ///
140         TfToken name;
141         /// Equal to handle->GetTextureObject()->GetTextureType().
142         /// Saved here for convenience (note that name and type
143         /// completely determine the creation of the texture accesor
144         /// HdGet_name(...)).
145         ///
146         HdTextureType type;
147         /// The texture.
148         HdStTextureHandleSharedPtr handle;
149 
150         /// A hash unique to the corresponding asset; used to
151         /// split draw batches when not using bindless textures.
152         size_t hash;
153     };
154     using NamedTextureHandleVector = std::vector<NamedTextureHandle>;
155 
156     /// Textures that need to be bound for this shader.
157     ///
158     HDST_API
159     virtual NamedTextureHandleVector const & GetNamedTextureHandles() const;
160 
161     /// @}
162 
163     // XXX: Should be pure-virtual
164     /// Returns a buffer which stores parameter fallback values and texture
165     /// handles.
166     HDST_API
167     virtual HdBufferArrayRangeSharedPtr const& GetShaderData() const;
168 
169     /// Binds shader-specific resources to \a program
170     /// XXX: this interface is meant to be used for bridging
171     /// the GlfSimpleLightingContext mechanism, and not for generic use-cases.
172     virtual void BindResources(int program,
173                                HdSt_ResourceBinder const &binder,
174                                HdRenderPassState const &state) = 0;
175 
176     /// Unbinds shader-specific resources.
177     virtual void UnbindResources(int program,
178                                  HdSt_ResourceBinder const &binder,
179                                  HdRenderPassState const &state) = 0;
180 
181     /// Add custom bindings (used by codegen)
182     virtual void AddBindings(HdBindingRequestVector* customBindings) = 0;
183 
184     /// Material tags can be set in the meta-data of a glslfx file to control
185     /// what rprim collection that prims using this shader should go into.
186     /// E.g. We can use it to split opaque and translucent prims into different
187     /// collections. When no material tags are specified in the shader, a empty
188     /// token is returned.
189     HDST_API
190     virtual TfToken GetMaterialTag() const;
191 
192     /// \class ResourceContext
193     ///
194     /// The context available in implementations of
195     /// AddResourcesFromTextures.
196     class ResourceContext {
197     public:
198         HDST_API
199         void AddSource(HdBufferArrayRangeSharedPtr const &range,
200                        HdBufferSourceSharedPtr const &source);
201 
202         HDST_API
203         void AddSources(HdBufferArrayRangeSharedPtr const &range,
204                         HdBufferSourceSharedPtrVector &&sources);
205 
206         HDST_API
207         void AddComputation(HdBufferArrayRangeSharedPtr const &range,
208                             HdComputationSharedPtr const &computation,
209                             HdStComputeQueue const queue);
210 
211     private:
212         friend class HdStResourceRegistry;
213         ResourceContext(HdStResourceRegistry *);
214         HdStResourceRegistry *_registry;
215     };
216 
217     /// This function is called after textures have been allocated and
218     /// loaded to add buffer sources and computations to the resource
219     /// registry that require texture meta data not available until
220     /// the texture is allocated or loaded. For example, the OpenGl
221     /// texture sampler handle (in the bindless case) is not available
222     /// until after the texture commit phase.
223     ///
224     HDST_API
225     virtual void AddResourcesFromTextures(ResourceContext &ctx) const;
226 
227 private:
228 
229     // No copying
230     HdStShaderCode(const HdStShaderCode &)                      = delete;
231     HdStShaderCode &operator =(const HdStShaderCode &)          = delete;
232 };
233 
234 
235 PXR_NAMESPACE_CLOSE_SCOPE
236 
237 #endif //HDST_SHADER_H
238