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 "Reflection/BsIReflectable.h" |
7 | #include "Allocators/BsStaticAlloc.h" |
8 | #include "Math/BsVector2.h" |
9 | #include "RenderAPI/BsGpuParams.h" |
10 | #include "Allocators/BsPoolAlloc.h" |
11 | |
12 | namespace bs |
13 | { |
14 | template<class T> |
15 | class TAnimationCurve; |
16 | class ColorGradient; |
17 | |
18 | /** @addtogroup Material-Internal |
19 | * @{ |
20 | */ |
21 | |
22 | struct SHADER_DATA_PARAM_DESC; |
23 | struct SHADER_OBJECT_PARAM_DESC; |
24 | struct SHADER_PARAM_ATTRIBUTE; |
25 | |
26 | /** Types of textures that can be assigned to a material texture parameter. */ |
27 | enum class MateralParamTextureType |
28 | { |
29 | /** Normal texture (static image, entire UV range). */ |
30 | Normal, |
31 | /** Texture that is writeable by the material using unordered writes. */ |
32 | LoadStore, |
33 | /** Sprite texture (either a subset of a larger texture, or an animated texture). */ |
34 | Sprite |
35 | }; |
36 | |
37 | /** Common functionality for MaterialParams and ct::MaterialParams. */ |
38 | class BS_CORE_EXPORT MaterialParamsBase |
39 | { |
40 | public: |
41 | /** Type of material parameter. */ |
42 | enum class ParamType |
43 | { |
44 | Data, Texture, Sampler, Buffer |
45 | }; |
46 | |
47 | /** Result codes for getParam method. */ |
48 | enum class GetParamResult |
49 | { |
50 | Success, |
51 | NotFound, |
52 | InvalidType, |
53 | IndexOutOfBounds |
54 | }; |
55 | |
56 | /** Meta-data about a parameter. */ |
57 | struct ParamData |
58 | { |
59 | ParamType type; |
60 | GpuParamDataType dataType; |
61 | UINT32 index; |
62 | UINT32 arraySize; |
63 | mutable UINT64 version; |
64 | }; |
65 | |
66 | /** Information about a single data parameter in a material. */ |
67 | struct DataParamInfo |
68 | { |
69 | UINT32 offset; |
70 | |
71 | TAnimationCurve<float>* floatCurve; |
72 | ColorGradient* colorGradient; |
73 | UINT32 spriteTextureIdx; |
74 | }; |
75 | |
76 | /** |
77 | * Creates a new material params object and initializes enough room for parameters from the provided parameter data. |
78 | */ |
79 | MaterialParamsBase( |
80 | const Map<String, SHADER_DATA_PARAM_DESC>& dataParams, |
81 | const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams, |
82 | const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferParams, |
83 | const Map<String, SHADER_OBJECT_PARAM_DESC>& samplerParams, |
84 | UINT64 initialParamVersion |
85 | ); |
86 | |
87 | /** Constructor for serialization use only. */ |
88 | MaterialParamsBase() = default; |
89 | virtual ~MaterialParamsBase(); |
90 | |
91 | /** |
92 | * Returns the value of a shader data parameter with the specified name at the specified array index. If the |
93 | * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved. |
94 | * |
95 | * @param[in] name Name of the shader parameter. |
96 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
97 | * @param[out] output If successful, value of the parameter. |
98 | * |
99 | * @tparam T Native type of the parameter. |
100 | */ |
101 | template <typename T> |
102 | void getDataParam(const String& name, UINT32 arrayIdx, T& output) const |
103 | { |
104 | GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId; |
105 | |
106 | const ParamData* param = nullptr; |
107 | auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, ¶m); |
108 | if (result != GetParamResult::Success) |
109 | return; |
110 | |
111 | const DataParamInfo& paramInfo = mDataParams[param->index + arrayIdx]; |
112 | |
113 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType]; |
114 | UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
115 | |
116 | memcpy(output, &mDataParamsBuffer[paramInfo.offset], sizeof(paramTypeSize)); |
117 | } |
118 | |
119 | /** |
120 | * Sets the value of a shader data parameter with the specified name at the specified array index. If the |
121 | * parameter name, index or type is not valid a warning will be logged and output value will not be set. |
122 | * |
123 | * @param[in] name Name of the shader parameter. |
124 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
125 | * @param[in] input New value of the parameter. |
126 | * |
127 | * @tparam T Native type of the parameter. |
128 | */ |
129 | template <typename T> |
130 | void setDataParam(const String& name, UINT32 arrayIdx, const T& input) const |
131 | { |
132 | GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId; |
133 | |
134 | const ParamData* param = nullptr; |
135 | auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, ¶m); |
136 | if (result != GetParamResult::Success) |
137 | return; |
138 | |
139 | const DataParamInfo& paramInfo = mDataParams[param->index + arrayIdx]; |
140 | |
141 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType]; |
142 | UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
143 | |
144 | memcpy(&mDataParamsBuffer[paramInfo.offset], input, sizeof(paramTypeSize)); |
145 | } |
146 | |
147 | /** |
148 | * Returns the animation curve assigned to a shader data parameter with the specified name at the specified array |
149 | * index. If the parameter name, index or type is not valid a warning will be logged and output value will not be |
150 | * retrieved. If no curve has been assigned to this parameter then an empty curve is returned. |
151 | * |
152 | * @param[in] name Name of the shader parameter. |
153 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
154 | * @return Animation curve assigned to the parameter. |
155 | * |
156 | * @tparam T Native type of the parameter. |
157 | */ |
158 | template <typename T> |
159 | const TAnimationCurve<T>& getCurveParam(const String& name, UINT32 arrayIdx) const |
160 | { |
161 | static TAnimationCurve<T> EMPTY_CURVE; |
162 | GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId; |
163 | |
164 | const ParamData* param = nullptr; |
165 | auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, ¶m); |
166 | if (result != GetParamResult::Success) |
167 | return EMPTY_CURVE; |
168 | |
169 | return getCurveParam<T>(*param, arrayIdx); |
170 | } |
171 | |
172 | /** |
173 | * Sets an animation curve to a shader data parameter with the specified name at the specified array index. If the |
174 | * parameter name, index or type is not valid a warning will be logged and output value will not be set. |
175 | * |
176 | * @param[in] name Name of the shader parameter. |
177 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
178 | * @param[in] input New value of the parameter. |
179 | * |
180 | * @tparam T Native type of the parameter. |
181 | */ |
182 | template <typename T> |
183 | void setCurveParam(const String& name, UINT32 arrayIdx, TAnimationCurve<T> input) const |
184 | { |
185 | GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId; |
186 | |
187 | const ParamData* param = nullptr; |
188 | auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, ¶m); |
189 | if (result != GetParamResult::Success) |
190 | return; |
191 | |
192 | setCurveParam(*param, arrayIdx, std::move(input)); |
193 | } |
194 | |
195 | /** |
196 | * Returns the color gradient assigned to a shader color parameter with the specified name at the specified array |
197 | * index. If the parameter name, index or type is not valid a warning will be logged and output value will not be |
198 | * retrieved. If no gradient has been assigned to this parameter then an empty gradient is returned. |
199 | * |
200 | * @param[in] name Name of the shader parameter. |
201 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
202 | * @return Color gradient assigned to the parameter. |
203 | */ |
204 | const ColorGradient& getColorGradientParam(const String& name, UINT32 arrayIdx) const; |
205 | |
206 | /** |
207 | * Sets a color gradient to a shader color parameter with the specified name at the specified array index. If the |
208 | * parameter name, index or type is not valid a warning will be logged and output value will not be set. |
209 | * |
210 | * @param[in] name Name of the shader parameter. |
211 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
212 | * @param[in] input New value of the parameter. |
213 | */ |
214 | void setColorGradientParam(const String& name, UINT32 arrayIdx, const ColorGradient& input) const; |
215 | |
216 | /** |
217 | * Returns an index of the parameter with the specified name. Index can be used in a call to getParamData(UINT32) to |
218 | * get the actual parameter data. |
219 | * |
220 | * @param[in] name Name of the shader parameter. |
221 | * @return Index of the parameter, or -1 if not found. |
222 | */ |
223 | UINT32 getParamIndex(const String& name) const; |
224 | |
225 | /** |
226 | * Returns an index of the parameter with the specified name. Index can be used in a call to getParamData(UINT32) to |
227 | * get the actual parameter data. |
228 | * |
229 | * @param[in] name Name of the shader parameter. |
230 | * @param[in] type Type of the parameter retrieve. Error will be logged if actual type of the parameter |
231 | * doesn't match. |
232 | * @param[in] dataType Only relevant if the parameter is a data type. Determines exact data type of the parameter |
233 | * to retrieve. |
234 | * @param[in] arrayIdx Array index of the entry to retrieve. |
235 | * @param[out] output Index of the requested parameter, only valid if success is returned. |
236 | * @return Success or error state of the request. |
237 | */ |
238 | GetParamResult getParamIndex(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx, |
239 | UINT32& output) const; |
240 | |
241 | /** |
242 | * Returns data about a parameter and reports an error if there is a type or size mismatch, or if the parameter |
243 | * does exist. |
244 | * |
245 | * @param[in] name Name of the shader parameter. |
246 | * @param[in] type Type of the parameter retrieve. Error will be logged if actual type of the parameter |
247 | * doesn't match. |
248 | * @param[in] dataType Only relevant if the parameter is a data type. Determines exact data type of the parameter |
249 | * to retrieve. |
250 | * @param[in] arrayIdx Array index of the entry to retrieve. |
251 | * @param[out] output Object describing the parameter with an index to its data. If the parameter was not found |
252 | * this value is undefined. This value will still be valid if parameter was found but |
253 | * some other error was reported. |
254 | * @return Success or error state of the request. |
255 | */ |
256 | GetParamResult getParamData(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx, |
257 | const ParamData** output) const; |
258 | |
259 | /** |
260 | * Returns information about a parameter at the specified global index, as retrieved by getParamIndex(). |
261 | */ |
262 | const ParamData* getParamData(UINT32 index) const { return &mParams[index]; } |
263 | |
264 | /** Returns the total number of parameters managed by this object. */ |
265 | UINT32 getNumParams() const { return (UINT32)mParams.size(); } |
266 | |
267 | /** |
268 | * Logs an error that was reported by getParamData(). |
269 | * |
270 | * @param[in] errorCode Information about the error. |
271 | * @param[in] name Name of the shader parameter for which the error occurred. |
272 | * @param[in] arrayIdx Array index for which the error occurred. |
273 | */ |
274 | void reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const; |
275 | |
276 | /** |
277 | * Equivalent to getDataParam(const String&, UINT32, T&) except it uses the internal parameter reference |
278 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
279 | * object. |
280 | */ |
281 | template <typename T> |
282 | void getDataParam(const ParamData& param, UINT32 arrayIdx, T& output) const |
283 | { |
284 | GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId; |
285 | |
286 | const DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
287 | |
288 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType]; |
289 | UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
290 | |
291 | assert(sizeof(output) == paramTypeSize); |
292 | memcpy(&output, &mDataParamsBuffer[paramInfo.offset], paramTypeSize); |
293 | } |
294 | |
295 | /** |
296 | * Equivalent to setDataParam(const String&, UINT32, T&) except it uses the internal parameter reference |
297 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
298 | * object. |
299 | */ |
300 | template <typename T> |
301 | void setDataParam(const ParamData& param, UINT32 arrayIdx, const T& input) const |
302 | { |
303 | GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId; |
304 | |
305 | DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
306 | if (paramInfo.floatCurve) |
307 | { |
308 | bs_pool_free(paramInfo.floatCurve); |
309 | paramInfo.floatCurve = nullptr; |
310 | } |
311 | |
312 | if (paramInfo.colorGradient) |
313 | { |
314 | bs_pool_free(paramInfo.colorGradient); |
315 | paramInfo.colorGradient = nullptr; |
316 | } |
317 | |
318 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType]; |
319 | UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
320 | |
321 | assert(sizeof(input) == paramTypeSize); |
322 | memcpy(&mDataParamsBuffer[paramInfo.offset], &input, paramTypeSize); |
323 | |
324 | param.version = ++mParamVersion; |
325 | } |
326 | |
327 | /** |
328 | * Equivalent to getCurveParam(const String&, UINT32) except it uses the internal parameter reference directly, |
329 | * avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
330 | * object. |
331 | */ |
332 | template <typename T> |
333 | const TAnimationCurve<T>& getCurveParam(const ParamData& param, UINT32 arrayIdx) const |
334 | { |
335 | GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId; |
336 | |
337 | // Only supported for float types |
338 | if(dataType == GPDT_FLOAT1) |
339 | { |
340 | const DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
341 | if (paramInfo.floatCurve) |
342 | return *paramInfo.floatCurve; |
343 | } |
344 | |
345 | static TAnimationCurve<T> EMPTY_CURVE; |
346 | return EMPTY_CURVE; |
347 | } |
348 | |
349 | /** |
350 | * Equivalent to setCurveParam(const String&, UINT32, const TAnimationCurve<T>&) except it uses the internal |
351 | * parameter reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid |
352 | * and belongs to this object. |
353 | */ |
354 | template <typename T> |
355 | void setCurveParam(const ParamData& param, UINT32 arrayIdx, TAnimationCurve<T> input) const |
356 | { |
357 | GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId; |
358 | |
359 | // Only supported for float types |
360 | if(dataType == GPDT_FLOAT1) |
361 | { |
362 | DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
363 | if(paramInfo.floatCurve) |
364 | bs_pool_free(paramInfo.floatCurve); |
365 | |
366 | paramInfo.floatCurve = bs_pool_new<TAnimationCurve<T>>(std::move(input)); |
367 | |
368 | param.version = ++mParamVersion; |
369 | } |
370 | } |
371 | |
372 | /** |
373 | * Equivalent to getColorGradientParam(const String&, UINT32) except it uses the internal parameter reference |
374 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
375 | * object. |
376 | */ |
377 | const ColorGradient& getColorGradientParam(const ParamData& param, UINT32 arrayIdx) const; |
378 | |
379 | /** |
380 | * Equivalent to setColorGradientParam(const String&, UINT32, const ColorGradient&) except it uses the internal |
381 | * parameter reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid |
382 | * and belongs to this object. |
383 | */ |
384 | void setColorGradientParam(const ParamData& param, UINT32 arrayIdx, const ColorGradient& input) const; |
385 | |
386 | /** Returns pointer to the internal data buffer for a data parameter at the specified index. */ |
387 | UINT8* getData(UINT32 index) const |
388 | { |
389 | return &mDataParamsBuffer[mDataParams[index].offset]; |
390 | } |
391 | |
392 | /** Returns a counter that gets incremented whenever a parameter gets updated. */ |
393 | UINT64 getParamVersion() const { return mParamVersion; } |
394 | |
395 | protected: |
396 | const static UINT32 STATIC_BUFFER_SIZE = 256; |
397 | |
398 | UnorderedMap<String, UINT32> mParamLookup; |
399 | Vector<ParamData> mParams; |
400 | |
401 | DataParamInfo* mDataParams = nullptr; |
402 | UINT8* mDataParamsBuffer = nullptr; |
403 | |
404 | UINT32 mDataSize = 0; |
405 | UINT32 mNumDataParams = 0; |
406 | UINT32 mNumStructParams = 0; |
407 | UINT32 mNumTextureParams = 0; |
408 | UINT32 mNumBufferParams = 0; |
409 | UINT32 mNumSamplerParams = 0; |
410 | |
411 | mutable UINT64 mParamVersion = 1; |
412 | mutable StaticAlloc<STATIC_BUFFER_SIZE> mAlloc; |
413 | }; |
414 | |
415 | /** Raw data for a single structure parameter. */ |
416 | class BS_CORE_EXPORT MaterialParamStructDataCore |
417 | { |
418 | public: |
419 | UINT8* data; |
420 | UINT32 dataSize; |
421 | }; |
422 | |
423 | /** Raw data for a single structure parameter. */ |
424 | class BS_CORE_EXPORT MaterialParamStructData : public IReflectable |
425 | { |
426 | public: |
427 | UINT8* data; |
428 | UINT32 dataSize; |
429 | |
430 | friend class MaterialParamStructDataRTTI; |
431 | static RTTITypeBase* getRTTIStatic(); |
432 | RTTITypeBase* getRTTI() const override; |
433 | }; |
434 | |
435 | /** Data for a single texture parameter. */ |
436 | class BS_CORE_EXPORT MaterialParamTextureDataCore |
437 | { |
438 | public: |
439 | SPtr<ct::Texture> texture; |
440 | SPtr<ct::SpriteTexture> spriteTexture; |
441 | bool isLoadStore; |
442 | TextureSurface surface; |
443 | }; |
444 | |
445 | /** Data for a single texture parameter. */ |
446 | class BS_CORE_EXPORT MaterialParamTextureData : public IReflectable |
447 | { |
448 | public: |
449 | HTexture texture; |
450 | HSpriteTexture spriteTexture; |
451 | bool isLoadStore; |
452 | TextureSurface surface; |
453 | |
454 | friend class MaterialParamTextureDataRTTI; |
455 | static RTTITypeBase* getRTTIStatic(); |
456 | RTTITypeBase* getRTTI() const override; |
457 | }; |
458 | |
459 | /** Data for a single buffer parameter. */ |
460 | class BS_CORE_EXPORT MaterialParamBufferDataCore |
461 | { |
462 | public: |
463 | SPtr<ct::GpuBuffer> value; |
464 | }; |
465 | |
466 | /** Data for a single buffer parameter. */ |
467 | class BS_CORE_EXPORT MaterialParamBufferData |
468 | { |
469 | public: |
470 | SPtr<GpuBuffer> value; |
471 | }; |
472 | |
473 | /** Data for a single sampler state parameter. */ |
474 | class BS_CORE_EXPORT MaterialParamSamplerStateDataCore |
475 | { |
476 | public: |
477 | SPtr<ct::SamplerState> value; |
478 | }; |
479 | |
480 | /** Data for a single sampler state parameter. */ |
481 | class BS_CORE_EXPORT MaterialParamSamplerStateData |
482 | { |
483 | public: |
484 | SPtr<SamplerState> value; |
485 | }; |
486 | |
487 | /** Helper typedefs that reference types used by either core or sim thread implementation of TMaterialParams<Core>. */ |
488 | template<bool Core> struct TMaterialParamsTypes { }; |
489 | template<> struct TMaterialParamsTypes < false > |
490 | { |
491 | typedef MaterialParamStructData StructParamDataType; |
492 | typedef MaterialParamTextureData TextureParamDataType; |
493 | typedef MaterialParamBufferData BufferParamDataType; |
494 | typedef MaterialParamSamplerStateData SamplerStateParamDataType; |
495 | }; |
496 | |
497 | template<> struct TMaterialParamsTypes < true > |
498 | { |
499 | typedef MaterialParamStructDataCore StructParamDataType; |
500 | typedef MaterialParamTextureDataCore TextureParamDataType; |
501 | typedef MaterialParamBufferDataCore BufferParamDataType; |
502 | typedef MaterialParamSamplerStateDataCore SamplerStateParamDataType; |
503 | }; |
504 | |
505 | /** Common code that may be specialized for both MaterialParams and ct::MaterialParams. */ |
506 | template<bool Core> |
507 | class BS_CORE_EXPORT TMaterialParams : public MaterialParamsBase |
508 | { |
509 | public: |
510 | using GpuParamsType = CoreVariantType<GpuParams, Core>; |
511 | using TextureType = CoreVariantHandleType<Texture, Core>; |
512 | using ShaderType = CoreVariantHandleType<Shader, Core>; |
513 | using SpriteTextureType = CoreVariantHandleType<SpriteTexture, Core>; |
514 | using BufferType = SPtr<CoreVariantType<GpuBuffer, Core>>; |
515 | using SamplerType = SPtr<CoreVariantType<SamplerState, Core>>; |
516 | |
517 | using ParamStructDataType = typename TMaterialParamsTypes<Core>::StructParamDataType; |
518 | using ParamTextureDataType = typename TMaterialParamsTypes<Core>::TextureParamDataType; |
519 | using ParamBufferDataType = typename TMaterialParamsTypes<Core>::BufferParamDataType; |
520 | using ParamSamplerStateDataType = typename TMaterialParamsTypes<Core>::SamplerStateParamDataType; |
521 | |
522 | /** |
523 | * Creates a new material params object and initializes enough room for parameters from the provided shader. |
524 | * |
525 | * @param[in] shader Shader containing the information about parameters and their types. |
526 | * @param[in] initialParamVersion Initial version number to assign to the parameters. Usually relevant if |
527 | * you are replacing an existing MaterialParams object and wish to ensure |
528 | * version number keeps getting incremented. |
529 | */ |
530 | TMaterialParams(const ShaderType& shader, UINT64 initialParamVersion); |
531 | |
532 | /** Constructor for serialization use only. */ |
533 | TMaterialParams() = default; |
534 | |
535 | virtual ~TMaterialParams(); |
536 | |
537 | /** |
538 | * Returns the value of a shader structure parameter with the specified name at the specified array index. If the |
539 | * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved. |
540 | * |
541 | * @param[in] name Name of the shader parameter. |
542 | * @param[out] value Pre-allocated buffer of @p size bytes where the value will be retrieved. |
543 | * @param[in] size Size of the buffer into which to write the value. Must match parameter struct's size. |
544 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
545 | */ |
546 | void getStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx) const; |
547 | |
548 | /** |
549 | * Sets the value of a shader structure parameter with the specified name at the specified array index. If the |
550 | * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved. |
551 | * |
552 | * @param[in] name Name of the shader parameter. |
553 | * @param[in] value Buffer of @p size bytes containing the new value of the structure. |
554 | * @param[in] size Size of the buffer from which to retrieve the value. Must match parameter struct's size. |
555 | * @param[in] arrayIdx If the parameter is an array, index of the entry to access. |
556 | */ |
557 | void setStructData(const String& name, const void* value, UINT32 size, UINT32 arrayIdx); |
558 | |
559 | /** |
560 | * Returns the value of a shader texture parameter with the specified name. If the parameter name or type is not |
561 | * valid a warning will be logged and output value will not be retrieved. |
562 | * |
563 | * @param[in] name Name of the shader parameter. |
564 | * @param[out] value Output value of the parameter. |
565 | * @param[out] surface Surface describing which part of the texture is being accessed. |
566 | */ |
567 | void getTexture(const String& name, TextureType& value, TextureSurface& surface) const; |
568 | |
569 | /** |
570 | * Sets the value of a shader texture parameter with the specified name. If the parameter name or type is not |
571 | * valid a warning will be logged and output value will not be set. |
572 | * |
573 | * @param[in] name Name of the shader parameter. |
574 | * @param[in] value New value of the parameter. |
575 | * @param[in] surface Surface describing which part of the texture is being accessed. |
576 | */ |
577 | void setTexture(const String& name, const TextureType& value, |
578 | const TextureSurface& surface = TextureSurface::COMPLETE); |
579 | |
580 | /** |
581 | * Returns the value of a shader texture parameter with the specified name as a sprite texture. If the parameter |
582 | * name or type is not valid a warning will be logged and output value will not be retrieved. If the assigned |
583 | * texture is not a sprite texture then this returns null and you should use one of the getTexture() overloads |
584 | * instead. |
585 | * |
586 | * @param[in] name Name of the shader parameter. |
587 | * @param[out] value Output value of the parameter. |
588 | */ |
589 | void getSpriteTexture(const String& name, SpriteTextureType& value) const; |
590 | |
591 | /** |
592 | * Assigns a sprite texture to a shader texture parameter with the specified name. If the parameter name or type |
593 | * is not valid a warning will be logged and output value will not be set. |
594 | * |
595 | * @param[in] name Name of the shader parameter. |
596 | * @param[in] value New value of the parameter. |
597 | */ |
598 | void setSpriteTexture(const String& name, const SpriteTextureType& value); |
599 | /** |
600 | * Returns the value of a shader load/store texture parameter with the specified name. If the parameter name or |
601 | * type is not valid a warning will be logged and output value will not be retrieved. |
602 | * |
603 | * @param[in] name Name of the shader parameter. |
604 | * @param[out] value Output value of the parameter. |
605 | * @param[out] surface Surface describing which part of the texture is being accessed. |
606 | */ |
607 | void getLoadStoreTexture(const String& name, TextureType& value, TextureSurface& surface) const; |
608 | |
609 | /** |
610 | * Sets the value of a shader load/store texture parameter with the specified name. If the parameter name or |
611 | * type is not valid a warning will be logged and the value will not be set. |
612 | * |
613 | * @param[in] name Name of the shader parameter. |
614 | * @param[in] value New value of the parameter. |
615 | * @param[in] surface Surface describing which part of the texture is being accessed. |
616 | */ |
617 | void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface); |
618 | |
619 | /** |
620 | * Returns the value of a shader buffer parameter with the specified name. If the parameter name or type is not |
621 | * valid a warning will be logged and output value will not be retrieved. |
622 | * |
623 | * @param[in] name Name of the shader parameter. |
624 | * @param[out] value Output value of the parameter. |
625 | */ |
626 | void getBuffer(const String& name, BufferType& value) const; |
627 | |
628 | /** |
629 | * Sets the value of a shader buffer parameter with the specified name. If the parameter name or type is not |
630 | * valid a warning will be logged and output value will not be set. |
631 | * |
632 | * @param[in] name Name of the shader parameter. |
633 | * @param[in] value New value of the parameter. |
634 | */ |
635 | void setBuffer(const String& name, const BufferType& value); |
636 | |
637 | /** |
638 | * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not |
639 | * valid a warning will be logged and output value will not be set. |
640 | * |
641 | * @param[in] name Name of the shader parameter. |
642 | * @param[out] value Output value of the parameter. |
643 | */ |
644 | void getSamplerState(const String& name, SamplerType& value) const; |
645 | |
646 | /** |
647 | * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not |
648 | * valid a warning will be logged and output value will not be set. |
649 | * |
650 | * @param[in] name Name of the shader parameter. |
651 | * @param[in] value New value of the parameter. |
652 | */ |
653 | void setSamplerState(const String& name, const SamplerType& value); |
654 | |
655 | /** |
656 | * Checks does the data parameter with the specified name currently contains animated data. This could be |
657 | * an animation curve or a color gradient. |
658 | */ |
659 | bool isAnimated(const String& name, UINT32 arrayIdx = 0); |
660 | |
661 | /** |
662 | * Equivalent to getStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter reference |
663 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
664 | * object. |
665 | */ |
666 | void getStructData(const ParamData& param, void* value, UINT32 size, UINT32 arrayIdx) const; |
667 | |
668 | /** |
669 | * Equivalent to setStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter reference |
670 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
671 | * object. |
672 | */ |
673 | void setStructData(const ParamData& param, const void* value, UINT32 size, UINT32 arrayIdx); |
674 | |
675 | /** |
676 | * Returns a size of a struct parameter in bytes, using the internal parameter reference. Caller must guarantee the |
677 | * parameter reference is valid and belongs to this object. |
678 | */ |
679 | UINT32 getStructSize(const ParamData& param) const; |
680 | |
681 | /** |
682 | * Equivalent to getTexture(const String&, HTexture&, TextureSurface&) except it uses the internal parameter |
683 | * reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs |
684 | * to this object. |
685 | */ |
686 | void getTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const; |
687 | |
688 | /** |
689 | * Equivalent to setTexture(const String&, const HTexture&, const TextureSurface&) except it uses the internal |
690 | * parameter reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid |
691 | * and belongs to this object. |
692 | */ |
693 | void setTexture(const ParamData& param, const TextureType& value, |
694 | const TextureSurface& surface = TextureSurface::COMPLETE); |
695 | |
696 | /** |
697 | * Equivalent to getSpriteTexture(const String&, HSpriteTexture&) except it uses the internal parameter reference |
698 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
699 | * object. |
700 | */ |
701 | void getSpriteTexture(const ParamData& param, SpriteTextureType& value) const; |
702 | |
703 | /** |
704 | * Equivalent to setSpriteTexture(const String&, const HSpriteTexture&) except it uses the internal parameter |
705 | * reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs |
706 | * to this object. |
707 | */ |
708 | void setSpriteTexture(const ParamData& param, const SpriteTextureType& value); |
709 | |
710 | /** |
711 | * Equivalent to getBuffer(const String&, SPtr<GpuBuffer>&) except it uses the internal parameter reference |
712 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
713 | * object. |
714 | */ |
715 | void getBuffer(const ParamData& param, BufferType& value) const; |
716 | |
717 | /** |
718 | * Equivalent to setBuffer(const String&, const SPtr<GpuBuffer>&) except it uses the internal parameter reference |
719 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
720 | * object. |
721 | */ |
722 | void setBuffer(const ParamData& param, const BufferType& value); |
723 | |
724 | /** |
725 | * Equivalent to getLoadStoreTexture(const String&, HTexture&, TextureSurface&) except it uses the internal |
726 | * parameter reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid |
727 | * and belongs to this object. |
728 | */ |
729 | void getLoadStoreTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const; |
730 | |
731 | /** |
732 | * Equivalent to setLoadStoreTexture(const String&, const HTexture&, TextureSurface&) except it uses the internal |
733 | * parameter reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid |
734 | * and belongs to this object. |
735 | */ |
736 | void setLoadStoreTexture(const ParamData& param, const TextureType& value, const TextureSurface& surface); |
737 | |
738 | /** |
739 | * Returns the type of texture that is currently assigned to the provided parameter. This can only be called on |
740 | * on texture parameters. Caller must guarantee the parameter reference is valid, is of a texture type and |
741 | * belongs to this object. |
742 | */ |
743 | MateralParamTextureType getTextureType(const ParamData& param) const; |
744 | |
745 | /** |
746 | * Checks does the provided parameter have a curve or gradient assigned. This can only be called on data parameters. |
747 | * Caller must guarantee the parameter reference is valid, is of a data type and belongs to this object. |
748 | |
749 | */ |
750 | bool isAnimated(const ParamData& param, UINT32 arrayIdx) const; |
751 | |
752 | /** |
753 | * Returns a sprite texture that is used for populating the specified data parameter. This is only relevant |
754 | * for data parameters marked with the ShaderParamAttributeType::SpriteUV attribute. |
755 | */ |
756 | SpriteTextureType getOwningSpriteTexture(const ParamData& param) const; |
757 | |
758 | /** |
759 | * Equivalent to getSamplerState(const String&, SPtr<SamplerState>&) except it uses the internal parameter reference |
760 | * directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this |
761 | * object. |
762 | */ |
763 | void getSamplerState(const ParamData& param, SamplerType& value) const; |
764 | |
765 | /** |
766 | * Equivalent to setSamplerState(const String&, const SPtr<SamplerState>&) except it uses the internal parameter |
767 | * reference directly, avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs |
768 | * to this object. |
769 | */ |
770 | void setSamplerState(const ParamData& param, const SamplerType& value); |
771 | |
772 | /** |
773 | * Returns the default texture (one assigned when no other is provided), if available for the specified parameter. |
774 | * Parameter is represented using the internal parameter reference and the caller must guarantee the parameter |
775 | * eference is valid and belongs to this object. |
776 | */ |
777 | void getDefaultTexture(const ParamData& param, TextureType& value) const; |
778 | |
779 | /** |
780 | * Returns the default sampler state (one assigned when no other is provided), if available for the specified |
781 | * parameter. Parameter is represented using the internal parameter reference and the caller must guarantee the |
782 | * parameter reference is valid and belongs to this object. |
783 | */ |
784 | void getDefaultSamplerState(const ParamData& param, SamplerType& value) const; |
785 | |
786 | protected: |
787 | ParamStructDataType* mStructParams = nullptr; |
788 | ParamTextureDataType* mTextureParams = nullptr; |
789 | ParamBufferDataType* mBufferParams = nullptr; |
790 | ParamSamplerStateDataType* mSamplerStateParams = nullptr; |
791 | TextureType* mDefaultTextureParams = nullptr; |
792 | SamplerType* mDefaultSamplerStateParams = nullptr; |
793 | }; |
794 | |
795 | /** |
796 | * Contains all parameter values set in a Material. This is similar to GpuParams which also stores parameter values, |
797 | * however GpuParams are built for use on the GPU-side and don't store parameters that don't exist in a compiled GPU |
798 | * program. This object on the other hand stores all parameters defined in a shader, regardless or not if they actually |
799 | * exist in the GPU program. Additionally GpuParams are defined per-program (for example vertex, fragment) while this |
800 | * object exists for the entire material. |
801 | * |
802 | * @note |
803 | * This introduces redundancy as parameters stored by GpuParams and this object are duplicated. If this is an issue the |
804 | * implementation can be modified to only store parameters not included in GpuParams. |
805 | * @note |
806 | * The reason why parameters in this class and GpuParams differ is most often compiler optimizations. If a compiler |
807 | * optimizes out a variable in a GPU program we should still be able to store it, either for later when the variable |
808 | * will be introduced, or for other techniques that might have that variable implemented. |
809 | */ |
810 | class BS_CORE_EXPORT MaterialParams : public IReflectable, public TMaterialParams<false> |
811 | { |
812 | public: |
813 | /** @copydoc TMaterialParams::TMaterialParams(const ShaderType&, UINT32) */ |
814 | MaterialParams(const HShader& shader, UINT64 initialParamVersion = 1); |
815 | |
816 | /** |
817 | * Populates the provided buffer with parameters that can be used for syncing this object with its core-thread |
818 | * counterpart. Can be applied by calling ct::MaterialParams::setSyncData. |
819 | * |
820 | * @param[in] buffer Pre-allocated buffer to store the sync data in. Set to null to calculate the size |
821 | * of the required buffer. |
822 | * @param[in, out] size Size of the provided allocated buffer. Or if the buffer is null, this parameter will |
823 | * contain the required buffer size when the method executes. |
824 | * @param[in] forceAll If false, only the parameters that were changed since the last call will be synced. |
825 | * Otherwise all parameters will be synced. |
826 | */ |
827 | void getSyncData(UINT8* buffer, UINT32& size, bool forceAll); |
828 | |
829 | /** Appends any resources stored by this object to the provided vector. */ |
830 | void getResourceDependencies(Vector<HResource>& resources); |
831 | |
832 | /** Appends any core objects stored by this object to the provided vector. */ |
833 | void getCoreObjectDependencies(Vector<CoreObject*>& coreObjects); |
834 | |
835 | private: |
836 | friend class ct::MaterialParams; |
837 | |
838 | UINT64 mLastSyncVersion; |
839 | |
840 | /************************************************************************/ |
841 | /* RTTI */ |
842 | /************************************************************************/ |
843 | public: |
844 | MaterialParams() { } // Only for serialization |
845 | |
846 | friend class MaterialParamsRTTI; |
847 | static RTTITypeBase* getRTTIStatic(); |
848 | RTTITypeBase* getRTTI() const override; |
849 | }; |
850 | |
851 | namespace ct |
852 | { |
853 | /** Core thread version of MaterialParams. */ |
854 | class BS_CORE_EXPORT MaterialParams : public TMaterialParams<true> |
855 | { |
856 | public: |
857 | /** Initializes the core thread version of MaterialParams from its sim thread counterpart. */ |
858 | MaterialParams(const SPtr<Shader>& shader, const SPtr<bs::MaterialParams>& params); |
859 | |
860 | /** @copydoc TMaterialParams::TMaterialParams(const ShaderType&, UINT32) */ |
861 | MaterialParams(const SPtr<Shader>& shader, UINT64 initialParamVersion = 1); |
862 | |
863 | /** |
864 | * Updates the stored parameters from the provided buffer, allowing changes to be transfered between the sim and |
865 | * core thread material param objects. Buffer must be retrieved from bs::MaterialParams::getSyncData. |
866 | * |
867 | * @param[in] buffer Buffer containing the dirty data. |
868 | * @param[in, out] size Size of the provided buffer. |
869 | */ |
870 | void setSyncData(UINT8* buffer, UINT32 size); |
871 | }; |
872 | } |
873 | /** @} */ |
874 | } |
875 | |