Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / 3d / gpu_program_params.cpp
blobd5ad9823e3f0838bb008a8181a9c6b67751b3341
1 /**
2 * \file gpu_program_params.cpp
3 * \brief CGPUProgramParams
4 * \date 2013-09-07 22:17GMT
5 * \author Jan Boon (Kaetemi)
6 * CGPUProgramParams
7 */
9 // NeL - MMORPG Framework <https://wiki.ryzom.dev/>
10 // Copyright (C) 2013 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
12 // This program is free software: you can redistribute it and/or modify
13 // it under the terms of the GNU Affero General Public License as
14 // published by the Free Software Foundation, either version 3 of the
15 // License, or (at your option) any later version.
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Affero General Public License for more details.
22 // You should have received a copy of the GNU Affero General Public License
23 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "std3d.h"
26 #include "nel/3d/gpu_program_params.h"
28 // STL includes
30 // NeL includes
31 // #include <nel/misc/debug.h>
32 #include "nel/misc/vector.h"
33 #include "nel/misc/matrix.h"
35 // Project includes
36 #include "nel/3d/driver.h"
38 using namespace std;
39 // using namespace NLMISC;
41 #ifdef DEBUG_NEW
42 #define new DEBUG_NEW
43 #endif
45 namespace NL3D {
47 const size_t CGPUProgramParams::s_End = -1;
49 CGPUProgramParams::CGPUProgramParams() : m_First(s_End), m_Last(s_End)
53 CGPUProgramParams::~CGPUProgramParams()
57 void CGPUProgramParams::copy(CGPUProgramParams *params)
59 size_t offset = params->getBegin();
60 while (offset != params->getEnd())
62 uint index = params->getIndexByOffset(offset);
63 const std::string &name = params->getNameByOffset(offset);
64 size_t local;
65 uint size = params->getSizeByOffset(offset);
66 uint count = params->getCountByOffset(offset);
67 uint nbComponents = size * count;
68 if (index)
70 local = allocOffset(index, size, count, params->getTypeByOffset(offset));
71 if (!name.empty())
73 map(index, name);
76 else
78 nlassert(!name.empty());
79 local = allocOffset(name, size, count, params->getTypeByOffset(offset));
82 uint32 *src = params->getPtrUIByOffset(offset);
83 uint32 *dst = getPtrUIByOffset(local);
85 for (uint c = 0; c < nbComponents; ++c)
87 dst[c] = src[c];
90 offset = params->getNext(offset);
94 void CGPUProgramParams::set1f(uint index, float f0)
96 float *f = getPtrFByOffset(allocOffset(index, 1, 1, Float));
97 f[0] = f0;
100 void CGPUProgramParams::set2f(uint index, float f0, float f1)
102 float *f = getPtrFByOffset(allocOffset(index, 2, 1, Float));
103 f[0] = f0;
104 f[1] = f1;
107 void CGPUProgramParams::set3f(uint index, float f0, float f1, float f2)
109 float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float));
110 f[0] = f0;
111 f[1] = f1;
112 f[2] = f2;
115 void CGPUProgramParams::set4f(uint index, float f0, float f1, float f2, float f3)
117 float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float));
118 f[0] = f0;
119 f[1] = f1;
120 f[2] = f2;
121 f[3] = f3;
124 void CGPUProgramParams::set1i(uint index, sint32 i0)
126 sint32 *i = getPtrIByOffset(allocOffset(index, 1, 1, Int));
127 i[0] = i0;
130 void CGPUProgramParams::set2i(uint index, sint32 i0, sint32 i1)
132 sint32 *i = getPtrIByOffset(allocOffset(index, 2, 1, Int));
133 i[0] = i0;
134 i[1] = i1;
137 void CGPUProgramParams::set3i(uint index, sint32 i0, sint32 i1, sint32 i2)
139 sint32 *i = getPtrIByOffset(allocOffset(index, 3, 1, Int));
140 i[0] = i0;
141 i[1] = i1;
142 i[2] = i2;
145 void CGPUProgramParams::set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
147 sint32 *i = getPtrIByOffset(allocOffset(index, 4, 1, Int));
148 i[0] = i0;
149 i[1] = i1;
150 i[2] = i2;
151 i[3] = i3;
154 void CGPUProgramParams::set1ui(uint index, uint32 ui0)
156 uint32 *ui = getPtrUIByOffset(allocOffset(index, 1, 1, UInt));
157 ui[0] = ui0;
160 void CGPUProgramParams::set2ui(uint index, uint32 ui0, uint32 ui1)
162 uint32 *ui = getPtrUIByOffset(allocOffset(index, 2, 1, UInt));
163 ui[0] = ui0;
164 ui[1] = ui1;
167 void CGPUProgramParams::set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2)
169 uint32 *ui = getPtrUIByOffset(allocOffset(index, 3, 1, UInt));
170 ui[0] = ui0;
171 ui[1] = ui1;
172 ui[2] = ui2;
175 void CGPUProgramParams::set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
177 uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, 1, UInt));
178 ui[0] = ui0;
179 ui[1] = ui1;
180 ui[2] = ui2;
181 ui[3] = ui3;
184 void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v)
186 float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float));
187 f[0] = v.x;
188 f[1] = v.y;
189 f[2] = v.z;
192 void CGPUProgramParams::set4f(uint index, const NLMISC::CVector& v, float f3)
194 float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float));
195 f[0] = v.x;
196 f[1] = v.y;
197 f[2] = v.z;
198 f[3] = f3;
201 void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m)
203 // TODO: Verify this!
204 float *f = getPtrFByOffset(allocOffset(index, 4, 4, Float));
205 NLMISC::CMatrix mt = m;
206 mt.transpose();
207 mt.get(f);
210 void CGPUProgramParams::set4fv(uint index, size_t num, const float *src)
212 float *f = getPtrFByOffset(allocOffset(index, 4, num, Float));
213 size_t nb = 4 * num;
214 for (uint c = 0; c < nb; ++c)
215 f[c] = src[c];
218 void CGPUProgramParams::set4iv(uint index, size_t num, const sint32 *src)
220 sint32 *i = getPtrIByOffset(allocOffset(index, 4, num, Int));
221 size_t nb = 4 * num;
222 for (uint c = 0; c < nb; ++c)
223 i[c] = src[c];
226 void CGPUProgramParams::set4uiv(uint index, size_t num, const uint32 *src)
228 uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, num, UInt));
229 size_t nb = 4 * num;
230 for (uint c = 0; c < nb; ++c)
231 ui[c] = src[c];
234 void CGPUProgramParams::unset(uint index)
236 size_t offset = getOffset(index);
237 if (offset != getEnd())
239 freeOffset(offset);
243 void CGPUProgramParams::set1f(const std::string &name, float f0)
245 float *f = getPtrFByOffset(allocOffset(name, 1, 1, Float));
246 f[0] = f0;
249 void CGPUProgramParams::set2f(const std::string &name, float f0, float f1)
251 float *f = getPtrFByOffset(allocOffset(name, 2, 1, Float));
252 f[0] = f0;
253 f[1] = f1;
256 void CGPUProgramParams::set3f(const std::string &name, float f0, float f1, float f2)
258 float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float));
259 f[0] = f0;
260 f[1] = f1;
261 f[2] = f2;
264 void CGPUProgramParams::set4f(const std::string &name, float f0, float f1, float f2, float f3)
266 float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float));
267 f[0] = f0;
268 f[1] = f1;
269 f[2] = f2;
270 f[3] = f3;
273 void CGPUProgramParams::set1i(const std::string &name, sint32 i0)
275 sint32 *i = getPtrIByOffset(allocOffset(name, 1, 1, Int));
276 i[0] = i0;
279 void CGPUProgramParams::set2i(const std::string &name, sint32 i0, sint32 i1)
281 sint32 *i = getPtrIByOffset(allocOffset(name, 2, 1, Int));
282 i[0] = i0;
283 i[1] = i1;
286 void CGPUProgramParams::set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2)
288 sint32 *i = getPtrIByOffset(allocOffset(name, 3, 1, Int));
289 i[0] = i0;
290 i[1] = i1;
291 i[2] = i2;
294 void CGPUProgramParams::set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
296 sint32 *i = getPtrIByOffset(allocOffset(name, 4, 1, Int));
297 i[0] = i0;
298 i[1] = i1;
299 i[2] = i2;
300 i[3] = i3;
303 void CGPUProgramParams::set1ui(const std::string &name, uint32 ui0)
305 uint32 *ui = getPtrUIByOffset(allocOffset(name, 1, 1, UInt));
306 ui[0] = ui0;
309 void CGPUProgramParams::set2ui(const std::string &name, uint32 ui0, uint32 ui1)
311 uint32 *ui = getPtrUIByOffset(allocOffset(name, 2, 1, UInt));
312 ui[0] = ui0;
313 ui[1] = ui1;
316 void CGPUProgramParams::set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2)
318 uint32 *ui = getPtrUIByOffset(allocOffset(name, 3, 1, UInt));
319 ui[0] = ui0;
320 ui[1] = ui1;
321 ui[2] = ui2;
324 void CGPUProgramParams::set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
326 uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, 1, UInt));
327 ui[0] = ui0;
328 ui[1] = ui1;
329 ui[2] = ui2;
330 ui[3] = ui3;
333 void CGPUProgramParams::set3f(const std::string &name, const NLMISC::CVector& v)
335 float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float));
336 f[0] = v.x;
337 f[1] = v.y;
338 f[2] = v.z;
341 void CGPUProgramParams::set4f(const std::string &name, const NLMISC::CVector& v, float f3)
343 float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float));
344 f[0] = v.x;
345 f[1] = v.y;
346 f[2] = v.z;
347 f[3] = f3;
350 void CGPUProgramParams::set4x4f(const std::string &name, const NLMISC::CMatrix& m)
352 // TODO: Verify this!
353 float *f = getPtrFByOffset(allocOffset(name, 4, 4, Float));
354 NLMISC::CMatrix mt = m;
355 mt.transpose();
356 mt.get(f);
359 void CGPUProgramParams::set4fv(const std::string &name, size_t num, const float *src)
361 float *f = getPtrFByOffset(allocOffset(name, 4, num, Float));
362 size_t nb = 4 * num;
363 for (uint c = 0; c < nb; ++c)
364 f[c] = src[c];
367 void CGPUProgramParams::set4iv(const std::string &name, size_t num, const sint32 *src)
369 sint32 *i = getPtrIByOffset(allocOffset(name, 4, num, Int));
370 size_t nb = 4 * num;
371 for (uint c = 0; c < nb; ++c)
372 i[c] = src[c];
375 void CGPUProgramParams::set4uiv(const std::string &name, size_t num, const uint32 *src)
377 uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, num, UInt));
378 size_t nb = 4 * num;
379 for (uint c = 0; c < nb; ++c)
380 ui[c] = src[c];
383 void CGPUProgramParams::unset(const std::string &name)
385 size_t offset = getOffset(name);
386 if (offset != getEnd())
388 freeOffset(offset);
392 void CGPUProgramParams::map(uint index, const std::string &name)
394 size_t offsetIndex = getOffset(index);
395 size_t offsetName = getOffset(name);
396 if (offsetName != getEnd())
398 // Remove possible duplicate
399 if (offsetIndex != getEnd())
401 freeOffset(offsetIndex);
404 // Set index
405 m_Meta[offsetName].Index = index;
407 // Map index to name
408 if (index >= m_Map.size())
409 m_Map.resize(index + 1, s_End);
410 m_Map[index] = offsetName;
412 else if (offsetIndex != getEnd())
414 // Set name
415 m_Meta[offsetIndex].Name = name;
417 // Map name to index
418 m_MapName[name] = offsetIndex;
422 /// Allocate specified number of components if necessary
423 size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type)
425 nlassert(count > 0); // this code will not properly handle 0
426 nlassert(size > 0); // this code will not properly handle 0
427 nlassert(index < 0xFFFF); // sanity check
429 uint nbComponents = size * count;
430 size_t offset = getOffset(index);
431 if (offset != s_End)
433 if (getCountByOffset(offset) >= nbComponents)
435 m_Meta[offset].Type = type;
436 m_Meta[offset].Size = size;
437 m_Meta[offset].Count = count;
438 return offset;
440 if (getCountByOffset(offset) < nbComponents)
442 freeOffset(offset);
446 // Allocate space
447 offset = allocOffset(size, count, type);
449 // Fill
450 m_Meta[offset].Index = index;
452 // Store offset in map
453 if (index >= m_Map.size())
454 m_Map.resize(index + 1, s_End);
455 m_Map[index] = offset;
457 return offset;
460 /// Allocate specified number of components if necessary
461 size_t CGPUProgramParams::allocOffset(const std::string &name, uint size, uint count, TType type)
463 nlassert(count > 0); // this code will not properly handle 0
464 nlassert(size > 0); // this code will not properly handle 0
465 nlassert(!name.empty()); // sanity check
467 uint nbComponents = size * count;
468 size_t offset = getOffset(name);
469 if (offset != s_End)
471 if (getCountByOffset(offset) >= nbComponents)
473 m_Meta[offset].Type = type;
474 m_Meta[offset].Size = size;
475 m_Meta[offset].Count = count;
476 return offset;
478 if (getCountByOffset(offset) < nbComponents)
480 freeOffset(offset);
484 // Allocate space
485 offset = allocOffset(size, count, type);
487 // Fill
488 m_Meta[offset].Name = name;
490 // Store offset in map
491 m_MapName[name] = offset;
493 return offset;
496 /// Allocate specified number of components if necessary
497 size_t CGPUProgramParams::allocOffset(uint size, uint count, TType type)
499 uint nbComponents = size * count;
501 // Allocate space
502 size_t offset = m_Meta.size();
503 uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components
504 m_Meta.resize(offset + blocks);
505 m_Vec.resize(offset + blocks);
507 // Fill
508 m_Meta[offset].Size = size;
509 m_Meta[offset].Count = count;
510 m_Meta[offset].Type = type;
511 m_Meta[offset].Prev = m_Last;
512 m_Meta[offset].Next = s_End;
514 // Link
515 if (m_Last == s_End)
517 m_First = m_Last = offset;
519 else
521 nlassert(m_Meta[m_Last].Next == s_End); // code error otherwise
522 m_Meta[m_Last].Next = offset;
523 m_Last = offset;
526 return offset;
529 /// Return offset for specified index
530 size_t CGPUProgramParams::getOffset(uint index) const
532 if (index >= m_Map.size())
533 return s_End;
534 return m_Map[index];
537 size_t CGPUProgramParams::getOffset(const std::string &name) const
539 std::map<std::string, size_t>::const_iterator it = m_MapName.find(name);
540 if (it == m_MapName.end())
541 return s_End;
542 return it->second;
545 /// Remove by offset
546 void CGPUProgramParams::freeOffset(size_t offset)
548 uint index = getIndexByOffset(offset);
549 if (index != std::numeric_limits<uint>::max())
551 if (m_Map.size() > index)
553 m_Map[index] = getEnd();
556 const std::string &name = getNameByOffset(offset);
557 if (!name.empty())
559 if (m_MapName.find(name) != m_MapName.end())
561 m_MapName.erase(name);
564 if (offset == m_Last)
566 nlassert(m_Meta[offset].Next == s_End);
567 m_Last = m_Meta[offset].Prev;
569 else
571 nlassert(m_Meta[offset].Next != s_End);
572 m_Meta[m_Meta[offset].Next].Prev = m_Meta[offset].Prev;
574 if (offset == m_First)
576 nlassert(m_Meta[offset].Prev == s_End);
577 m_First = m_Meta[offset].Next;
579 else
581 nlassert(m_Meta[offset].Prev != s_End);
582 m_Meta[m_Meta[offset].Prev].Next = m_Meta[offset].Next;
586 } /* namespace NL3D */
588 /* end of file */