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 "RenderAPI/BsGpuParams.h"
4#include "RenderAPI/BsGpuParamDesc.h"
5#include "RenderAPI/BsGpuParamBlockBuffer.h"
6#include "RenderAPI/BsGpuPipelineParamInfo.h"
7#include "RenderAPI/BsGpuPipelineState.h"
8#include "Math/BsVector2.h"
9#include "Image/BsTexture.h"
10#include "RenderAPI/BsGpuBuffer.h"
11#include "RenderAPI/BsSamplerState.h"
12#include "Debug/BsDebug.h"
13#include "Error/BsException.h"
14#include "Math/BsVector3I.h"
15#include "Math/BsVector4I.h"
16#include "Math/BsMatrixNxM.h"
17#include "Managers/BsHardwareBufferManager.h"
18
19namespace bs
20{
21 const TextureSurface TextureSurface::COMPLETE = TextureSurface(0, 0, 0, 0);
22
23 GpuParamsBase::GpuParamsBase(const SPtr<GpuPipelineParamInfoBase>& paramInfo)
24 :mParamInfo(paramInfo)
25 { }
26
27 SPtr<GpuParamDesc> GpuParamsBase::getParamDesc(GpuProgramType type) const
28 {
29 return mParamInfo->getParamDesc(type);
30 }
31
32 UINT32 GpuParamsBase::getDataParamSize(GpuProgramType type, const String& name) const
33 {
34 GpuParamDataDesc* desc = getParamDesc(type, name);
35 if(desc != nullptr)
36 return desc->elementSize * 4;
37
38 return 0;
39 }
40
41 bool GpuParamsBase::hasParam(GpuProgramType type, const String& name) const
42 {
43 return getParamDesc(type, name) != nullptr;
44 }
45
46 bool GpuParamsBase::hasTexture(GpuProgramType type, const String& name) const
47 {
48 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
49 if (paramDesc == nullptr)
50 return false;
51
52 auto paramIter = paramDesc->textures.find(name);
53 if(paramIter != paramDesc->textures.end())
54 return true;
55
56 return false;
57 }
58
59 bool GpuParamsBase::hasBuffer(GpuProgramType type, const String& name) const
60 {
61 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
62 if (paramDesc == nullptr)
63 return false;
64
65 auto paramIter = paramDesc->buffers.find(name);
66 if (paramIter != paramDesc->buffers.end())
67 return true;
68
69 return false;
70 }
71
72 bool GpuParamsBase::hasLoadStoreTexture(GpuProgramType type, const String& name) const
73 {
74 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
75 if (paramDesc == nullptr)
76 return false;
77
78 auto paramIter = paramDesc->loadStoreTextures.find(name);
79 if (paramIter != paramDesc->loadStoreTextures.end())
80 return true;
81
82 return false;
83 }
84
85 bool GpuParamsBase::hasSamplerState(GpuProgramType type, const String& name) const
86 {
87 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
88 if (paramDesc == nullptr)
89 return false;
90
91 auto paramIter = paramDesc->samplers.find(name);
92 if(paramIter != paramDesc->samplers.end())
93 return true;
94
95 return false;
96 }
97
98 bool GpuParamsBase::hasParamBlock(GpuProgramType type, const String& name) const
99 {
100 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
101 if (paramDesc == nullptr)
102 return false;
103
104 auto paramBlockIter = paramDesc->paramBlocks.find(name);
105 if(paramBlockIter != paramDesc->paramBlocks.end())
106 return true;
107
108 return false;
109 }
110
111 GpuParamDataDesc* GpuParamsBase::getParamDesc(GpuProgramType type, const String& name) const
112 {
113 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
114 if (paramDesc == nullptr)
115 return nullptr;
116
117 auto paramIter = paramDesc->params.find(name);
118 if (paramIter != paramDesc->params.end())
119 return &paramIter->second;
120
121 return nullptr;
122 }
123
124 GpuParamBlockDesc* GpuParamsBase::getParamBlockDesc(GpuProgramType type, const String& name) const
125 {
126 const SPtr<GpuParamDesc>& paramDesc = mParamInfo->getParamDesc(type);
127 if (paramDesc == nullptr)
128 return nullptr;
129
130 auto paramBlockIter = paramDesc->paramBlocks.find(name);
131 if (paramBlockIter != paramDesc->paramBlocks.end())
132 return &paramBlockIter->second;
133
134 return nullptr;
135 }
136
137 template<bool Core>
138 TGpuParams<Core>::TGpuParams(const SPtr<GpuPipelineParamInfoBase>& paramInfo)
139 : GpuParamsBase(paramInfo)
140 {
141 UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock);
142 UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture);
143 UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture);
144 UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
145 UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
146
147 UINT32 paramBlocksSize = sizeof(ParamsBufferType) * numParamBlocks;
148 UINT32 texturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numTextures;
149 UINT32 loadStoreTexturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numStorageTextures;
150 UINT32 buffersSize = sizeof(BufferType) * numBuffers;
151 UINT32 samplerStatesSize = sizeof(SamplerType) * numSamplers;
152
153 UINT32 totalSize = paramBlocksSize + texturesSize + loadStoreTexturesSize + buffersSize + samplerStatesSize;
154
155 UINT8* data = (UINT8*)bs_alloc(totalSize);
156 mParamBlockBuffers = (ParamsBufferType*)data;
157 for (UINT32 i = 0; i < numParamBlocks; i++)
158 new (&mParamBlockBuffers[i]) ParamsBufferType();
159
160 data += paramBlocksSize;
161 mSampledTextureData = (TextureData*)data;
162 for (UINT32 i = 0; i < numTextures; i++)
163 {
164 new (&mSampledTextureData[i].texture) TextureType();
165 new (&mSampledTextureData[i].surface) TextureSurface(0, 0, 0, 0);
166 }
167
168 data += texturesSize;
169 mLoadStoreTextureData = (TextureData*)data;
170 for (UINT32 i = 0; i < numStorageTextures; i++)
171 {
172 new (&mLoadStoreTextureData[i].texture) TextureType();
173 new (&mLoadStoreTextureData[i].surface) TextureSurface(0, 0, 0, 0);
174 }
175
176 data += loadStoreTexturesSize;
177 mBuffers = (BufferType*)data;
178 for (UINT32 i = 0; i < numBuffers; i++)
179 new (&mBuffers[i]) BufferType();
180
181 data += buffersSize;
182 mSamplerStates = (SamplerType*)data;
183 for (UINT32 i = 0; i < numSamplers; i++)
184 new (&mSamplerStates[i]) SamplerType();
185
186 data += samplerStatesSize;
187 }
188
189 template<bool Core>
190 TGpuParams<Core>::~TGpuParams()
191 {
192 UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock);
193 UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture);
194 UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture);
195 UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
196 UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
197
198 for (UINT32 i = 0; i < numParamBlocks; i++)
199 mParamBlockBuffers[i].~ParamsBufferType();
200
201 for (UINT32 i = 0; i < numTextures; i++)
202 {
203 mSampledTextureData[i].texture.~TextureType();
204 mSampledTextureData[i].surface.~TextureSurface();
205 }
206
207 for (UINT32 i = 0; i < numStorageTextures; i++)
208 {
209 mLoadStoreTextureData[i].texture.~TextureType();
210 mLoadStoreTextureData[i].surface.~TextureSurface();
211 }
212
213 for (UINT32 i = 0; i < numBuffers; i++)
214 mBuffers[i].~BufferType();
215
216 for (UINT32 i = 0; i < numSamplers; i++)
217 mSamplerStates[i].~SamplerType();
218
219 // Everything is allocated in a single block, so it's enough to free the first element
220 bs_free(mParamBlockBuffers);
221 }
222
223 template<bool Core>
224 void TGpuParams<Core>::setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer)
225 {
226 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::ParamBlock, set, slot);
227 if (globalSlot == (UINT32)-1)
228 return;
229
230 mParamBlockBuffers[globalSlot] = paramBlockBuffer;
231
232 _markCoreDirty();
233 }
234
235 template<bool Core>
236 void TGpuParams<Core>::setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer)
237 {
238 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
239 if(paramDescs == nullptr)
240 {
241 LOGWRN("Cannot find parameter block with the name: '" + name + "'");
242 return;
243 }
244
245 auto iterFind = paramDescs->paramBlocks.find(name);
246 if (iterFind == paramDescs->paramBlocks.end())
247 {
248 LOGWRN("Cannot find parameter block with the name: '" + name + "'");
249 return;
250 }
251
252 setParamBlockBuffer(iterFind->second.set, iterFind->second.slot, paramBlockBuffer);
253 }
254
255 template<bool Core>
256 void TGpuParams<Core>::setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer)
257 {
258 for (UINT32 i = 0; i < 6; i++)
259 {
260 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc((GpuProgramType)i);
261 if (paramDescs == nullptr)
262 continue;
263
264 auto iterFind = paramDescs->paramBlocks.find(name);
265 if (iterFind == paramDescs->paramBlocks.end())
266 continue;
267
268 setParamBlockBuffer(iterFind->second.set, iterFind->second.slot, paramBlockBuffer);
269 }
270 }
271
272 template<bool Core>
273 template<class T>
274 void TGpuParams<Core>::getParam(GpuProgramType type, const String& name, TGpuDataParam<T, Core>& output) const
275 {
276 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
277 if (paramDescs == nullptr)
278 {
279 output = TGpuDataParam<T, Core>(nullptr, nullptr);
280 LOGWRN("Cannot find parameter block with the name: '" + name + "'");
281 return;
282 }
283
284 auto iterFind = paramDescs->params.find(name);
285 if (iterFind == paramDescs->params.end())
286 {
287 output = TGpuDataParam<T, Core>(nullptr, nullptr);
288 LOGWRN("Cannot find parameter with the name '" + name + "'");
289 }
290 else
291 output = TGpuDataParam<T, Core>(&iterFind->second, _getThisPtr());
292 }
293
294 template<bool Core>
295 void TGpuParams<Core>::getStructParam(GpuProgramType type, const String& name, TGpuParamStruct<Core>& output) const
296 {
297 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
298 if (paramDescs == nullptr)
299 {
300 output = TGpuParamStruct<Core>(nullptr, nullptr);
301 LOGWRN("Cannot find struct parameter with the name: '" + name + "'");
302 return;
303 }
304
305 auto iterFind = paramDescs->params.find(name);
306 if (iterFind == paramDescs->params.end() || iterFind->second.type != GPDT_STRUCT)
307 {
308 output = TGpuParamStruct<Core>(nullptr, nullptr);
309 LOGWRN("Cannot find struct parameter with the name '" + name + "'");
310 }
311 else
312 output = TGpuParamStruct<Core>(&iterFind->second, _getThisPtr());
313 }
314
315 template<bool Core>
316 void TGpuParams<Core>::getTextureParam(GpuProgramType type, const String& name, TGpuParamTexture<Core>& output) const
317 {
318 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
319 if (paramDescs == nullptr)
320 {
321 output = TGpuParamTexture<Core>(nullptr, nullptr);
322 LOGWRN("Cannot find texture parameter with the name: '" + name + "'");
323 return;
324 }
325
326 auto iterFind = paramDescs->textures.find(name);
327 if (iterFind == paramDescs->textures.end())
328 {
329 output = TGpuParamTexture<Core>(nullptr, nullptr);
330 LOGWRN("Cannot find texture parameter with the name '" + name + "'");
331 }
332 else
333 output = TGpuParamTexture<Core>(&iterFind->second, _getThisPtr());
334 }
335
336 template<bool Core>
337 void TGpuParams<Core>::getLoadStoreTextureParam(GpuProgramType type, const String& name, TGpuParamLoadStoreTexture<Core>& output) const
338 {
339 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
340 if (paramDescs == nullptr)
341 {
342 output = TGpuParamLoadStoreTexture<Core>(nullptr, nullptr);
343 LOGWRN("Cannot find texture parameter with the name: '" + name + "'");
344 return;
345 }
346
347 auto iterFind = paramDescs->loadStoreTextures.find(name);
348 if (iterFind == paramDescs->loadStoreTextures.end())
349 {
350 output = TGpuParamLoadStoreTexture<Core>(nullptr, nullptr);
351 LOGWRN("Cannot find texture parameter with the name '" + name + "'");
352 }
353 else
354 output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, _getThisPtr());
355 }
356
357 template<bool Core>
358 void TGpuParams<Core>::getBufferParam(GpuProgramType type, const String& name, TGpuParamBuffer<Core>& output) const
359 {
360 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
361 if (paramDescs == nullptr)
362 {
363 output = TGpuParamBuffer<Core>(nullptr, nullptr);
364 LOGWRN("Cannot find buffer parameter with the name: '" + name + "'");
365 return;
366 }
367
368 auto iterFind = paramDescs->buffers.find(name);
369 if (iterFind == paramDescs->buffers.end())
370 {
371 output = TGpuParamBuffer<Core>(nullptr, nullptr);
372 LOGWRN("Cannot find buffer parameter with the name '" + name + "'");
373 }
374 else
375 output = TGpuParamBuffer<Core>(&iterFind->second, _getThisPtr());
376 }
377
378 template<bool Core>
379 void TGpuParams<Core>::getSamplerStateParam(GpuProgramType type, const String& name, TGpuParamSampState<Core>& output) const
380 {
381 const SPtr<GpuParamDesc>& paramDescs = mParamInfo->getParamDesc(type);
382 if (paramDescs == nullptr)
383 {
384 output = TGpuParamSampState<Core>(nullptr, nullptr);
385 LOGWRN("Cannot find sampler state parameter with the name: '" + name + "'");
386 return;
387 }
388
389 auto iterFind = paramDescs->samplers.find(name);
390 if (iterFind == paramDescs->samplers.end())
391 {
392 output = TGpuParamSampState<Core>(nullptr, nullptr);
393 LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
394 }
395 else
396 output = TGpuParamSampState<Core>(&iterFind->second, _getThisPtr());
397 }
398
399 template<bool Core>
400 typename TGpuParams<Core>::ParamsBufferType TGpuParams<Core>::getParamBlockBuffer(UINT32 set, UINT32 slot) const
401 {
402 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::ParamBlock, set, slot);
403 if (globalSlot == (UINT32)-1)
404 return nullptr;
405
406 return mParamBlockBuffers[globalSlot];
407 }
408
409 template<bool Core>
410 typename TGpuParams<Core>::TextureType TGpuParams<Core>::getTexture(UINT32 set, UINT32 slot) const
411 {
412 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
413 if (globalSlot == (UINT32)-1)
414 return TGpuParams<Core>::TextureType();
415
416 return mSampledTextureData[globalSlot].texture;
417 }
418
419 template<bool Core>
420 typename TGpuParams<Core>::TextureType TGpuParams<Core>::getLoadStoreTexture(UINT32 set, UINT32 slot) const
421 {
422 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot);
423 if (globalSlot == (UINT32)-1)
424 return TGpuParams<Core>::TextureType();
425
426 return mLoadStoreTextureData[globalSlot].texture;
427 }
428
429 template<bool Core>
430 typename TGpuParams<Core>::BufferType TGpuParams<Core>::getBuffer(UINT32 set, UINT32 slot) const
431 {
432 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Buffer, set, slot);
433 if (globalSlot == (UINT32)-1)
434 return nullptr;
435
436 return mBuffers[globalSlot];
437 }
438
439 template<bool Core>
440 typename TGpuParams<Core>::SamplerType TGpuParams<Core>::getSamplerState(UINT32 set, UINT32 slot) const
441 {
442 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::SamplerState, set, slot);
443 if (globalSlot == (UINT32)-1)
444 return nullptr;
445
446 return mSamplerStates[globalSlot];
447 }
448
449 template<bool Core>
450 const TextureSurface& TGpuParams<Core>::getTextureSurface(UINT32 set, UINT32 slot) const
451 {
452 static TextureSurface emptySurface;
453
454 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
455 if (globalSlot == (UINT32)-1)
456 return emptySurface;
457
458 return mSampledTextureData[globalSlot].surface;
459 }
460
461 template<bool Core>
462 const TextureSurface& TGpuParams<Core>::getLoadStoreSurface(UINT32 set, UINT32 slot) const
463 {
464 static TextureSurface emptySurface;
465
466 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot);
467 if (globalSlot == (UINT32)-1)
468 return emptySurface;
469
470 return mLoadStoreTextureData[globalSlot].surface;
471 }
472
473
474 template<bool Core>
475 void TGpuParams<Core>::setTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface)
476 {
477 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
478 if (globalSlot == (UINT32)-1)
479 return;
480
481 mSampledTextureData[globalSlot].texture = texture;
482 mSampledTextureData[globalSlot].surface = surface;
483
484 _markResourcesDirty();
485 _markCoreDirty();
486 }
487
488 template<bool Core>
489 void TGpuParams<Core>::setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface)
490 {
491 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot);
492 if (globalSlot == (UINT32)-1)
493 return;
494
495 mLoadStoreTextureData[globalSlot].texture = texture;
496 mLoadStoreTextureData[globalSlot].surface = surface;
497
498 _markResourcesDirty();
499 _markCoreDirty();
500 }
501
502 template<bool Core>
503 void TGpuParams<Core>::setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer)
504 {
505 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Buffer, set, slot);
506 if (globalSlot == (UINT32)-1)
507 return;
508
509 mBuffers[globalSlot] = buffer;
510
511 _markResourcesDirty();
512 _markCoreDirty();
513 }
514
515 template<bool Core>
516 void TGpuParams<Core>::setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler)
517 {
518 UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::SamplerState, set, slot);
519 if (globalSlot == (UINT32)-1)
520 return;
521
522 mSamplerStates[globalSlot] = sampler;
523
524 _markResourcesDirty();
525 _markCoreDirty();
526 }
527
528 template class TGpuParams < false > ;
529 template class TGpuParams < true > ;
530
531 template BS_CORE_EXPORT void TGpuParams<false>::getParam<float>(GpuProgramType type, const String&, TGpuDataParam<float, false>&) const;
532 template BS_CORE_EXPORT void TGpuParams<false>::getParam<int>(GpuProgramType type, const String&, TGpuDataParam<int, false>&) const;
533 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Color>(GpuProgramType type, const String&, TGpuDataParam<Color, false>&) const;
534 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2>(GpuProgramType type, const String&, TGpuDataParam<Vector2, false>&) const;
535 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3>(GpuProgramType type, const String&, TGpuDataParam<Vector3, false>&) const;
536 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4>(GpuProgramType type, const String&, TGpuDataParam<Vector4, false>&) const;
537 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2I>(GpuProgramType type, const String&, TGpuDataParam<Vector2I, false>&) const;
538 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3I>(GpuProgramType type, const String&, TGpuDataParam<Vector3I, false>&) const;
539 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4I>(GpuProgramType type, const String&, TGpuDataParam<Vector4I, false>&) const;
540 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2>(GpuProgramType type, const String&, TGpuDataParam<Matrix2, false>&) const;
541 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x3, false>&) const;
542 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x4, false>&) const;
543 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3>(GpuProgramType type, const String&, TGpuDataParam<Matrix3, false>&) const;
544 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x2, false>&) const;
545 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x4, false>&) const;
546 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4>(GpuProgramType type, const String&, TGpuDataParam<Matrix4, false>&) const;
547 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x2, false>&) const;
548 template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x3, false>&) const;
549
550 template BS_CORE_EXPORT void TGpuParams<true>::getParam<float>(GpuProgramType type, const String&, TGpuDataParam<float, true>&) const;
551 template BS_CORE_EXPORT void TGpuParams<true>::getParam<int>(GpuProgramType type, const String&, TGpuDataParam<int, true>&) const;
552 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Color>(GpuProgramType type, const String&, TGpuDataParam<Color, true>&) const;
553 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2>(GpuProgramType type, const String&, TGpuDataParam<Vector2, true>&) const;
554 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3>(GpuProgramType type, const String&, TGpuDataParam<Vector3, true>&) const;
555 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4>(GpuProgramType type, const String&, TGpuDataParam<Vector4, true>&) const;
556 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2I>(GpuProgramType type, const String&, TGpuDataParam<Vector2I, true>&) const;
557 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3I>(GpuProgramType type, const String&, TGpuDataParam<Vector3I, true>&) const;
558 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4I>(GpuProgramType type, const String&, TGpuDataParam<Vector4I, true>&) const;
559 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2>(GpuProgramType type, const String&, TGpuDataParam<Matrix2, true>&) const;
560 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x3, true>&) const;
561 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x4, true>&) const;
562 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3>(GpuProgramType type, const String&, TGpuDataParam<Matrix3, true>&) const;
563 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x2, true>&) const;
564 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x4, true>&) const;
565 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4>(GpuProgramType type, const String&, TGpuDataParam<Matrix4, true>&) const;
566 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x2, true>&) const;
567 template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x3, true>&) const;
568
569 const GpuDataParamInfos GpuParams::PARAM_SIZES;
570
571 GpuParams::GpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo)
572 : TGpuParams(paramInfo)
573 {
574
575 }
576
577 SPtr<GpuParams> GpuParams::_getThisPtr() const
578 {
579 return std::static_pointer_cast<GpuParams>(getThisPtr());
580 }
581
582 SPtr<ct::GpuParams> GpuParams::getCore() const
583 {
584 return std::static_pointer_cast<ct::GpuParams>(mCoreSpecific);
585 }
586
587 SPtr<ct::CoreObject> GpuParams::createCore() const
588 {
589 SPtr<GpuPipelineParamInfo> paramInfo = std::static_pointer_cast<GpuPipelineParamInfo>(mParamInfo);
590
591 return ct::HardwareBufferManager::instance().createGpuParams(paramInfo->getCore());
592 }
593
594 void GpuParams::_markCoreDirty()
595 {
596 markCoreDirty();
597 }
598
599 void GpuParams::_markResourcesDirty()
600 {
601 markListenerResourcesDirty();
602 }
603
604 SPtr<GpuParams> GpuParams::create(const SPtr<GraphicsPipelineState>& pipelineState)
605 {
606 return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo());
607 }
608
609 SPtr<GpuParams> GpuParams::create(const SPtr<ComputePipelineState>& pipelineState)
610 {
611 return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo());
612 }
613
614 SPtr<GpuParams> GpuParams::create(const SPtr<GpuPipelineParamInfo>& paramInfo)
615 {
616 return HardwareBufferManager::instance().createGpuParams(paramInfo);
617 }
618
619 CoreSyncData GpuParams::syncToCore(FrameAlloc* allocator)
620 {
621 UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock);
622 UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture);
623 UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture);
624 UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
625 UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
626
627 UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface);
628 UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
629 UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<ct::GpuParamBlockBuffer>);
630 UINT32 textureArraySize = numTextures * sizeof(SPtr<ct::Texture>);
631 UINT32 loadStoreTextureArraySize = numStorageTextures * sizeof(SPtr<ct::Texture>);
632 UINT32 bufferArraySize = numBuffers * sizeof(SPtr<ct::GpuBuffer>);
633 UINT32 samplerArraySize = numSamplers * sizeof(SPtr<ct::SamplerState>);
634
635 UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize
636 + loadStoreTextureArraySize + bufferArraySize + samplerArraySize;
637
638 UINT32 sampledSurfaceOffset = 0;
639 UINT32 loadStoreSurfaceOffset = sampledSurfaceOffset + sampledSurfacesSize;
640 UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize;
641 UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
642 UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
643 UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
644 UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize;
645
646 UINT8* data = allocator->alloc(totalSize);
647
648 TextureSurface* sampledSurfaces = (TextureSurface*)(data + sampledSurfaceOffset);
649 TextureSurface* loadStoreSurfaces = (TextureSurface*)(data + loadStoreSurfaceOffset);
650 SPtr<ct::GpuParamBlockBuffer>* paramBuffers = (SPtr<ct::GpuParamBlockBuffer>*)(data + paramBufferOffset);
651 SPtr<ct::Texture>* textures = (SPtr<ct::Texture>*)(data + textureArrayOffset);
652 SPtr<ct::Texture>* loadStoreTextures = (SPtr<ct::Texture>*)(data + loadStoreTextureArrayOffset);
653 SPtr<ct::GpuBuffer>* buffers = (SPtr<ct::GpuBuffer>*)(data + bufferArrayOffset);
654 SPtr<ct::SamplerState>* samplers = (SPtr<ct::SamplerState>*)(data + samplerArrayOffset);
655
656 // Construct & copy
657 for (UINT32 i = 0; i < numParamBlocks; i++)
658 {
659 new (&paramBuffers[i]) SPtr<ct::GpuParamBlockBuffer>();
660
661 if (mParamBlockBuffers[i] != nullptr)
662 paramBuffers[i] = mParamBlockBuffers[i]->getCore();
663 }
664
665 for (UINT32 i = 0; i < numTextures; i++)
666 {
667 new (&sampledSurfaces[i]) TextureSurface();
668 sampledSurfaces[i] = mSampledTextureData[i].surface;
669
670 new (&textures[i]) SPtr<ct::Texture>();
671
672 if (mSampledTextureData[i].texture.isLoaded())
673 textures[i] = mSampledTextureData[i].texture->getCore();
674 else
675 textures[i] = nullptr;
676 }
677
678 for (UINT32 i = 0; i < numStorageTextures; i++)
679 {
680 new (&loadStoreSurfaces[i]) TextureSurface();
681 loadStoreSurfaces[i] = mLoadStoreTextureData[i].surface;
682
683 new (&loadStoreTextures[i]) SPtr<ct::Texture>();
684
685 if (mLoadStoreTextureData[i].texture.isLoaded())
686 loadStoreTextures[i] = mLoadStoreTextureData[i].texture->getCore();
687 else
688 loadStoreTextures[i] = nullptr;
689 }
690
691 for (UINT32 i = 0; i < numBuffers; i++)
692 {
693 new (&buffers[i]) SPtr<ct::GpuBuffer>();
694
695 if (mBuffers[i] != nullptr)
696 buffers[i] = mBuffers[i]->getCore();
697 else
698 buffers[i] = nullptr;
699 }
700
701 for (UINT32 i = 0; i < numSamplers; i++)
702 {
703 new (&samplers[i]) SPtr<ct::SamplerState>();
704
705 if (mSamplerStates[i] != nullptr)
706 samplers[i] = mSamplerStates[i]->getCore();
707 else
708 samplers[i] = nullptr;
709 }
710
711 return CoreSyncData(data, totalSize);
712 }
713
714 void GpuParams::getListenerResources(Vector<HResource>& resources)
715 {
716 UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture);
717 UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture);
718
719 for (UINT32 i = 0; i < numTextures; i++)
720 {
721 if (mSampledTextureData[i].texture != nullptr)
722 resources.push_back(mSampledTextureData[i].texture);
723 }
724
725 for (UINT32 i = 0; i < numStorageTextures; i++)
726 {
727 if (mLoadStoreTextureData[i].texture != nullptr)
728 resources.push_back(mLoadStoreTextureData[i].texture);
729 }
730 }
731
732 namespace ct
733 {
734 GpuParams::GpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo, GpuDeviceFlags deviceMask)
735 : TGpuParams(paramInfo)
736 {
737
738 }
739
740 SPtr<GpuParams> GpuParams::_getThisPtr() const
741 {
742 return std::static_pointer_cast<GpuParams>(getThisPtr());
743 }
744
745 void GpuParams::syncToCore(const CoreSyncData& data)
746 {
747 UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock);
748 UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture);
749 UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture);
750 UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
751 UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
752
753 UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface);
754 UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
755 UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<GpuParamBlockBuffer>);
756 UINT32 textureArraySize = numTextures * sizeof(SPtr<Texture>);
757 UINT32 loadStoreTextureArraySize = numStorageTextures * sizeof(SPtr<Texture>);
758 UINT32 bufferArraySize = numBuffers * sizeof(SPtr<GpuBuffer>);
759 UINT32 samplerArraySize = numSamplers * sizeof(SPtr<SamplerState>);
760
761 UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize
762 + loadStoreTextureArraySize + bufferArraySize + samplerArraySize;
763
764 UINT32 sampledSurfacesOffset = 0;
765 UINT32 loadStoreSurfaceOffset = sampledSurfacesOffset + sampledSurfacesSize;
766 UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize;
767 UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
768 UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
769 UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
770 UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize;
771
772 assert(data.getBufferSize() == totalSize);
773
774 UINT8* dataPtr = data.getBuffer();
775
776 TextureSurface* sampledSurfaces = (TextureSurface*)(dataPtr + sampledSurfacesOffset);
777 TextureSurface* loadStoreSurfaces = (TextureSurface*)(dataPtr + loadStoreSurfaceOffset);
778 SPtr<GpuParamBlockBuffer>* paramBuffers = (SPtr<GpuParamBlockBuffer>*)(dataPtr + paramBufferOffset);
779 SPtr<Texture>* textures = (SPtr<Texture>*)(dataPtr + textureArrayOffset);
780 SPtr<Texture>* loadStoreTextures = (SPtr<Texture>*)(dataPtr + loadStoreTextureArrayOffset);
781 SPtr<GpuBuffer>* buffers = (SPtr<GpuBuffer>*)(dataPtr + bufferArrayOffset);
782 SPtr<SamplerState>* samplers = (SPtr<SamplerState>*)(dataPtr + samplerArrayOffset);
783
784 // Copy & destruct
785 for (UINT32 i = 0; i < numParamBlocks; i++)
786 {
787 mParamBlockBuffers[i] = paramBuffers[i];
788 paramBuffers[i].~SPtr<GpuParamBlockBuffer>();
789 }
790
791 for (UINT32 i = 0; i < numTextures; i++)
792 {
793 mSampledTextureData[i].surface = sampledSurfaces[i];
794 loadStoreSurfaces[i].~TextureSurface();
795
796 mSampledTextureData[i].texture = textures[i];
797 textures[i].~SPtr<Texture>();
798 }
799
800 for (UINT32 i = 0; i < numStorageTextures; i++)
801 {
802 mLoadStoreTextureData[i].surface = loadStoreSurfaces[i];
803 loadStoreSurfaces[i].~TextureSurface();
804
805 mLoadStoreTextureData[i].texture = loadStoreTextures[i];
806 loadStoreTextures[i].~SPtr<Texture>();
807 }
808
809 for (UINT32 i = 0; i < numBuffers; i++)
810 {
811 mBuffers[i] = buffers[i];
812 buffers[i].~SPtr<GpuBuffer>();
813 }
814
815 for (UINT32 i = 0; i < numSamplers; i++)
816 {
817 mSamplerStates[i] = samplers[i];
818 samplers[i].~SPtr<SamplerState>();
819 }
820 }
821
822 SPtr<GpuParams> GpuParams::create(const SPtr<GraphicsPipelineState>& pipelineState, GpuDeviceFlags deviceMask)
823 {
824 return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo(), deviceMask);
825 }
826
827 SPtr<GpuParams> GpuParams::create(const SPtr<ComputePipelineState>& pipelineState, GpuDeviceFlags deviceMask)
828 {
829 return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo(), deviceMask);
830 }
831
832 SPtr<GpuParams> GpuParams::create(const SPtr<GpuPipelineParamInfo>& paramInfo, GpuDeviceFlags deviceMask)
833 {
834 return HardwareBufferManager::instance().createGpuParams(paramInfo, deviceMask);
835 }
836 }
837}