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 | #include "Material/BsMaterialParams.h" |
4 | #include "Private/RTTI/BsMaterialParamsRTTI.h" |
5 | #include "Material/BsShader.h" |
6 | #include "Image/BsTexture.h" |
7 | #include "Image/BsSpriteTexture.h" |
8 | #include "RenderAPI/BsGpuBuffer.h" |
9 | #include "RenderAPI/BsSamplerState.h" |
10 | #include "Image/BsColorGradient.h" |
11 | #include "Animation/BsAnimationCurve.h" |
12 | #include "Allocators/BsPoolAlloc.h" |
13 | |
14 | namespace bs |
15 | { |
16 | namespace impl |
17 | { |
18 | SPtr<ct::Texture> getSpriteTextureAtlas(const SPtr<ct::SpriteTexture>& spriteTexture) |
19 | { |
20 | if(spriteTexture) |
21 | return spriteTexture->getTexture(); |
22 | |
23 | return nullptr; |
24 | } |
25 | |
26 | HTexture getSpriteTextureAtlas(const HSpriteTexture& spriteTexture) |
27 | { |
28 | if(spriteTexture.isLoaded()) |
29 | return spriteTexture->getTexture(); |
30 | |
31 | return HTexture(); |
32 | } |
33 | } |
34 | |
35 | MaterialParamsBase::MaterialParamsBase( |
36 | const Map<String, SHADER_DATA_PARAM_DESC>& dataParams, |
37 | const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams, |
38 | const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferParams, |
39 | const Map<String, SHADER_OBJECT_PARAM_DESC>& samplerParams, |
40 | UINT64 initialParamVersion |
41 | ) |
42 | : mParamVersion(initialParamVersion) |
43 | { |
44 | mDataSize = 0; |
45 | |
46 | for (auto& param : dataParams) |
47 | { |
48 | if(param.second.type == GPDT_UNKNOWN) |
49 | continue; |
50 | |
51 | UINT32 arraySize = param.second.arraySize > 1 ? param.second.arraySize : 1; |
52 | if(param.second.type == GPDT_STRUCT) |
53 | mNumStructParams += arraySize; |
54 | else |
55 | { |
56 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.second.type]; |
57 | UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
58 | |
59 | mDataSize += arraySize * paramSize; |
60 | mNumDataParams += arraySize; |
61 | } |
62 | } |
63 | |
64 | mNumTextureParams = (UINT32)textureParams.size(); |
65 | mNumBufferParams = (UINT32)bufferParams.size(); |
66 | mNumSamplerParams = (UINT32)samplerParams.size(); |
67 | |
68 | mDataParamsBuffer = mAlloc.alloc(mDataSize); |
69 | memset(mDataParamsBuffer, 0, mDataSize); |
70 | |
71 | mDataParams = (DataParamInfo*)mAlloc.alloc(mNumDataParams * sizeof(DataParamInfo)); |
72 | memset(mDataParams, 0, mNumDataParams * sizeof(DataParamInfo)); |
73 | |
74 | UINT32 dataParamIdx = 0; |
75 | UINT32 dataBufferIdx = 0; |
76 | UINT32 structParamIdx = 0; |
77 | |
78 | for (auto& entry : dataParams) |
79 | { |
80 | if(entry.second.type == GPDT_UNKNOWN) |
81 | continue; |
82 | |
83 | const auto paramIdx = (UINT32)mParams.size(); |
84 | mParams.push_back(ParamData()); |
85 | mParamLookup[entry.first] = paramIdx; |
86 | |
87 | ParamData& dataParam = mParams.back(); |
88 | |
89 | const UINT32 arraySize = entry.second.arraySize > 1 ? entry.second.arraySize : 1; |
90 | dataParam.arraySize = arraySize; |
91 | dataParam.type = ParamType::Data; |
92 | dataParam.dataType = entry.second.type; |
93 | dataParam.version = 1; |
94 | |
95 | if(entry.second.type == GPDT_STRUCT) |
96 | { |
97 | dataParam.index = structParamIdx; |
98 | structParamIdx += arraySize; |
99 | } |
100 | else |
101 | { |
102 | dataParam.index = dataParamIdx; |
103 | |
104 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)dataParam.dataType]; |
105 | const UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
106 | for (UINT32 i = 0; i < arraySize; i++) |
107 | { |
108 | mDataParams[dataParamIdx].offset = dataBufferIdx; |
109 | mDataParams[dataParamIdx].spriteTextureIdx = (UINT32)-1; |
110 | |
111 | dataBufferIdx += paramSize; |
112 | dataParamIdx++; |
113 | } |
114 | } |
115 | } |
116 | |
117 | UINT32 textureIdx = 0; |
118 | for (auto& entry : textureParams) |
119 | { |
120 | UINT32 paramIdx = (UINT32)mParams.size(); |
121 | mParams.push_back(ParamData()); |
122 | mParamLookup[entry.first] = paramIdx; |
123 | |
124 | ParamData& dataParam = mParams.back(); |
125 | |
126 | dataParam.arraySize = 1; |
127 | dataParam.type = ParamType::Texture; |
128 | dataParam.dataType = GPDT_UNKNOWN; |
129 | dataParam.index = textureIdx; |
130 | dataParam.version = 1; |
131 | |
132 | textureIdx++; |
133 | } |
134 | |
135 | UINT32 bufferIdx = 0; |
136 | for (auto& entry : bufferParams) |
137 | { |
138 | UINT32 paramIdx = (UINT32)mParams.size(); |
139 | mParams.push_back(ParamData()); |
140 | mParamLookup[entry.first] = paramIdx; |
141 | |
142 | ParamData& dataParam = mParams.back(); |
143 | |
144 | dataParam.arraySize = 1; |
145 | dataParam.type = ParamType::Buffer; |
146 | dataParam.dataType = GPDT_UNKNOWN; |
147 | dataParam.index = bufferIdx; |
148 | dataParam.version = 1; |
149 | |
150 | bufferIdx++; |
151 | } |
152 | |
153 | UINT32 samplerIdx = 0; |
154 | for (auto& entry : samplerParams) |
155 | { |
156 | UINT32 paramIdx = (UINT32)mParams.size(); |
157 | mParams.push_back(ParamData()); |
158 | mParamLookup[entry.first] = paramIdx; |
159 | |
160 | ParamData& dataParam = mParams.back(); |
161 | |
162 | dataParam.arraySize = 1; |
163 | dataParam.type = ParamType::Sampler; |
164 | dataParam.dataType = GPDT_UNKNOWN; |
165 | dataParam.index = samplerIdx; |
166 | dataParam.version = 1; |
167 | |
168 | samplerIdx++; |
169 | } |
170 | } |
171 | |
172 | MaterialParamsBase::~MaterialParamsBase() |
173 | { |
174 | for(UINT32 i = 0; i < mNumDataParams; i++) |
175 | { |
176 | DataParamInfo& paramInfo = mDataParams[i]; |
177 | |
178 | if (paramInfo.floatCurve) |
179 | { |
180 | bs_pool_free(paramInfo.floatCurve); |
181 | paramInfo.floatCurve = nullptr; |
182 | } |
183 | |
184 | if (paramInfo.colorGradient) |
185 | { |
186 | bs_pool_free(paramInfo.colorGradient); |
187 | paramInfo.colorGradient = nullptr; |
188 | } |
189 | } |
190 | |
191 | mAlloc.free(mDataParamsBuffer); |
192 | mAlloc.free(mDataParams); |
193 | |
194 | mAlloc.clear(); |
195 | } |
196 | |
197 | const ColorGradient& MaterialParamsBase::getColorGradientParam(const String& name, UINT32 arrayIdx) const |
198 | { |
199 | static ColorGradient EMPTY_GRADIENT; |
200 | |
201 | const ParamData* param = nullptr; |
202 | auto result = getParamData(name, ParamType::Data, GPDT_COLOR, arrayIdx, ¶m); |
203 | if (result != GetParamResult::Success) |
204 | return EMPTY_GRADIENT; |
205 | |
206 | return getColorGradientParam(*param, arrayIdx); |
207 | } |
208 | |
209 | void MaterialParamsBase::setColorGradientParam(const String& name, UINT32 arrayIdx, const ColorGradient& input) const |
210 | { |
211 | const ParamData* param = nullptr; |
212 | auto result = getParamData(name, ParamType::Data, GPDT_COLOR, arrayIdx, ¶m); |
213 | if (result != GetParamResult::Success) |
214 | return; |
215 | |
216 | setColorGradientParam(*param, arrayIdx, input); |
217 | } |
218 | |
219 | const ColorGradient& MaterialParamsBase::getColorGradientParam(const ParamData& param, UINT32 arrayIdx) const |
220 | { |
221 | const DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
222 | if (paramInfo.colorGradient) |
223 | return *paramInfo.colorGradient; |
224 | |
225 | static ColorGradient EMPTY_GRADIENT; |
226 | return EMPTY_GRADIENT; |
227 | } |
228 | |
229 | void MaterialParamsBase::setColorGradientParam(const ParamData& param, UINT32 arrayIdx, const ColorGradient& input) const |
230 | { |
231 | DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
232 | if (paramInfo.colorGradient) |
233 | bs_pool_free(paramInfo.colorGradient); |
234 | |
235 | paramInfo.colorGradient = bs_pool_new<ColorGradient>(input); |
236 | |
237 | param.version = ++mParamVersion; |
238 | } |
239 | |
240 | UINT32 MaterialParamsBase::getParamIndex(const String& name) const |
241 | { |
242 | auto iterFind = mParamLookup.find(name); |
243 | if (iterFind == mParamLookup.end()) |
244 | return (UINT32)-1; |
245 | |
246 | return iterFind->second; |
247 | } |
248 | |
249 | MaterialParamsBase::GetParamResult MaterialParamsBase::getParamIndex(const String& name, ParamType type, |
250 | GpuParamDataType dataType, UINT32 arrayIdx, UINT32& output) const |
251 | { |
252 | auto iterFind = mParamLookup.find(name); |
253 | if (iterFind == mParamLookup.end()) |
254 | return GetParamResult::NotFound; |
255 | |
256 | UINT32 index = iterFind->second; |
257 | const ParamData& param = mParams[index]; |
258 | |
259 | if (param.type != type || (type == ParamType::Data && param.dataType != dataType)) |
260 | return GetParamResult::InvalidType; |
261 | |
262 | if (arrayIdx >= param.arraySize) |
263 | return GetParamResult::IndexOutOfBounds; |
264 | |
265 | output = index; |
266 | return GetParamResult::Success; |
267 | } |
268 | |
269 | MaterialParamsBase::GetParamResult MaterialParamsBase::getParamData(const String& name, ParamType type, |
270 | GpuParamDataType dataType, UINT32 arrayIdx, const ParamData** output) const |
271 | { |
272 | auto iterFind = mParamLookup.find(name); |
273 | if (iterFind == mParamLookup.end()) |
274 | return GetParamResult::NotFound; |
275 | |
276 | UINT32 index = iterFind->second; |
277 | const ParamData& param = mParams[index]; |
278 | *output = ¶m; |
279 | |
280 | if (param.type != type || (type == ParamType::Data && param.dataType != dataType)) |
281 | return GetParamResult::InvalidType; |
282 | |
283 | if (arrayIdx >= param.arraySize) |
284 | return GetParamResult::IndexOutOfBounds; |
285 | |
286 | return GetParamResult::Success; |
287 | } |
288 | |
289 | void MaterialParamsBase::reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const |
290 | { |
291 | switch (errorCode) |
292 | { |
293 | case GetParamResult::NotFound: |
294 | LOGWRN("Material doesn't have a parameter named " + name + "." ); |
295 | break; |
296 | case GetParamResult::InvalidType: |
297 | LOGWRN("Parameter \"" + name + "\" is not of the requested type." ); |
298 | break; |
299 | case GetParamResult::IndexOutOfBounds: |
300 | LOGWRN("Parameter \"" + name + "\" array index " + toString(arrayIdx) + " out of range." ); |
301 | break; |
302 | default: |
303 | break; |
304 | } |
305 | } |
306 | |
307 | RTTITypeBase* MaterialParamStructData::getRTTIStatic() |
308 | { |
309 | return MaterialParamStructDataRTTI::instance(); |
310 | } |
311 | |
312 | RTTITypeBase* MaterialParamStructData::getRTTI() const |
313 | { |
314 | return getRTTIStatic(); |
315 | } |
316 | |
317 | RTTITypeBase* MaterialParamTextureData::getRTTIStatic() |
318 | { |
319 | return MaterialParamTextureDataRTTI::instance(); |
320 | } |
321 | |
322 | RTTITypeBase* MaterialParamTextureData::getRTTI() const |
323 | { |
324 | return getRTTIStatic(); |
325 | } |
326 | |
327 | template<bool Core> |
328 | TMaterialParams<Core>::TMaterialParams(const ShaderType& shader, UINT64 initialParamVersion) |
329 | :MaterialParamsBase( |
330 | shader->getDataParams(), |
331 | shader->getTextureParams(), |
332 | shader->getBufferParams(), |
333 | shader->getSamplerParams(), |
334 | initialParamVersion |
335 | ) |
336 | { |
337 | mStructParams = mAlloc.construct<ParamStructDataType>(mNumStructParams); |
338 | mTextureParams = mAlloc.construct<ParamTextureDataType>(mNumTextureParams); |
339 | mBufferParams = mAlloc.construct<ParamBufferDataType>(mNumBufferParams); |
340 | mSamplerStateParams = mAlloc.construct<ParamSamplerStateDataType>(mNumSamplerParams); |
341 | mDefaultTextureParams = mAlloc.construct<TextureType>(mNumTextureParams); |
342 | mDefaultSamplerStateParams = mAlloc.construct<SamplerType>(mNumSamplerParams); |
343 | |
344 | auto& textureParams = shader->getTextureParams(); |
345 | UINT32 textureIdx = 0; |
346 | for (auto& entry : textureParams) |
347 | { |
348 | ParamTextureDataType& param = mTextureParams[textureIdx]; |
349 | param.isLoadStore = false; |
350 | |
351 | if (entry.second.defaultValueIdx != (UINT32)-1) |
352 | mDefaultTextureParams[textureIdx] = shader->getDefaultTexture(entry.second.defaultValueIdx); |
353 | |
354 | textureIdx++; |
355 | } |
356 | |
357 | auto& samplerParams = shader->getSamplerParams(); |
358 | UINT32 samplerIdx = 0; |
359 | for (auto& entry : samplerParams) |
360 | { |
361 | if (entry.second.defaultValueIdx != (UINT32)-1) |
362 | mDefaultSamplerStateParams[samplerIdx] = shader->getDefaultSampler(entry.second.defaultValueIdx); |
363 | |
364 | samplerIdx++; |
365 | } |
366 | |
367 | // Note: Make sure to process data parameters after textures, in order to handle SpriteUV data parameters |
368 | auto& dataParams = shader->getDataParams(); |
369 | auto& paramAttributes = shader->getParamAttributes(); |
370 | UINT32 structIdx = 0; |
371 | for (auto& entry : dataParams) |
372 | { |
373 | if(entry.second.type == GPDT_STRUCT) |
374 | { |
375 | UINT32 arraySize = entry.second.arraySize > 1 ? entry.second.arraySize : 1; |
376 | for (UINT32 i = 0; i < arraySize; i++) |
377 | { |
378 | ParamStructDataType& param = mStructParams[structIdx]; |
379 | param.dataSize = entry.second.elementSize; |
380 | param.data = mAlloc.alloc(param.dataSize); |
381 | |
382 | structIdx++; |
383 | } |
384 | } |
385 | else |
386 | { |
387 | // Check for SpriteUV attribute |
388 | UINT32 attribIdx = entry.second.attribIdx; |
389 | while (attribIdx != (UINT32)-1) |
390 | { |
391 | const SHADER_PARAM_ATTRIBUTE& attrib = paramAttributes[attribIdx]; |
392 | if (attrib.type == ShaderParamAttributeType::SpriteUV) |
393 | { |
394 | // Find referenced texture |
395 | const auto findIterTex = mParamLookup.find(attrib.value); |
396 | const auto findIterParam = mParamLookup.find(entry.first); |
397 | if (findIterTex != mParamLookup.end() && findIterParam != mParamLookup.end()) |
398 | { |
399 | ParamData& paramData = mParams[findIterParam->second]; |
400 | |
401 | DataParamInfo& dataParamInfo = mDataParams[paramData.index]; |
402 | dataParamInfo.spriteTextureIdx = findIterTex->second; |
403 | } |
404 | } |
405 | |
406 | attribIdx = attrib.nextParamIdx; |
407 | } |
408 | } |
409 | } |
410 | } |
411 | |
412 | template<bool Core> |
413 | TMaterialParams<Core>::~TMaterialParams() |
414 | { |
415 | if (mStructParams != nullptr) |
416 | { |
417 | for (UINT32 i = 0; i < mNumStructParams; i++) |
418 | mAlloc.free(mStructParams[i].data); |
419 | } |
420 | |
421 | mAlloc.destruct(mStructParams, mNumStructParams); |
422 | mAlloc.destruct(mTextureParams, mNumTextureParams); |
423 | mAlloc.destruct(mBufferParams, mNumBufferParams); |
424 | mAlloc.destruct(mSamplerStateParams, mNumSamplerParams); |
425 | |
426 | if(mDefaultTextureParams != nullptr) |
427 | mAlloc.destruct(mDefaultTextureParams, mNumTextureParams); |
428 | |
429 | if (mDefaultSamplerStateParams != nullptr) |
430 | mAlloc.destruct(mDefaultSamplerStateParams, mNumSamplerParams); |
431 | } |
432 | |
433 | template<bool Core> |
434 | void TMaterialParams<Core>::getStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx) const |
435 | { |
436 | const ParamData* param = nullptr; |
437 | GetParamResult result = getParamData(name, ParamType::Data, GPDT_STRUCT, arrayIdx, ¶m); |
438 | if (result != GetParamResult::Success) |
439 | { |
440 | reportGetParamError(result, name, arrayIdx); |
441 | return; |
442 | } |
443 | |
444 | getStructData(*param, value, size, arrayIdx); |
445 | } |
446 | |
447 | template<bool Core> |
448 | void TMaterialParams<Core>::setStructData(const String& name, const void* value, UINT32 size, UINT32 arrayIdx) |
449 | { |
450 | const ParamData* param = nullptr; |
451 | GetParamResult result = getParamData(name, ParamType::Data, GPDT_STRUCT, arrayIdx, ¶m); |
452 | if (result != GetParamResult::Success) |
453 | { |
454 | reportGetParamError(result, name, arrayIdx); |
455 | return; |
456 | } |
457 | |
458 | setStructData(*param, value, size, arrayIdx); |
459 | } |
460 | |
461 | template<bool Core> |
462 | void TMaterialParams<Core>::getTexture(const String& name, TextureType& value, TextureSurface& surface) const |
463 | { |
464 | const ParamData* param = nullptr; |
465 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
466 | if (result != GetParamResult::Success) |
467 | { |
468 | reportGetParamError(result, name, 0); |
469 | return; |
470 | } |
471 | |
472 | getTexture(*param, value, surface); |
473 | } |
474 | |
475 | template<bool Core> |
476 | void TMaterialParams<Core>::setTexture(const String& name, const TextureType& value, const TextureSurface& surface) |
477 | { |
478 | const ParamData* param = nullptr; |
479 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
480 | if (result != GetParamResult::Success) |
481 | { |
482 | reportGetParamError(result, name, 0); |
483 | return; |
484 | } |
485 | |
486 | setTexture(*param, value, surface); |
487 | } |
488 | |
489 | template<bool Core> |
490 | void TMaterialParams<Core>::getSpriteTexture(const String& name, SpriteTextureType& value) const |
491 | { |
492 | const ParamData* param = nullptr; |
493 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
494 | if (result != GetParamResult::Success) |
495 | { |
496 | reportGetParamError(result, name, 0); |
497 | return; |
498 | } |
499 | |
500 | getSpriteTexture(*param, value); |
501 | } |
502 | |
503 | template<bool Core> |
504 | void TMaterialParams<Core>::setSpriteTexture(const String& name, const SpriteTextureType& value) |
505 | { |
506 | const ParamData* param = nullptr; |
507 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
508 | if (result != GetParamResult::Success) |
509 | { |
510 | reportGetParamError(result, name, 0); |
511 | return; |
512 | } |
513 | |
514 | setSpriteTexture(*param, value); |
515 | } |
516 | |
517 | template<bool Core> |
518 | void TMaterialParams<Core>::getLoadStoreTexture(const String& name, TextureType& value, TextureSurface& surface) const |
519 | { |
520 | const ParamData* param = nullptr; |
521 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
522 | if (result != GetParamResult::Success) |
523 | { |
524 | reportGetParamError(result, name, 0); |
525 | return; |
526 | } |
527 | |
528 | getLoadStoreTexture(*param, value, surface); |
529 | } |
530 | |
531 | template<bool Core> |
532 | void TMaterialParams<Core>::setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface) |
533 | { |
534 | const ParamData* param = nullptr; |
535 | GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, ¶m); |
536 | if (result != GetParamResult::Success) |
537 | { |
538 | reportGetParamError(result, name, 0); |
539 | return; |
540 | } |
541 | |
542 | setLoadStoreTexture(*param, value, surface); |
543 | } |
544 | |
545 | template<bool Core> |
546 | void TMaterialParams<Core>::getBuffer(const String& name, BufferType& value) const |
547 | { |
548 | const ParamData* param = nullptr; |
549 | GetParamResult result = getParamData(name, ParamType::Buffer, GPDT_UNKNOWN, 0, ¶m); |
550 | if (result != GetParamResult::Success) |
551 | { |
552 | reportGetParamError(result, name, 0); |
553 | return; |
554 | } |
555 | |
556 | getBuffer(*param, value); |
557 | } |
558 | |
559 | template<bool Core> |
560 | void TMaterialParams<Core>::setBuffer(const String& name, const BufferType& value) |
561 | { |
562 | const ParamData* param = nullptr; |
563 | GetParamResult result = getParamData(name, ParamType::Buffer, GPDT_UNKNOWN, 0, ¶m); |
564 | if (result != GetParamResult::Success) |
565 | { |
566 | reportGetParamError(result, name, 0); |
567 | return; |
568 | } |
569 | |
570 | setBuffer(*param, value); |
571 | } |
572 | |
573 | template<bool Core> |
574 | void TMaterialParams<Core>::getSamplerState(const String& name, SamplerType& value) const |
575 | { |
576 | const ParamData* param = nullptr; |
577 | GetParamResult result = getParamData(name, ParamType::Sampler, GPDT_UNKNOWN, 0, ¶m); |
578 | if (result != GetParamResult::Success) |
579 | { |
580 | reportGetParamError(result, name, 0); |
581 | return; |
582 | } |
583 | |
584 | getSamplerState(*param, value); |
585 | } |
586 | |
587 | template<bool Core> |
588 | void TMaterialParams<Core>::setSamplerState(const String& name, const SamplerType& value) |
589 | { |
590 | const ParamData* param = nullptr; |
591 | GetParamResult result = getParamData(name, ParamType::Sampler, GPDT_UNKNOWN, 0, ¶m); |
592 | if(result != GetParamResult::Success) |
593 | { |
594 | reportGetParamError(result, name, 0); |
595 | return; |
596 | } |
597 | |
598 | setSamplerState(*param, value); |
599 | } |
600 | |
601 | template<bool Core> |
602 | bool TMaterialParams<Core>::isAnimated(const String& name, UINT32 arrayIdx) |
603 | { |
604 | auto iterFind = mParamLookup.find(name); |
605 | if (iterFind == mParamLookup.end()) |
606 | return false; |
607 | |
608 | UINT32 index = iterFind->second; |
609 | const ParamData& param = mParams[index]; |
610 | |
611 | if (param.type != ParamType::Data) |
612 | return false; |
613 | |
614 | if (arrayIdx >= param.arraySize) |
615 | return false; |
616 | |
617 | return isAnimated(param, arrayIdx); |
618 | } |
619 | |
620 | template<bool Core> |
621 | void TMaterialParams<Core>::getStructData(const ParamData& param, void* value, UINT32 size, UINT32 arrayIdx) const |
622 | { |
623 | const ParamStructDataType& structParam = mStructParams[param.index + arrayIdx]; |
624 | if (structParam.dataSize != size) |
625 | { |
626 | LOGWRN("Size mismatch when writing to a struct. Provided size was " + toString(size) + " bytes but the " |
627 | "struct size is" + toString(structParam.dataSize) + " bytes" ); |
628 | return; |
629 | } |
630 | |
631 | memcpy(value, structParam.data, structParam.dataSize); |
632 | } |
633 | |
634 | template<bool Core> |
635 | void TMaterialParams<Core>::setStructData(const ParamData& param, const void* value, UINT32 size, UINT32 arrayIdx) |
636 | { |
637 | const ParamStructDataType& structParam = mStructParams[param.index + arrayIdx]; |
638 | if (structParam.dataSize != size) |
639 | { |
640 | LOGWRN("Size mismatch when writing to a struct. Provided size was " + toString(size) + " bytes but the " |
641 | "struct size is" + toString(structParam.dataSize) + " bytes" ); |
642 | return; |
643 | } |
644 | |
645 | memcpy(structParam.data, value, structParam.dataSize); |
646 | param.version = ++mParamVersion; |
647 | } |
648 | |
649 | template<bool Core> |
650 | UINT32 TMaterialParams<Core>::getStructSize(const ParamData& param) const |
651 | { |
652 | const ParamStructDataType& structParam = mStructParams[param.index]; |
653 | return structParam.dataSize; |
654 | } |
655 | |
656 | template<bool Core> |
657 | void TMaterialParams<Core>::getTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const |
658 | { |
659 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
660 | |
661 | if(textureParam.texture) |
662 | value = textureParam.texture; |
663 | else if(textureParam.spriteTexture) |
664 | value = impl::getSpriteTextureAtlas(textureParam.spriteTexture); |
665 | |
666 | surface = textureParam.surface; |
667 | } |
668 | |
669 | template<bool Core> |
670 | void TMaterialParams<Core>::setTexture(const ParamData& param, const TextureType& value, const TextureSurface& surface) |
671 | { |
672 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
673 | textureParam.texture = value; |
674 | textureParam.spriteTexture = nullptr; |
675 | textureParam.isLoadStore = false; |
676 | textureParam.surface = surface; |
677 | |
678 | param.version = ++mParamVersion; |
679 | } |
680 | |
681 | template<bool Core> |
682 | void TMaterialParams<Core>::getSpriteTexture(const ParamData& param, SpriteTextureType& value) const |
683 | { |
684 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
685 | value = textureParam.spriteTexture; |
686 | } |
687 | |
688 | template<bool Core> |
689 | void TMaterialParams<Core>::setSpriteTexture(const ParamData& param, const SpriteTextureType& value) |
690 | { |
691 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
692 | textureParam.texture = nullptr; |
693 | textureParam.spriteTexture = value; |
694 | textureParam.isLoadStore = false; |
695 | textureParam.surface = TextureSurface::COMPLETE; |
696 | |
697 | param.version = ++mParamVersion; |
698 | } |
699 | |
700 | template<bool Core> |
701 | void TMaterialParams<Core>::getBuffer(const ParamData& param, BufferType& value) const |
702 | { |
703 | value = mBufferParams[param.index].value; |
704 | } |
705 | |
706 | template<bool Core> |
707 | void TMaterialParams<Core>::setBuffer(const ParamData& param, const BufferType& value) |
708 | { |
709 | mBufferParams[param.index].value = value; |
710 | |
711 | param.version = ++mParamVersion; |
712 | } |
713 | |
714 | template<bool Core> |
715 | void TMaterialParams<Core>::getLoadStoreTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const |
716 | { |
717 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
718 | value = textureParam.texture; |
719 | surface = textureParam.surface; |
720 | } |
721 | |
722 | template<bool Core> |
723 | void TMaterialParams<Core>::setLoadStoreTexture(const ParamData& param, const TextureType& value, const TextureSurface& surface) |
724 | { |
725 | ParamTextureDataType& textureParam = mTextureParams[param.index]; |
726 | textureParam.texture = value; |
727 | textureParam.spriteTexture = nullptr; |
728 | textureParam.isLoadStore = true; |
729 | textureParam.surface = surface; |
730 | |
731 | param.version = ++mParamVersion; |
732 | } |
733 | |
734 | template<bool Core> |
735 | void TMaterialParams<Core>::getSamplerState(const ParamData& param, SamplerType& value) const |
736 | { |
737 | value = mSamplerStateParams[param.index].value; |
738 | } |
739 | |
740 | template<bool Core> |
741 | void TMaterialParams<Core>::setSamplerState(const ParamData& param, const SamplerType& value) |
742 | { |
743 | mSamplerStateParams[param.index].value = value; |
744 | |
745 | param.version = ++mParamVersion; |
746 | } |
747 | |
748 | template<bool Core> |
749 | MateralParamTextureType TMaterialParams<Core>::getTextureType(const ParamData& param) const |
750 | { |
751 | if(mTextureParams[param.index].isLoadStore) |
752 | return MateralParamTextureType::LoadStore; |
753 | |
754 | if(mTextureParams[param.index].spriteTexture) |
755 | return MateralParamTextureType::Sprite; |
756 | |
757 | return MateralParamTextureType::Normal; |
758 | } |
759 | |
760 | template<bool Core> |
761 | bool TMaterialParams<Core>::isAnimated(const ParamData& param, UINT32 arrayIdx) const |
762 | { |
763 | const DataParamInfo& paramInfo = mDataParams[param.index + arrayIdx]; |
764 | |
765 | return paramInfo.floatCurve || paramInfo.colorGradient || paramInfo.spriteTextureIdx != (UINT32)-1; |
766 | } |
767 | |
768 | template<bool Core> |
769 | typename TMaterialParams<Core>::SpriteTextureType TMaterialParams<Core>::getOwningSpriteTexture(const ParamData& param) const |
770 | { |
771 | SpriteTextureType output; |
772 | |
773 | const DataParamInfo& paramInfo = mDataParams[param.index]; |
774 | if (paramInfo.spriteTextureIdx == (UINT32)-1) |
775 | return output; |
776 | |
777 | const ParamData* spriteTexParamData = getParamData(paramInfo.spriteTextureIdx); |
778 | if(spriteTexParamData) |
779 | getSpriteTexture(*spriteTexParamData, output); |
780 | |
781 | return output; |
782 | } |
783 | |
784 | template<bool Core> |
785 | void TMaterialParams<Core>::getDefaultTexture(const ParamData& param, TextureType& value) const |
786 | { |
787 | value = mDefaultTextureParams[param.index]; |
788 | } |
789 | |
790 | template<bool Core> |
791 | void TMaterialParams<Core>::getDefaultSamplerState(const ParamData& param, SamplerType& value) const |
792 | { |
793 | value = mDefaultSamplerStateParams[param.index]; |
794 | } |
795 | |
796 | template class TMaterialParams<true>; |
797 | template class TMaterialParams<false>; |
798 | |
799 | MaterialParams::MaterialParams(const HShader& shader, UINT64 initialParamVersion) |
800 | :TMaterialParams(shader, initialParamVersion), mLastSyncVersion(1) |
801 | { } |
802 | |
803 | void MaterialParams::getSyncData(UINT8* buffer, UINT32& size, bool forceAll) |
804 | { |
805 | // Note: Not syncing struct data |
806 | |
807 | UINT32 numDirtyDataParams = 0; |
808 | UINT32 numDirtyStructParams = 0; |
809 | UINT32 numDirtyTextureParams = 0; |
810 | UINT32 numDirtyBufferParams = 0; |
811 | UINT32 numDirtySamplerParams = 0; |
812 | |
813 | UINT32 dataParamSize = 0; |
814 | UINT32 structParamSize = 0; |
815 | for(auto& param : mParams) |
816 | { |
817 | if (param.version <= mLastSyncVersion && !forceAll) |
818 | continue; |
819 | |
820 | switch(param.type) |
821 | { |
822 | case ParamType::Data: |
823 | { |
824 | const UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1; |
825 | |
826 | if(param.dataType == GPDT_STRUCT) |
827 | { |
828 | // Param index |
829 | structParamSize += sizeof(UINT32); |
830 | |
831 | // Param data |
832 | structParamSize += arraySize * mStructParams[param.index].dataSize; |
833 | |
834 | numDirtyStructParams++; |
835 | } |
836 | else |
837 | { |
838 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.dataType]; |
839 | const UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
840 | |
841 | // Param index |
842 | dataParamSize += sizeof(UINT32); |
843 | |
844 | // Param data |
845 | dataParamSize += arraySize * paramSize; |
846 | |
847 | // Param curves |
848 | dataParamSize += sizeof(UINT32); |
849 | for (UINT32 i = 0; i < arraySize; i++) |
850 | { |
851 | const DataParamInfo& paramInfo = mDataParams[param.index + i]; |
852 | if (paramInfo.floatCurve && param.dataType == GPDT_FLOAT1) |
853 | { |
854 | // Array index |
855 | dataParamSize += sizeof(UINT32); |
856 | |
857 | // Curve data |
858 | dataParamSize += rttiGetElemSize(*paramInfo.floatCurve); |
859 | } |
860 | else if (paramInfo.colorGradient && param.dataType == GPDT_COLOR) |
861 | { |
862 | // Array index |
863 | dataParamSize += sizeof(UINT32); |
864 | |
865 | // Curve data |
866 | dataParamSize += rttiGetElemSize(*paramInfo.colorGradient); |
867 | } |
868 | } |
869 | |
870 | numDirtyDataParams++; |
871 | } |
872 | } |
873 | break; |
874 | case ParamType::Texture: |
875 | numDirtyTextureParams++; |
876 | break; |
877 | case ParamType::Buffer: |
878 | numDirtyBufferParams++; |
879 | break; |
880 | case ParamType::Sampler: |
881 | numDirtySamplerParams++; |
882 | break; |
883 | } |
884 | } |
885 | |
886 | const UINT32 textureEntrySize = sizeof(MaterialParamTextureDataCore) + sizeof(UINT32); |
887 | const UINT32 bufferEntrySize = sizeof(MaterialParamBufferDataCore) + sizeof(UINT32); |
888 | const UINT32 samplerStateEntrySize = sizeof(MaterialParamSamplerStateDataCore) + sizeof(UINT32); |
889 | |
890 | const UINT32 dataParamsOffset = sizeof(UINT32) * 5; |
891 | const UINT32 textureParamsOffset = dataParamsOffset + dataParamSize; |
892 | const UINT32 bufferParamsOffset = textureParamsOffset + textureEntrySize * numDirtyTextureParams; |
893 | const UINT32 samplerStateParamsOffset = bufferParamsOffset + bufferEntrySize * numDirtyBufferParams; |
894 | const UINT32 structParamsOffset = samplerStateParamsOffset + samplerStateEntrySize * numDirtySamplerParams; |
895 | |
896 | const UINT32 totalSize = structParamsOffset + structParamSize; |
897 | |
898 | if (buffer == nullptr) |
899 | { |
900 | size = totalSize; |
901 | return; |
902 | } |
903 | |
904 | if(size != totalSize) |
905 | { |
906 | LOGERR("Invalid buffer size provided, ignoring." ); |
907 | return; |
908 | } |
909 | |
910 | char* writeDest = (char*)buffer; |
911 | |
912 | // Dirty counts for each parameter type |
913 | writeDest = rttiWriteElem(numDirtyDataParams, writeDest); |
914 | writeDest = rttiWriteElem(numDirtyTextureParams, writeDest); |
915 | writeDest = rttiWriteElem(numDirtyBufferParams, writeDest); |
916 | writeDest = rttiWriteElem(numDirtySamplerParams, writeDest); |
917 | writeDest = rttiWriteElem(numDirtyStructParams, writeDest); |
918 | |
919 | UINT32 dirtyDataParamOffset = 0; |
920 | UINT32 dirtyTextureParamIdx = 0; |
921 | UINT32 dirtyBufferParamIdx = 0; |
922 | UINT32 dirtySamplerParamIdx = 0; |
923 | UINT32 dirtyStructParamOffset = 0; |
924 | |
925 | for(UINT32 i = 0; i < (UINT32)mParams.size(); i++) |
926 | { |
927 | ParamData& param = mParams[i]; |
928 | if (param.version <= mLastSyncVersion && !forceAll) |
929 | continue; |
930 | |
931 | switch (param.type) |
932 | { |
933 | case ParamType::Data: |
934 | { |
935 | const UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1; |
936 | |
937 | if (param.dataType == GPDT_STRUCT) |
938 | { |
939 | const ParamStructDataType& paramData = mStructParams[param.index]; |
940 | |
941 | writeDest = (char*)buffer + structParamsOffset + dirtyStructParamOffset; |
942 | |
943 | // Param index |
944 | writeDest = rttiWriteElem(i, writeDest, dirtyStructParamOffset); |
945 | |
946 | // Param data |
947 | for (UINT32 j = 0; j < arraySize; j++) |
948 | { |
949 | memcpy(writeDest, mStructParams[param.index + j].data, paramData.dataSize); |
950 | writeDest += paramData.dataSize; |
951 | dirtyStructParamOffset += paramData.dataSize; |
952 | } |
953 | } |
954 | else |
955 | { |
956 | const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.dataType]; |
957 | const UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
958 | |
959 | const UINT32 dataSize = arraySize * paramSize; |
960 | const DataParamInfo& paramInfo = mDataParams[param.index]; |
961 | |
962 | writeDest = (char*)buffer + dataParamsOffset + dirtyDataParamOffset; |
963 | |
964 | // Param index |
965 | writeDest = rttiWriteElem(i, writeDest, dirtyDataParamOffset); |
966 | |
967 | // Param data |
968 | // Note: This relies on the fact that all data params in the array are sequential |
969 | memcpy(writeDest, &mDataParamsBuffer[paramInfo.offset], dataSize); |
970 | writeDest += dataSize; |
971 | dirtyDataParamOffset += dataSize; |
972 | |
973 | // Param curves |
974 | UINT32* numDirtyCurvesWriteDst = (UINT32*)writeDest; |
975 | writeDest += sizeof(UINT32); |
976 | dirtyDataParamOffset += sizeof(UINT32); |
977 | |
978 | UINT32 numDirtyCurves = 0; |
979 | for (UINT32 j = 0; j < arraySize; j++) |
980 | { |
981 | const DataParamInfo& arrParamInfo = mDataParams[param.index + j]; |
982 | if (arrParamInfo.floatCurve && param.dataType == GPDT_FLOAT1) |
983 | { |
984 | // Array index |
985 | writeDest = rttiWriteElem(j, writeDest, dirtyDataParamOffset); |
986 | |
987 | // Curve data |
988 | writeDest = rttiWriteElem(*arrParamInfo.floatCurve, writeDest, dirtyDataParamOffset); |
989 | |
990 | numDirtyCurves++; |
991 | } |
992 | else if (arrParamInfo.colorGradient && param.dataType == GPDT_COLOR) |
993 | { |
994 | // Array index |
995 | writeDest = rttiWriteElem(j, writeDest, dirtyDataParamOffset); |
996 | |
997 | // Curve data |
998 | writeDest = rttiWriteElem(*arrParamInfo.colorGradient, writeDest, dirtyDataParamOffset); |
999 | |
1000 | numDirtyCurves++; |
1001 | } |
1002 | } |
1003 | |
1004 | *numDirtyCurvesWriteDst = numDirtyCurves; |
1005 | } |
1006 | } |
1007 | break; |
1008 | case ParamType::Texture: |
1009 | { |
1010 | writeDest = (char*)buffer + textureParamsOffset + dirtyTextureParamIdx * textureEntrySize; |
1011 | writeDest = rttiWriteElem(i, writeDest); |
1012 | |
1013 | const MaterialParamTextureData& textureData = mTextureParams[param.index]; |
1014 | MaterialParamTextureDataCore* coreTexData = (MaterialParamTextureDataCore*)writeDest; |
1015 | new (coreTexData) MaterialParamTextureDataCore(); |
1016 | |
1017 | coreTexData->isLoadStore = textureData.isLoadStore; |
1018 | coreTexData->surface = textureData.surface; |
1019 | |
1020 | if (textureData.texture.isLoaded()) |
1021 | coreTexData->texture = textureData.texture->getCore(); |
1022 | |
1023 | if (textureData.spriteTexture.isLoaded()) |
1024 | coreTexData->spriteTexture = textureData.spriteTexture->getCore(); |
1025 | |
1026 | dirtyTextureParamIdx++; |
1027 | } |
1028 | break; |
1029 | case ParamType::Buffer: |
1030 | { |
1031 | writeDest = (char*)buffer + bufferParamsOffset + dirtyBufferParamIdx * bufferEntrySize; |
1032 | writeDest = rttiWriteElem(i, writeDest); |
1033 | |
1034 | const MaterialParamBufferData& bufferData = mBufferParams[param.index]; |
1035 | MaterialParamBufferDataCore* coreBufferData = (MaterialParamBufferDataCore*)writeDest; |
1036 | new (coreBufferData) MaterialParamBufferDataCore(); |
1037 | |
1038 | if(bufferData.value != nullptr) |
1039 | coreBufferData->value = bufferData.value->getCore(); |
1040 | |
1041 | dirtyBufferParamIdx++; |
1042 | } |
1043 | break; |
1044 | case ParamType::Sampler: |
1045 | { |
1046 | writeDest = (char*)buffer + samplerStateParamsOffset + dirtySamplerParamIdx * samplerStateEntrySize; |
1047 | writeDest = rttiWriteElem(i, writeDest); |
1048 | |
1049 | const MaterialParamSamplerStateData& samplerData = mSamplerStateParams[param.index]; |
1050 | MaterialParamSamplerStateDataCore* coreSamplerData = (MaterialParamSamplerStateDataCore*)writeDest; |
1051 | new (coreSamplerData) MaterialParamSamplerStateDataCore(); |
1052 | |
1053 | if (samplerData.value != nullptr) |
1054 | coreSamplerData->value = samplerData.value->getCore(); |
1055 | |
1056 | dirtySamplerParamIdx++; |
1057 | } |
1058 | break; |
1059 | } |
1060 | } |
1061 | |
1062 | mLastSyncVersion = mParamVersion; |
1063 | } |
1064 | |
1065 | void MaterialParams::getResourceDependencies(Vector<HResource>& resources) |
1066 | { |
1067 | for (UINT32 i = 0; i < (UINT32)mParams.size(); i++) |
1068 | { |
1069 | ParamData& param = mParams[i]; |
1070 | if (param.type != ParamType::Texture) |
1071 | continue; |
1072 | |
1073 | const MaterialParamTextureData& textureData = mTextureParams[param.index]; |
1074 | if (textureData.texture != nullptr) |
1075 | resources.push_back(textureData.texture); |
1076 | |
1077 | if (textureData.spriteTexture != nullptr) |
1078 | resources.push_back(textureData.spriteTexture); |
1079 | } |
1080 | } |
1081 | |
1082 | void MaterialParams::getCoreObjectDependencies(Vector<CoreObject*>& coreObjects) |
1083 | { |
1084 | for (UINT32 i = 0; i < (UINT32)mParams.size(); i++) |
1085 | { |
1086 | ParamData& param = mParams[i]; |
1087 | |
1088 | switch (param.type) |
1089 | { |
1090 | case ParamType::Texture: |
1091 | { |
1092 | const MaterialParamTextureData& textureData = mTextureParams[param.index]; |
1093 | |
1094 | if (textureData.texture.isLoaded()) |
1095 | coreObjects.push_back(textureData.texture.get()); |
1096 | |
1097 | if (textureData.spriteTexture.isLoaded()) |
1098 | coreObjects.push_back(textureData.spriteTexture.get()); |
1099 | } |
1100 | break; |
1101 | case ParamType::Buffer: |
1102 | { |
1103 | const MaterialParamBufferData& bufferData = mBufferParams[param.index]; |
1104 | |
1105 | if (bufferData.value != nullptr) |
1106 | coreObjects.push_back(bufferData.value.get()); |
1107 | } |
1108 | break; |
1109 | case ParamType::Sampler: |
1110 | { |
1111 | |
1112 | const MaterialParamSamplerStateData& samplerData = mSamplerStateParams[param.index]; |
1113 | |
1114 | if (samplerData.value != nullptr) |
1115 | coreObjects.push_back(samplerData.value.get()); |
1116 | } |
1117 | break; |
1118 | default: |
1119 | break; |
1120 | } |
1121 | } |
1122 | } |
1123 | |
1124 | RTTITypeBase* MaterialParams::getRTTIStatic() |
1125 | { |
1126 | return MaterialParamsRTTI::instance(); |
1127 | } |
1128 | |
1129 | RTTITypeBase* MaterialParams::getRTTI() const |
1130 | { |
1131 | return MaterialParams::getRTTIStatic(); |
1132 | } |
1133 | |
1134 | namespace ct |
1135 | { |
1136 | MaterialParams::MaterialParams(const SPtr<Shader>& shader, UINT64 initialParamVersion) |
1137 | :TMaterialParams(shader, initialParamVersion) |
1138 | { } |
1139 | |
1140 | MaterialParams::MaterialParams(const SPtr<Shader>& shader, const SPtr<bs::MaterialParams>& params) |
1141 | : TMaterialParams(shader, 1) |
1142 | { |
1143 | memcpy(mDataParamsBuffer, params->mDataParamsBuffer, mDataSize); |
1144 | |
1145 | for (auto& param : mParams) |
1146 | { |
1147 | switch (param.type) |
1148 | { |
1149 | case ParamType::Data: |
1150 | { |
1151 | const UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1; |
1152 | |
1153 | if(param.dataType == GPDT_STRUCT) |
1154 | { |
1155 | for (UINT32 i = 0; i < arraySize; i++) |
1156 | { |
1157 | const MaterialParamStructData& srcParamInfo = params->mStructParams[param.index + i]; |
1158 | MaterialParamStructDataCore& dstParamInfo = mStructParams[param.index + i]; |
1159 | |
1160 | memcpy(dstParamInfo.data, srcParamInfo.data, srcParamInfo.dataSize); |
1161 | } |
1162 | } |
1163 | else |
1164 | { |
1165 | for (UINT32 i = 0; i < arraySize; i++) |
1166 | { |
1167 | DataParamInfo& srcParamInfo = params->mDataParams[param.index + i]; |
1168 | DataParamInfo& dstParamInfo = mDataParams[param.index + i]; |
1169 | |
1170 | if (srcParamInfo.floatCurve) |
1171 | dstParamInfo.floatCurve = bs_pool_new<TAnimationCurve<float>>(*srcParamInfo.floatCurve); |
1172 | |
1173 | if (srcParamInfo.colorGradient) |
1174 | dstParamInfo.colorGradient = bs_pool_new<ColorGradient>(*srcParamInfo.colorGradient); |
1175 | } |
1176 | } |
1177 | } |
1178 | break; |
1179 | case ParamType::Texture: |
1180 | { |
1181 | HTexture texture = params->mTextureParams[param.index].texture; |
1182 | SPtr<Texture> textureCore; |
1183 | if (texture.isLoaded()) |
1184 | textureCore = texture->getCore(); |
1185 | |
1186 | mTextureParams[param.index].texture = textureCore; |
1187 | |
1188 | HSpriteTexture spriteTexture = params->mTextureParams[param.index].spriteTexture; |
1189 | SPtr<SpriteTexture> spriteTextureCore; |
1190 | if (spriteTexture.isLoaded()) |
1191 | spriteTextureCore = spriteTexture->getCore(); |
1192 | |
1193 | mTextureParams[param.index].spriteTexture = spriteTextureCore; |
1194 | |
1195 | mTextureParams[param.index].isLoadStore = params->mTextureParams[param.index].isLoadStore; |
1196 | mTextureParams[param.index].surface = params->mTextureParams[param.index].surface; |
1197 | } |
1198 | break; |
1199 | case ParamType::Buffer: |
1200 | { |
1201 | SPtr<bs::GpuBuffer> buffer = params->mBufferParams[param.index].value; |
1202 | SPtr<GpuBuffer> bufferCore; |
1203 | if (buffer != nullptr) |
1204 | bufferCore = buffer->getCore(); |
1205 | |
1206 | mBufferParams[param.index].value = bufferCore; |
1207 | } |
1208 | break; |
1209 | case ParamType::Sampler: |
1210 | { |
1211 | SPtr<bs::SamplerState> sampState = params->mSamplerStateParams[param.index].value; |
1212 | SPtr<SamplerState> sampStateCore; |
1213 | if (sampState != nullptr) |
1214 | sampStateCore = sampState->getCore(); |
1215 | |
1216 | mSamplerStateParams[param.index].value = sampStateCore; |
1217 | } |
1218 | break; |
1219 | default: |
1220 | break; |
1221 | } |
1222 | } |
1223 | } |
1224 | |
1225 | void MaterialParams::setSyncData(UINT8* buffer, UINT32 size) |
1226 | { |
1227 | char* sourceData = (char*)buffer; |
1228 | |
1229 | UINT32 numDirtyDataParams = 0; |
1230 | UINT32 numDirtyTextureParams = 0; |
1231 | UINT32 numDirtyBufferParams = 0; |
1232 | UINT32 numDirtySamplerParams = 0; |
1233 | UINT32 numDirtyStructParams = 0; |
1234 | |
1235 | sourceData = rttiReadElem(numDirtyDataParams, sourceData); |
1236 | sourceData = rttiReadElem(numDirtyTextureParams, sourceData); |
1237 | sourceData = rttiReadElem(numDirtyBufferParams, sourceData); |
1238 | sourceData = rttiReadElem(numDirtySamplerParams, sourceData); |
1239 | sourceData = rttiReadElem(numDirtyStructParams, sourceData); |
1240 | |
1241 | mParamVersion++; |
1242 | |
1243 | for(UINT32 i = 0; i < numDirtyDataParams; i++) |
1244 | { |
1245 | // Param index |
1246 | UINT32 paramIdx = 0; |
1247 | sourceData = rttiReadElem(paramIdx, sourceData); |
1248 | |
1249 | ParamData& param = mParams[paramIdx]; |
1250 | param.version = mParamVersion; |
1251 | |
1252 | const UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1; |
1253 | const GpuParamDataTypeInfo& typeInfo = bs::GpuParams::PARAM_SIZES.lookup[(int)param.dataType]; |
1254 | const UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize; |
1255 | |
1256 | const DataParamInfo& paramInfo = mDataParams[param.index]; |
1257 | |
1258 | const UINT32 dataParamSize = arraySize * paramSize; |
1259 | |
1260 | // Param data |
1261 | // Note: This relies on the fact that all data params in the array are sequential |
1262 | memcpy(&mDataParamsBuffer[paramInfo.offset], sourceData, dataParamSize); |
1263 | sourceData += dataParamSize; |
1264 | |
1265 | // Param curves |
1266 | UINT32 numDirtyCurves = 0; |
1267 | sourceData = rttiReadElem(numDirtyCurves, sourceData); |
1268 | for(UINT32 j = 0; j < numDirtyCurves; j++) |
1269 | { |
1270 | UINT32 localIdx = 0; |
1271 | sourceData = rttiReadElem(localIdx, sourceData); |
1272 | |
1273 | DataParamInfo& arrParamInfo = mDataParams[param.index + localIdx]; |
1274 | if (param.dataType == GPDT_FLOAT1) |
1275 | { |
1276 | if(arrParamInfo.floatCurve) |
1277 | bs_pool_free(arrParamInfo.floatCurve); |
1278 | |
1279 | arrParamInfo.floatCurve = bs_pool_new<TAnimationCurve<float>>(); |
1280 | sourceData = rttiReadElem(*arrParamInfo.floatCurve, sourceData); |
1281 | } |
1282 | else if (param.dataType == GPDT_COLOR) |
1283 | { |
1284 | if(arrParamInfo.colorGradient) |
1285 | bs_pool_free(arrParamInfo.colorGradient); |
1286 | |
1287 | arrParamInfo.colorGradient = bs_pool_new<ColorGradient>(); |
1288 | sourceData = rttiReadElem(*arrParamInfo.colorGradient, sourceData); |
1289 | } |
1290 | } |
1291 | } |
1292 | |
1293 | for(UINT32 i = 0; i < numDirtyTextureParams; i++) |
1294 | { |
1295 | UINT32 paramIdx = 0; |
1296 | sourceData = rttiReadElem(paramIdx, sourceData); |
1297 | |
1298 | ParamData& param = mParams[paramIdx]; |
1299 | param.version = mParamVersion; |
1300 | |
1301 | MaterialParamTextureDataCore* sourceTexData = (MaterialParamTextureDataCore*)sourceData; |
1302 | sourceData += sizeof(MaterialParamTextureDataCore); |
1303 | |
1304 | mTextureParams[param.index] = *sourceTexData; |
1305 | sourceTexData->~MaterialParamTextureDataCore(); |
1306 | } |
1307 | |
1308 | for (UINT32 i = 0; i < numDirtyBufferParams; i++) |
1309 | { |
1310 | UINT32 paramIdx = 0; |
1311 | sourceData = rttiReadElem(paramIdx, sourceData); |
1312 | |
1313 | ParamData& param = mParams[paramIdx]; |
1314 | param.version = mParamVersion; |
1315 | |
1316 | MaterialParamBufferDataCore* sourceBufferData = (MaterialParamBufferDataCore*)sourceData; |
1317 | sourceData += sizeof(MaterialParamBufferDataCore); |
1318 | |
1319 | mBufferParams[param.index] = *sourceBufferData; |
1320 | sourceBufferData->~MaterialParamBufferDataCore(); |
1321 | } |
1322 | |
1323 | for (UINT32 i = 0; i < numDirtySamplerParams; i++) |
1324 | { |
1325 | UINT32 paramIdx = 0; |
1326 | sourceData = rttiReadElem(paramIdx, sourceData); |
1327 | |
1328 | ParamData& param = mParams[paramIdx]; |
1329 | param.version = mParamVersion; |
1330 | |
1331 | MaterialParamSamplerStateDataCore* sourceSamplerStateData = (MaterialParamSamplerStateDataCore*)sourceData; |
1332 | sourceData += sizeof(MaterialParamSamplerStateDataCore); |
1333 | |
1334 | mSamplerStateParams[param.index] = *sourceSamplerStateData; |
1335 | sourceSamplerStateData->~MaterialParamSamplerStateDataCore(); |
1336 | } |
1337 | |
1338 | for(UINT32 i = 0; i < numDirtyStructParams; i++) |
1339 | { |
1340 | // Param index |
1341 | UINT32 paramIdx = 0; |
1342 | sourceData = rttiReadElem(paramIdx, sourceData); |
1343 | |
1344 | ParamData& param = mParams[paramIdx]; |
1345 | param.version = mParamVersion; |
1346 | |
1347 | const UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1; |
1348 | const ParamStructDataType& paramData = mStructParams[param.index]; |
1349 | |
1350 | // Param data |
1351 | for (UINT32 j = 0; j < arraySize; j++) |
1352 | { |
1353 | memcpy(mStructParams[param.index + j].data, sourceData, paramData.dataSize); |
1354 | sourceData += paramData.dataSize; |
1355 | } |
1356 | } |
1357 | } |
1358 | } |
1359 | } |
1360 | |