1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "RenderAPI/BsGpuParam.h"
7#include "CoreThread/BsCoreObject.h"
8#include "Resources/BsIResourceListener.h"
9#include "Math/BsMatrixNxM.h"
10
11namespace bs
12{
13 /** @addtogroup Implementation
14 * @{
15 */
16
17 /** Helper structure whose specializations convert an engine data type into a GPU program data parameter type. */
18 template<class T> struct TGpuDataParamInfo { enum { TypeId = GPDT_STRUCT };};
19 template<> struct TGpuDataParamInfo < float > { enum { TypeId = GPDT_FLOAT1 }; };
20 template<> struct TGpuDataParamInfo < Vector2 > { enum { TypeId = GPDT_FLOAT2 }; };
21 template<> struct TGpuDataParamInfo < Vector3 > { enum { TypeId = GPDT_FLOAT3 }; };
22 template<> struct TGpuDataParamInfo < Vector4 > { enum { TypeId = GPDT_FLOAT4 }; };
23 template<> struct TGpuDataParamInfo < int > { enum { TypeId = GPDT_INT1 }; };
24 template<> struct TGpuDataParamInfo < Vector2I > { enum { TypeId = GPDT_INT2 }; };
25 template<> struct TGpuDataParamInfo < Vector3I > { enum { TypeId = GPDT_INT3 }; };
26 template<> struct TGpuDataParamInfo < Vector4I > { enum { TypeId = GPDT_INT4 }; };
27 template<> struct TGpuDataParamInfo < Matrix2 > { enum { TypeId = GPDT_MATRIX_2X2 }; };
28 template<> struct TGpuDataParamInfo < Matrix2x3 > { enum { TypeId = GPDT_MATRIX_2X3 }; };
29 template<> struct TGpuDataParamInfo < Matrix2x4 > { enum { TypeId = GPDT_MATRIX_2X4 }; };
30 template<> struct TGpuDataParamInfo < Matrix3 > { enum { TypeId = GPDT_MATRIX_3X3 }; };
31 template<> struct TGpuDataParamInfo < Matrix3x2 > { enum { TypeId = GPDT_MATRIX_3X2 }; };
32 template<> struct TGpuDataParamInfo < Matrix3x4 > { enum { TypeId = GPDT_MATRIX_3X4 }; };
33 template<> struct TGpuDataParamInfo < Matrix4 > { enum { TypeId = GPDT_MATRIX_4X4 }; };
34 template<> struct TGpuDataParamInfo < Matrix4x2 > { enum { TypeId = GPDT_MATRIX_4X2 }; };
35 template<> struct TGpuDataParamInfo < Matrix4x3 > { enum { TypeId = GPDT_MATRIX_4X3 }; };
36 template<> struct TGpuDataParamInfo < Color > { enum { TypeId = GPDT_COLOR }; };
37
38 class GpuPipelineParamInfoBase;
39
40 /** Contains functionality common for both sim and core thread version of GpuParams. */
41 class BS_CORE_EXPORT GpuParamsBase
42 {
43 public:
44 virtual ~GpuParamsBase() = default;
45
46 // Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
47 // all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
48 GpuParamsBase(const GpuParamsBase& other) = delete;
49 GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
50
51 /** Returns a description of all stored parameters. */
52 SPtr<GpuParamDesc> getParamDesc(GpuProgramType type) const;
53
54 /** Gets the object that contains the processed information about all parameters. */
55 SPtr<GpuPipelineParamInfoBase> getParamInfo() const { return mParamInfo; }
56
57 /**
58 * Returns the size of a data parameter with the specified name, in bytes. Returns 0 if such parameter doesn't exist.
59 */
60 UINT32 getDataParamSize(GpuProgramType type, const String& name) const;
61
62 /** Checks if parameter with the specified name exists. */
63 bool hasParam(GpuProgramType type, const String& name) const;
64
65 /** Checks if texture parameter with the specified name exists. */
66 bool hasTexture(GpuProgramType type, const String& name) const;
67
68 /** Checks if load/store texture parameter with the specified name exists. */
69 bool hasLoadStoreTexture(GpuProgramType type, const String& name) const;
70
71 /** Checks if buffer parameter with the specified name exists. */
72 bool hasBuffer(GpuProgramType type, const String& name) const;
73
74 /** Checks if sampler state parameter with the specified name exists. */
75 bool hasSamplerState(GpuProgramType type, const String& name) const;
76
77 /** Checks if a parameter block with the specified name exists. */
78 bool hasParamBlock(GpuProgramType type, const String& name) const;
79
80 /** Gets a descriptor for a parameter block buffer with the specified name. */
81 GpuParamBlockDesc* getParamBlockDesc(GpuProgramType type, const String& name) const;
82
83 /** Marks the sim thread object as dirty, causing it to sync its contents with its core thread counterpart. */
84 virtual void _markCoreDirty() { }
85
86 /** @copydoc IResourceListener::markListenerResourcesDirty */
87 virtual void _markResourcesDirty() { }
88
89 protected:
90 GpuParamsBase(const SPtr<GpuPipelineParamInfoBase>& paramInfo);
91
92 /** Gets a descriptor for a data parameter with the specified name. */
93 GpuParamDataDesc* getParamDesc(GpuProgramType type, const String& name) const;
94
95 SPtr<GpuPipelineParamInfoBase> mParamInfo;
96 };
97
98 /** Templated version of GpuParams that contains functionality for both sim and core thread versions of stored data. */
99 template <bool Core>
100 class BS_CORE_EXPORT TGpuParams : public GpuParamsBase
101 {
102 public:
103 using GpuParamsType = CoreVariantType<GpuParams, Core>;
104 using TextureType = CoreVariantHandleType<Texture, Core>;
105 using BufferType = SPtr<CoreVariantType<GpuBuffer, Core>>;
106 using SamplerType = SPtr<CoreVariantType<SamplerState, Core>>;
107 using ParamsBufferType = SPtr<CoreVariantType<GpuParamBlockBuffer, Core>>;
108
109 virtual ~TGpuParams();
110
111 /**
112 * Returns a handle for the parameter with the specified name. Handle may then be stored and used for quickly
113 * setting or retrieving values to/from that parameter.
114 *
115 * Throws exception if parameter with that name and type doesn't exist.
116 *
117 * Parameter handles will be invalidated when their parent GpuParams object changes.
118 */
119 template<class T> void getParam(GpuProgramType type, const String& name, TGpuDataParam<T, Core>& output) const;
120
121 /** @copydoc getParam */
122 void getStructParam(GpuProgramType type, const String& name, TGpuParamStruct<Core>& output) const;
123
124 /** @copydoc getParam */
125 void getTextureParam(GpuProgramType type, const String& name, TGpuParamTexture<Core>& output) const;
126
127 /** @copydoc getParam */
128 void getLoadStoreTextureParam(GpuProgramType type, const String& name, TGpuParamLoadStoreTexture<Core>& output) const;
129
130 /** @copydoc getParam */
131 void getBufferParam(GpuProgramType type, const String& name, TGpuParamBuffer<Core>& output) const;
132
133 /** @copydoc getParam */
134 void getSamplerStateParam(GpuProgramType type, const String& name, TGpuParamSampState<Core>& output) const;
135
136 /** Gets a parameter block buffer from the specified set/slot combination. */
137 ParamsBufferType getParamBlockBuffer(UINT32 set, UINT32 slot) const;
138
139 /** Gets a texture bound to the specified set/slot combination. */
140 TextureType getTexture(UINT32 set, UINT32 slot) const;
141
142 /** Gets a load/store texture bound to the specified set/slot combination. */
143 TextureType getLoadStoreTexture(UINT32 set, UINT32 slot) const;
144
145 /** Gets a buffer bound to the specified set/slot combination. */
146 BufferType getBuffer(UINT32 set, UINT32 slot) const;
147
148 /** Gets a sampler state bound to the specified set/slot combination. */
149 SamplerType getSamplerState(UINT32 set, UINT32 slot) const;
150
151 /** Gets information that determines which texture surfaces to bind as a sampled texture parameter. */
152 const TextureSurface& getTextureSurface(UINT32 set, UINT32 slot) const;
153
154 /** Gets information that determines which texture surfaces to bind as a load/store parameter. */
155 const TextureSurface& getLoadStoreSurface(UINT32 set, UINT32 slot) const;
156
157 /**
158 * Assigns the provided parameter block buffer to a buffer with the specified name, for the specified GPU program
159 * stage. Any following parameter reads or writes that are referencing that buffer will use the new buffer.
160 *
161 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
162 */
163 void setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer);
164
165 /**
166 * Assigns the provided parameter block buffer to a buffer with the specified name, for any stages that reference
167 * the buffer. Any following parameter reads or writes that are referencing that buffer will use the new buffer.
168 *
169 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
170 * It is up to the caller that all stages using this buffer name refer to the same buffer type.
171 */
172 void setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer);
173
174 /**
175 * Sets the parameter buffer with the specified set/slot combination.Any following parameter reads or writes that are
176 * referencing that buffer will use the new buffer. Set/slot information for a specific buffer can be extracted
177 * from GPUProgram's GpuParamDesc structure.
178 *
179 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
180 */
181 virtual void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
182
183 /** Sets a texture at the specified set/slot combination. */
184 virtual void setTexture(UINT32 set, UINT32 slot, const TextureType& texture,
185 const TextureSurface& surface = TextureSurface::COMPLETE);
186
187 /** Sets a load/store texture at the specified set/slot combination. */
188 virtual void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
189
190 /** Sets a buffer at the specified set/slot combination. */
191 virtual void setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer);
192
193 /** Sets a sampler state at the specified set/slot combination. */
194 virtual void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
195
196 /** Assigns a data value to the parameter with the specified name. */
197 template<class T> void setParam(GpuProgramType type, const String& name, const T& value)
198 { TGpuDataParam<T, Core> param; getParam(type, name, param); param.set(value); }
199
200 /** Assigns a texture to the parameter with the specified name. */
201 void setTexture(GpuProgramType type, const String& name, const TextureType& texture,
202 const TextureSurface& surface = TextureSurface::COMPLETE)
203 { TGpuParamTexture<Core> param; getTextureParam(type, name, param); param.set(texture, surface); }
204
205 /** Assigns a load/store texture to the parameter with the specified name. */
206 void setLoadStoreTexture(GpuProgramType type, const String& name, const TextureType& texture, const TextureSurface& surface)
207 { TGpuParamLoadStoreTexture<Core> param; getLoadStoreTextureParam(type, name, param); param.set(texture, surface); }
208
209 /** Assigns a buffer to the parameter with the specified name. */
210 void setBuffer(GpuProgramType type, const String& name, const BufferType& buffer)
211 { TGpuParamBuffer<Core> param; getBufferParam(type, name, param); param.set(buffer); }
212
213 /** Assigns a sampler state to the parameter with the specified name. */
214 void setSamplerState(GpuProgramType type, const String& name, const SamplerType& sampler)
215 { TGpuParamSampState<Core> param; getSamplerStateParam(type, name, param); param.set(sampler); }
216
217 protected:
218 TGpuParams(const SPtr<GpuPipelineParamInfoBase>& paramInfo);
219
220 /** @copydoc CoreObject::getThisPtr */
221 virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
222
223 /** Data for a single bound texture. */
224 struct TextureData
225 {
226 TextureType texture;
227 TextureSurface surface;
228 };
229
230 ParamsBufferType* mParamBlockBuffers = nullptr;
231 TextureData* mSampledTextureData = nullptr;
232 TextureData* mLoadStoreTextureData = nullptr;
233 BufferType* mBuffers = nullptr;
234 SamplerType* mSamplerStates = nullptr;
235 };
236
237 /** @} */
238
239 /** @addtogroup RenderAPI
240 * @{
241 */
242
243 /**
244 * Contains descriptions for all parameters in a set of programs (ones for each stage) and allows you to write and read
245 * those parameters. All parameter values are stored internally on the CPU, and are only submitted to the GPU once the
246 * parameters are bound to the pipeline.
247 *
248 * @note Sim thread only.
249 */
250 class BS_CORE_EXPORT GpuParams : public CoreObject, public TGpuParams<false>, public IResourceListener
251 {
252 public:
253 ~GpuParams() { }
254
255 /** Retrieves a core implementation of a mesh usable only from the core thread. */
256 SPtr<ct::GpuParams> getCore() const;
257
258 /**
259 * Creates new GpuParams object that can serve for changing the GPU program parameters on the specified pipeline.
260 *
261 * @param[in] pipelineState Pipeline state for which this object can set parameters for.
262 * @return New GpuParams object.
263 */
264 static SPtr<GpuParams> create(const SPtr<GraphicsPipelineState>& pipelineState);
265
266 /** @copydoc GpuParams::create(const SPtr<GraphicsPipelineState>&) */
267 static SPtr<GpuParams> create(const SPtr<ComputePipelineState>& pipelineState);
268
269 /**
270 * Creates a new set of GPU parameters using an object describing the parameters for a pipeline.
271 *
272 * @param[in] paramInfo Description of GPU parameters for a specific GPU pipeline state.
273 */
274 static SPtr<GpuParams> create(const SPtr<GpuPipelineParamInfo>& paramInfo);
275
276 /** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
277 const static GpuDataParamInfos PARAM_SIZES;
278
279 /** @name Internal
280 * @{
281 */
282
283 /** @copydoc GpuParamsBase::_markCoreDirty */
284 void _markCoreDirty() override;
285
286 /** @copydoc IResourceListener::markListenerResourcesDirty */
287 void _markResourcesDirty() override;
288
289 /** @} */
290 protected:
291 friend class HardwareBufferManager;
292
293 GpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo);
294
295 /** @copydoc CoreObject::getThisPtr */
296 SPtr<GpuParams> _getThisPtr() const override;
297
298 /** @copydoc CoreObject::createCore */
299 SPtr<ct::CoreObject> createCore() const override;
300
301 /** @copydoc CoreObject::syncToCore */
302 CoreSyncData syncToCore(FrameAlloc* allocator) override;
303
304 /** @copydoc IResourceListener::getListenerResources */
305 void getListenerResources(Vector<HResource>& resources) override;
306
307 /** @copydoc IResourceListener::notifyResourceLoaded */
308 void notifyResourceLoaded(const HResource& resource) override { markCoreDirty(); }
309
310 /** @copydoc IResourceListener::notifyResourceChanged */
311 void notifyResourceChanged(const HResource& resource) override { markCoreDirty(); }
312 };
313
314 /** @} */
315
316 namespace ct
317 {
318 /** @addtogroup RenderAPI-Internal
319 * @{
320 */
321
322 /**
323 * Core thread version of bs::GpuParams.
324 *
325 * @note Core thread only.
326 */
327 class BS_CORE_EXPORT GpuParams : public CoreObject, public TGpuParams<true>
328 {
329 public:
330 virtual ~GpuParams() { }
331
332 /**
333 * @copydoc bs::GpuParams::create(const SPtr<GraphicsPipelineState>&)
334 * @param[in] deviceMask Mask that determines on which GPU devices should the buffer be created on.
335 */
336 static SPtr<GpuParams> create(const SPtr<GraphicsPipelineState>& pipelineState,
337 GpuDeviceFlags deviceMask = GDF_DEFAULT);
338
339 /**
340 * @copydoc bs::GpuParams::create(const SPtr<ComputePipelineState>&)
341 * @param[in] deviceMask Mask that determines on which GPU devices should the buffer be created on.
342 */
343 static SPtr<GpuParams> create(const SPtr<ComputePipelineState>& pipelineState,
344 GpuDeviceFlags deviceMask = GDF_DEFAULT);
345
346 /**
347 * @copydoc bs::GpuParams::create(const SPtr<GpuPipelineParamInfo>&)
348 * @param[in] deviceMask Mask that determines on which GPU devices should the buffer be created on.
349 */
350 static SPtr<GpuParams> create(const SPtr<GpuPipelineParamInfo>& paramInfo,
351 GpuDeviceFlags deviceMask = GDF_DEFAULT);
352
353 protected:
354 friend class bs::GpuParams;
355 friend class HardwareBufferManager;
356
357 GpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo, GpuDeviceFlags deviceMask);
358
359 /** @copydoc CoreObject::getThisPtr */
360 SPtr<GpuParams> _getThisPtr() const override;
361
362 /** @copydoc CoreObject::syncToCore */
363 void syncToCore(const CoreSyncData& data) override;
364 };
365
366 /** @} */
367 }
368}