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 | |
19 | namespace 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 ¶mIter->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 ¶mBlockIter->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 = 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 (¶mBuffers[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 | } |