1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Math/BsVector2.h"
7#include "Math/BsVector3.h"
8#include "Math/BsVector4.h"
9#include "Math/BsMatrix3.h"
10#include "Math/BsMatrix4.h"
11#include "Math/BsMatrixNxM.h"
12#include "Math/BsVector3I.h"
13#include "Math/BsVector4I.h"
14#include "Image/BsColor.h"
15
16namespace bs
17{
18 /** @addtogroup Implementation
19 * @{
20 */
21
22 /**
23 * Policy class that allows us to re-use this template class for matrices which might need transposing, and other
24 * types which do not. Matrix needs to be transposed for certain render systems depending on how they store them
25 * in memory.
26 */
27 template<class Type>
28 struct TransposePolicy
29 {
30 static Type transpose(const Type& value) { return value; }
31 static bool transposeEnabled(bool enabled) { return false; }
32 };
33
34 /** Transpose policy for 3x3 matrix. */
35 template<>
36 struct TransposePolicy<Matrix3>
37 {
38 static Matrix3 transpose(const Matrix3& value) { return value.transpose(); }
39 static bool transposeEnabled(bool enabled) { return enabled; }
40 };
41
42 /** Transpose policy for 4x4 matrix. */
43 template<>
44 struct TransposePolicy<Matrix4>
45 {
46 static Matrix4 transpose(const Matrix4& value) { return value.transpose(); }
47 static bool transposeEnabled(bool enabled) { return enabled; }
48 };
49
50 /** Transpose policy for NxM matrix. */
51 template<int N, int M>
52 struct TransposePolicy<MatrixNxM<N, M>>
53 {
54 static MatrixNxM<M, N> transpose(const MatrixNxM<N, M>& value) { return value.transpose(); }
55 static bool transposeEnabled(bool enabled) { return enabled; }
56 };
57
58 /**
59 * A handle that allows you to set a GpuProgram parameter. Internally keeps a reference to the GPU parameter buffer and
60 * the necessary offsets. You should specialize this type for specific parameter types.
61 *
62 * Object of this type must be returned by a Material. Setting/Getting parameter values will internally access a GPU
63 * parameter buffer attached to the Material this parameter was created from. Anything rendered with that material will
64 * then use those set values.
65 *
66 * @note
67 * Normally you can set a GpuProgram parameter by calling various set/get methods on a Material. This class primarily
68 * used an as optimization in performance critical bits of code where it is important to locate and set parameters
69 * quickly without any lookups (Mentioned set/get methods expect a parameter name). You just retrieve the handle once
70 * and then set the parameter value many times with minimal performance impact.
71 *
72 * @see Material
73 */
74 template<class T, bool Core>
75 class BS_CORE_EXPORT TGpuDataParam
76 {
77 private:
78 using GpuParamBufferType = SPtr<CoreVariantType<GpuParamBlockBuffer, Core>>;
79 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
80
81 public:
82 TGpuDataParam();
83 TGpuDataParam(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
84
85 /**
86 * Sets a parameter value at the specified array index. If parameter does not contain an array leave the index at 0.
87 *
88 * @note
89 * Like with all GPU parameters, the actual GPU buffer will not be updated until rendering with material this
90 * parameter was created from starts on the core thread.
91 */
92 void set(const T& value, UINT32 arrayIdx = 0) const;
93
94 /**
95 * Returns a value of a parameter at the specified array index. If parameter does not contain an array leave the
96 * index at 0.
97 *
98 * @note No GPU reads are done. Data returned was cached when it was written.
99 */
100 T get(UINT32 arrayIdx = 0) const;
101
102 /** Returns meta-data about the parameter. */
103 const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
104
105 /** Checks if param is initialized. */
106 bool operator==(const std::nullptr_t& nullval) const
107 {
108 return mParamDesc == nullptr;
109 }
110
111 protected:
112 GpuParamsType mParent;
113 GpuParamDataDesc* mParamDesc;
114 };
115
116 /** @copydoc TGpuDataParam */
117 template<bool Core>
118 class BS_CORE_EXPORT TGpuParamStruct
119 {
120 public:
121 using GpuParamBufferType = SPtr<CoreVariantType<GpuParamBlockBuffer, Core>>;
122 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
123
124 TGpuParamStruct();
125 TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
126
127 /** @copydoc TGpuDataParam::set */
128 void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
129
130 /** @copydoc TGpuDataParam::get */
131 void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
132
133 /** Returns the size of the struct in bytes. */
134 UINT32 getElementSize() const;
135
136 /** Returns meta-data about the parameter. */
137 const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
138
139 /** Checks if param is initialized. */
140 bool operator==(const std::nullptr_t& nullval) const
141 {
142 return mParamDesc == nullptr;
143 }
144
145 protected:
146 GpuParamsType mParent;
147 GpuParamDataDesc* mParamDesc;
148 };
149
150 /** @copydoc TGpuDataParam */
151 template<bool Core>
152 class BS_CORE_EXPORT TGpuParamTexture
153 {
154 private:
155 friend class GpuParams;
156 friend class ct::GpuParams;
157
158 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
159 using TextureType = CoreVariantHandleType<Texture, Core>;
160
161 public:
162 TGpuParamTexture();
163 TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
164
165 /** @copydoc TGpuDataParam::set */
166 void set(const TextureType& texture, const TextureSurface& surface = TextureSurface::COMPLETE) const;
167
168 /** @copydoc TGpuDataParam::get */
169 TextureType get() const;
170
171 /** @copydoc TGpuDataParam::getDesc */
172 const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
173
174 /** Checks if param is initialized. */
175 bool operator==(const std::nullptr_t& nullval) const
176 {
177 return mParamDesc == nullptr;
178 }
179
180 protected:
181 GpuParamsType mParent;
182 GpuParamObjectDesc* mParamDesc;
183 };
184
185 /** @copydoc TGpuDataParam */
186 template<bool Core>
187 class BS_CORE_EXPORT TGpuParamLoadStoreTexture
188 {
189 private:
190 friend class GpuParams;
191 friend class ct::GpuParams;
192
193 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
194 using TextureType = CoreVariantHandleType<Texture, Core>;
195
196 public:
197 TGpuParamLoadStoreTexture();
198 TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
199
200 /** @copydoc TGpuDataParam::set */
201 void set(const TextureType& texture, const TextureSurface& surface = TextureSurface()) const;
202
203 /** @copydoc TGpuDataParam::get */
204 TextureType get() const;
205
206 /** @copydoc TGpuDataParam::getDesc */
207 const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
208
209 /** Checks if param is initialized. */
210 bool operator==(const std::nullptr_t& nullval) const
211 {
212 return mParamDesc == nullptr;
213 }
214
215 protected:
216 GpuParamsType mParent;
217 GpuParamObjectDesc* mParamDesc;
218 };
219
220 /** @copydoc TGpuDataParam */
221 template<bool Core>
222 class BS_CORE_EXPORT TGpuParamBuffer
223 {
224 private:
225 friend class GpuParams;
226 friend class ct::GpuParams;
227
228 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
229 using BufferType = SPtr<CoreVariantType<GpuBuffer, Core>>;
230
231 public:
232 TGpuParamBuffer();
233 TGpuParamBuffer(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
234
235 /** @copydoc TGpuDataParam::set */
236 void set(const BufferType& buffer) const;
237
238 /** @copydoc TGpuDataParam::get */
239 BufferType get() const;
240
241 /** @copydoc TGpuDataParam::getDesc */
242 const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
243
244 /** Checks if param is initialized. */
245 bool operator==(const std::nullptr_t& nullval) const
246 {
247 return mParamDesc == nullptr;
248 }
249
250 protected:
251 GpuParamsType mParent;
252 GpuParamObjectDesc* mParamDesc;
253 };
254
255 /** @copydoc TGpuDataParam */
256 template<bool Core>
257 class BS_CORE_EXPORT TGpuParamSampState
258 {
259 private:
260 friend class GpuParams;
261 friend class ct::GpuParams;
262
263 using GpuParamsType = SPtr<CoreVariantType<GpuParams, Core>>;
264 using SamplerStateType = SPtr<CoreVariantType<SamplerState, Core>>;
265
266 public:
267 TGpuParamSampState();
268 TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
269
270 /** @copydoc TGpuDataParam::set */
271 void set(const SamplerStateType& samplerState) const;
272
273 /** @copydoc TGpuDataParam::get */
274 SamplerStateType get() const;
275
276 /** @copydoc TGpuDataParam::getDesc */
277 const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
278
279 /** Checks if param is initialized. */
280 bool operator==(const std::nullptr_t& nullval) const
281 {
282 return mParamDesc == nullptr;
283 }
284
285 protected:
286 GpuParamsType mParent;
287 GpuParamObjectDesc* mParamDesc;
288 };
289
290 /** @} */
291
292 /** @addtogroup RenderAPI
293 * @{
294 */
295
296 typedef TGpuDataParam<float, false> GpuParamFloat;
297 typedef TGpuDataParam<Vector2, false> GpuParamVec2;
298 typedef TGpuDataParam<Vector3, false> GpuParamVec3;
299 typedef TGpuDataParam<Vector4, false> GpuParamVec4;
300 typedef TGpuDataParam<int, false> GpuParamInt;
301 typedef TGpuDataParam<Vector2I, false> GpuParamVec2I;
302 typedef TGpuDataParam<Vector3I, false> GpuParamVec3I;
303 typedef TGpuDataParam<Vector4I, false> GpuParamVec4I;
304 typedef TGpuDataParam<Matrix3, false> GpuParamMat3;
305 typedef TGpuDataParam<Matrix4, false> GpuParamMat4;
306 typedef TGpuDataParam<Color, false> GpuParamColor;
307
308 typedef TGpuParamStruct<false> GpuParamStruct;
309 typedef TGpuParamTexture<false> GpuParamTexture;
310 typedef TGpuParamBuffer<false> GpuParamBuffer;
311 typedef TGpuParamSampState<false> GpuParamSampState;
312 typedef TGpuParamLoadStoreTexture<false> GpuParamLoadStoreTexture;
313
314 namespace ct
315 {
316 typedef TGpuDataParam<float, true> GpuParamFloat;
317 typedef TGpuDataParam<Vector2, true> GpuParamVec2;
318 typedef TGpuDataParam<Vector3, true> GpuParamVec3;
319 typedef TGpuDataParam<Vector4, true> GpuParamVec4;
320 typedef TGpuDataParam<int, true> GpuParamInt;
321 typedef TGpuDataParam<Vector2I, true> GpuParamVec2I;
322 typedef TGpuDataParam<Vector3I, true> GpuParamVec3I;
323 typedef TGpuDataParam<Vector4I, true> GpuParamVec4I;
324 typedef TGpuDataParam<Matrix3, true> GpuParamMat3;
325 typedef TGpuDataParam<Matrix4, true> GpuParamMat4;
326 typedef TGpuDataParam<Color, true> GpuParamColor;
327
328 typedef TGpuParamStruct<true> GpuParamStruct;
329 typedef TGpuParamTexture<true> GpuParamTexture;
330 typedef TGpuParamBuffer<true> GpuParamBuffer;
331 typedef TGpuParamSampState<true> GpuParamSampState;
332 typedef TGpuParamLoadStoreTexture<true> GpuParamLoadStoreTexture;
333 }
334
335 /** @} */
336}