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/BsGpuParam.h" |
4 | #include "RenderAPI/BsGpuParams.h" |
5 | #include "RenderAPI/BsGpuParamBlockBuffer.h" |
6 | #include "RenderAPI/BsGpuParamDesc.h" |
7 | #include "RenderAPI/BsRenderAPI.h" |
8 | #include "Debug/BsDebug.h" |
9 | #include "Error/BsException.h" |
10 | #include "Math/BsVector2I.h" |
11 | |
12 | namespace bs |
13 | { |
14 | template<class T, bool Core> |
15 | TGpuDataParam<T, Core>::TGpuDataParam() |
16 | :mParamDesc(nullptr) |
17 | { } |
18 | |
19 | template<class T, bool Core> |
20 | TGpuDataParam<T, Core>::TGpuDataParam(GpuParamDataDesc* paramDesc, const GpuParamsType& parent) |
21 | :mParent(parent), mParamDesc(paramDesc) |
22 | { } |
23 | |
24 | template<class T, bool Core> |
25 | void TGpuDataParam<T, Core>::set(const T& value, UINT32 arrayIdx) const |
26 | { |
27 | if (mParent == nullptr) |
28 | return; |
29 | |
30 | GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); |
31 | if (paramBlock == nullptr) |
32 | return; |
33 | |
34 | #if BS_DEBUG_MODE |
35 | if (arrayIdx >= mParamDesc->arraySize) |
36 | { |
37 | BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + |
38 | toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); |
39 | } |
40 | #endif |
41 | |
42 | UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); |
43 | UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size |
44 | |
45 | const bool transposeMatrices = ct::gCaps().conventions.matrixOrder == Conventions::MatrixOrder::ColumnMajor; |
46 | if (TransposePolicy<T>::transposeEnabled(transposeMatrices)) |
47 | { |
48 | auto transposed = TransposePolicy<T>::transpose(value); |
49 | paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes); |
50 | } |
51 | else |
52 | paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes); |
53 | |
54 | // Set unused bytes to 0 |
55 | if (sizeBytes < elementSizeBytes) |
56 | { |
57 | UINT32 diffSize = elementSizeBytes - sizeBytes; |
58 | paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32) + sizeBytes, diffSize); |
59 | } |
60 | |
61 | mParent->_markCoreDirty(); |
62 | } |
63 | |
64 | template<class T, bool Core> |
65 | T TGpuDataParam<T, Core>::get(UINT32 arrayIdx) const |
66 | { |
67 | if (mParent == nullptr) |
68 | return T(); |
69 | |
70 | GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); |
71 | if (paramBlock == nullptr) |
72 | return T(); |
73 | |
74 | #if BS_DEBUG_MODE |
75 | if (arrayIdx >= mParamDesc->arraySize) |
76 | { |
77 | BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + |
78 | toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); |
79 | } |
80 | #endif |
81 | |
82 | UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); |
83 | UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); |
84 | |
85 | T value; |
86 | paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes); |
87 | |
88 | return value; |
89 | } |
90 | |
91 | template<bool Core> |
92 | TGpuParamStruct<Core>::TGpuParamStruct() |
93 | :mParamDesc(nullptr) |
94 | { } |
95 | |
96 | template<bool Core> |
97 | TGpuParamStruct<Core>::TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent) |
98 | :mParent(parent), mParamDesc(paramDesc) |
99 | { } |
100 | |
101 | template<bool Core> |
102 | void TGpuParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const |
103 | { |
104 | if (mParent == nullptr) |
105 | return; |
106 | |
107 | GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); |
108 | if (paramBlock == nullptr) |
109 | return; |
110 | |
111 | UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); |
112 | |
113 | #if BS_DEBUG_MODE |
114 | if (sizeBytes > elementSizeBytes) |
115 | { |
116 | LOGWRN("Provided element size larger than maximum element size. Maximum size: " + |
117 | toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes)); |
118 | } |
119 | |
120 | if (arrayIdx >= mParamDesc->arraySize) |
121 | { |
122 | BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + |
123 | toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); |
124 | } |
125 | #endif |
126 | |
127 | sizeBytes = std::min(elementSizeBytes, sizeBytes); |
128 | |
129 | paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes); |
130 | |
131 | // Set unused bytes to 0 |
132 | if (sizeBytes < elementSizeBytes) |
133 | { |
134 | UINT32 diffSize = elementSizeBytes - sizeBytes; |
135 | paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32) + sizeBytes, diffSize); |
136 | } |
137 | |
138 | mParent->_markCoreDirty(); |
139 | } |
140 | |
141 | template<bool Core> |
142 | void TGpuParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const |
143 | { |
144 | if (mParent == nullptr) |
145 | return; |
146 | |
147 | GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); |
148 | if (paramBlock == nullptr) |
149 | return; |
150 | |
151 | UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); |
152 | |
153 | #if BS_DEBUG_MODE |
154 | if (sizeBytes > elementSizeBytes) |
155 | { |
156 | LOGWRN("Provided element size larger than maximum element size. Maximum size: " + |
157 | toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes)); |
158 | } |
159 | |
160 | if (arrayIdx >= mParamDesc->arraySize) |
161 | { |
162 | BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + |
163 | toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); |
164 | } |
165 | #endif |
166 | sizeBytes = std::min(elementSizeBytes, sizeBytes); |
167 | |
168 | paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes); |
169 | } |
170 | |
171 | template<bool Core> |
172 | UINT32 TGpuParamStruct<Core>::getElementSize() const |
173 | { |
174 | if (mParent == nullptr) |
175 | return 0; |
176 | |
177 | return mParamDesc->elementSize * sizeof(UINT32); |
178 | } |
179 | |
180 | template<bool Core> |
181 | TGpuParamTexture<Core>::TGpuParamTexture() |
182 | :mParamDesc(nullptr) |
183 | { } |
184 | |
185 | template<bool Core> |
186 | TGpuParamTexture<Core>::TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent) |
187 | :mParent(parent), mParamDesc(paramDesc) |
188 | { } |
189 | |
190 | template<bool Core> |
191 | void TGpuParamTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const |
192 | { |
193 | if (mParent == nullptr) |
194 | return; |
195 | |
196 | mParent->setTexture(mParamDesc->set, mParamDesc->slot, texture, surface); |
197 | |
198 | mParent->_markResourcesDirty(); |
199 | mParent->_markCoreDirty(); |
200 | } |
201 | |
202 | template<bool Core> |
203 | typename TGpuParamTexture<Core>::TextureType TGpuParamTexture<Core>::get() const |
204 | { |
205 | if (mParent == nullptr) |
206 | return TextureType(); |
207 | |
208 | return mParent->getTexture(mParamDesc->set, mParamDesc->slot); |
209 | } |
210 | |
211 | template<bool Core> |
212 | TGpuParamBuffer<Core>::TGpuParamBuffer() |
213 | :mParamDesc(nullptr) |
214 | { } |
215 | |
216 | template<bool Core> |
217 | TGpuParamBuffer<Core>::TGpuParamBuffer(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent) |
218 | : mParent(parent), mParamDesc(paramDesc) |
219 | { } |
220 | |
221 | template<bool Core> |
222 | void TGpuParamBuffer<Core>::set(const BufferType& buffer) const |
223 | { |
224 | if (mParent == nullptr) |
225 | return; |
226 | |
227 | mParent->setBuffer(mParamDesc->set, mParamDesc->slot, buffer); |
228 | |
229 | mParent->_markResourcesDirty(); |
230 | mParent->_markCoreDirty(); |
231 | } |
232 | |
233 | template<bool Core> |
234 | typename TGpuParamBuffer<Core>::BufferType TGpuParamBuffer<Core>::get() const |
235 | { |
236 | if (mParent == nullptr) |
237 | return BufferType(); |
238 | |
239 | return mParent->getBuffer(mParamDesc->set, mParamDesc->slot); |
240 | } |
241 | |
242 | template<bool Core> |
243 | TGpuParamLoadStoreTexture<Core>::TGpuParamLoadStoreTexture() |
244 | :mParamDesc(nullptr) |
245 | { } |
246 | |
247 | template<bool Core> |
248 | TGpuParamLoadStoreTexture<Core>::TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent) |
249 | :mParent(parent), mParamDesc(paramDesc) |
250 | { } |
251 | |
252 | template<bool Core> |
253 | void TGpuParamLoadStoreTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const |
254 | { |
255 | if (mParent == nullptr) |
256 | return; |
257 | |
258 | mParent->setLoadStoreTexture(mParamDesc->set, mParamDesc->slot, texture, surface); |
259 | |
260 | mParent->_markResourcesDirty(); |
261 | mParent->_markCoreDirty(); |
262 | } |
263 | |
264 | template<bool Core> |
265 | typename TGpuParamLoadStoreTexture<Core>::TextureType TGpuParamLoadStoreTexture<Core>::get() const |
266 | { |
267 | if (mParent == nullptr) |
268 | return TextureType(); |
269 | |
270 | return mParent->getTexture(mParamDesc->set, mParamDesc->slot); |
271 | } |
272 | |
273 | template<bool Core> |
274 | TGpuParamSampState<Core>::TGpuParamSampState() |
275 | :mParamDesc(nullptr) |
276 | { } |
277 | |
278 | template<bool Core> |
279 | TGpuParamSampState<Core>::TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent) |
280 | :mParent(parent), mParamDesc(paramDesc) |
281 | { } |
282 | |
283 | template<bool Core> |
284 | void TGpuParamSampState<Core>::set(const SamplerStateType& samplerState) const |
285 | { |
286 | if (mParent == nullptr) |
287 | return; |
288 | |
289 | mParent->setSamplerState(mParamDesc->set, mParamDesc->slot, samplerState); |
290 | |
291 | mParent->_markResourcesDirty(); |
292 | mParent->_markCoreDirty(); |
293 | } |
294 | |
295 | template<bool Core> |
296 | typename TGpuParamSampState<Core>::SamplerStateType TGpuParamSampState<Core>::get() const |
297 | { |
298 | if (mParent == nullptr) |
299 | return SamplerStateType(); |
300 | |
301 | return mParent->getSamplerState(mParamDesc->set, mParamDesc->slot); |
302 | } |
303 | |
304 | template class TGpuDataParam < float, false > ; |
305 | template class TGpuDataParam < int, false >; |
306 | template class TGpuDataParam < Color, false > ; |
307 | template class TGpuDataParam < Vector2, false > ; |
308 | template class TGpuDataParam < Vector3, false > ; |
309 | template class TGpuDataParam < Vector4, false > ; |
310 | template class TGpuDataParam < Vector2I, false > ; |
311 | template class TGpuDataParam < Vector3I, false > ; |
312 | template class TGpuDataParam < Vector4I, false > ; |
313 | template class TGpuDataParam < Matrix2, false >; |
314 | template class TGpuDataParam < Matrix2x3, false >; |
315 | template class TGpuDataParam < Matrix2x4, false >; |
316 | template class TGpuDataParam < Matrix3, false > ; |
317 | template class TGpuDataParam < Matrix3x2, false > ; |
318 | template class TGpuDataParam < Matrix3x4, false > ; |
319 | template class TGpuDataParam < Matrix4, false > ; |
320 | template class TGpuDataParam < Matrix4x2, false >; |
321 | template class TGpuDataParam < Matrix4x3, false >; |
322 | |
323 | template class TGpuDataParam < float, true > ; |
324 | template class TGpuDataParam < int, true >; |
325 | template class TGpuDataParam < Color, true > ; |
326 | template class TGpuDataParam < Vector2, true > ; |
327 | template class TGpuDataParam < Vector3, true > ; |
328 | template class TGpuDataParam < Vector4, true > ; |
329 | template class TGpuDataParam < Vector2I, true > ; |
330 | template class TGpuDataParam < Vector3I, true > ; |
331 | template class TGpuDataParam < Vector4I, true > ; |
332 | template class TGpuDataParam < Matrix2, true >; |
333 | template class TGpuDataParam < Matrix2x3, true >; |
334 | template class TGpuDataParam < Matrix2x4, true >; |
335 | template class TGpuDataParam < Matrix3, true > ; |
336 | template class TGpuDataParam < Matrix3x2, true >; |
337 | template class TGpuDataParam < Matrix3x4, true >; |
338 | template class TGpuDataParam < Matrix4, true > ; |
339 | template class TGpuDataParam < Matrix4x2, true >; |
340 | template class TGpuDataParam < Matrix4x3, true >; |
341 | |
342 | template class TGpuParamStruct < false > ; |
343 | template class TGpuParamStruct < true > ; |
344 | |
345 | template class TGpuParamTexture < false > ; |
346 | template class TGpuParamTexture < true > ; |
347 | |
348 | template class TGpuParamBuffer < false >; |
349 | template class TGpuParamBuffer < true >; |
350 | |
351 | template class TGpuParamSampState < false > ; |
352 | template class TGpuParamSampState < true > ; |
353 | |
354 | template class TGpuParamLoadStoreTexture < false > ; |
355 | template class TGpuParamLoadStoreTexture < true > ; |
356 | } |