2 * \file gpu_program_params.cpp
3 * \brief CGPUProgramParams
4 * \date 2013-09-07 22:17GMT
5 * \author Jan Boon (Kaetemi)
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/>.
26 #include "nel/3d/gpu_program_params.h"
31 // #include <nel/misc/debug.h>
32 #include "nel/misc/vector.h"
33 #include "nel/misc/matrix.h"
36 #include "nel/3d/driver.h"
39 // using namespace NLMISC;
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
);
65 uint size
= params
->getSizeByOffset(offset
);
66 uint count
= params
->getCountByOffset(offset
);
67 uint nbComponents
= size
* count
;
70 local
= allocOffset(index
, size
, count
, params
->getTypeByOffset(offset
));
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
)
90 offset
= params
->getNext(offset
);
94 void CGPUProgramParams::set1f(uint index
, float f0
)
96 float *f
= getPtrFByOffset(allocOffset(index
, 1, 1, Float
));
100 void CGPUProgramParams::set2f(uint index
, float f0
, float f1
)
102 float *f
= getPtrFByOffset(allocOffset(index
, 2, 1, Float
));
107 void CGPUProgramParams::set3f(uint index
, float f0
, float f1
, float f2
)
109 float *f
= getPtrFByOffset(allocOffset(index
, 3, 1, Float
));
115 void CGPUProgramParams::set4f(uint index
, float f0
, float f1
, float f2
, float f3
)
117 float *f
= getPtrFByOffset(allocOffset(index
, 4, 1, Float
));
124 void CGPUProgramParams::set1i(uint index
, sint32 i0
)
126 sint32
*i
= getPtrIByOffset(allocOffset(index
, 1, 1, Int
));
130 void CGPUProgramParams::set2i(uint index
, sint32 i0
, sint32 i1
)
132 sint32
*i
= getPtrIByOffset(allocOffset(index
, 2, 1, Int
));
137 void CGPUProgramParams::set3i(uint index
, sint32 i0
, sint32 i1
, sint32 i2
)
139 sint32
*i
= getPtrIByOffset(allocOffset(index
, 3, 1, Int
));
145 void CGPUProgramParams::set4i(uint index
, sint32 i0
, sint32 i1
, sint32 i2
, sint32 i3
)
147 sint32
*i
= getPtrIByOffset(allocOffset(index
, 4, 1, Int
));
154 void CGPUProgramParams::set1ui(uint index
, uint32 ui0
)
156 uint32
*ui
= getPtrUIByOffset(allocOffset(index
, 1, 1, UInt
));
160 void CGPUProgramParams::set2ui(uint index
, uint32 ui0
, uint32 ui1
)
162 uint32
*ui
= getPtrUIByOffset(allocOffset(index
, 2, 1, UInt
));
167 void CGPUProgramParams::set3ui(uint index
, uint32 ui0
, uint32 ui1
, uint32 ui2
)
169 uint32
*ui
= getPtrUIByOffset(allocOffset(index
, 3, 1, UInt
));
175 void CGPUProgramParams::set4ui(uint index
, uint32 ui0
, uint32 ui1
, uint32 ui2
, uint32 ui3
)
177 uint32
*ui
= getPtrUIByOffset(allocOffset(index
, 4, 1, UInt
));
184 void CGPUProgramParams::set3f(uint index
, const NLMISC::CVector
& v
)
186 float *f
= getPtrFByOffset(allocOffset(index
, 3, 1, Float
));
192 void CGPUProgramParams::set4f(uint index
, const NLMISC::CVector
& v
, float f3
)
194 float *f
= getPtrFByOffset(allocOffset(index
, 4, 1, Float
));
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
;
210 void CGPUProgramParams::set4fv(uint index
, size_t num
, const float *src
)
212 float *f
= getPtrFByOffset(allocOffset(index
, 4, num
, Float
));
214 for (uint c
= 0; c
< nb
; ++c
)
218 void CGPUProgramParams::set4iv(uint index
, size_t num
, const sint32
*src
)
220 sint32
*i
= getPtrIByOffset(allocOffset(index
, 4, num
, Int
));
222 for (uint c
= 0; c
< nb
; ++c
)
226 void CGPUProgramParams::set4uiv(uint index
, size_t num
, const uint32
*src
)
228 uint32
*ui
= getPtrUIByOffset(allocOffset(index
, 4, num
, UInt
));
230 for (uint c
= 0; c
< nb
; ++c
)
234 void CGPUProgramParams::unset(uint index
)
236 size_t offset
= getOffset(index
);
237 if (offset
!= getEnd())
243 void CGPUProgramParams::set1f(const std::string
&name
, float f0
)
245 float *f
= getPtrFByOffset(allocOffset(name
, 1, 1, Float
));
249 void CGPUProgramParams::set2f(const std::string
&name
, float f0
, float f1
)
251 float *f
= getPtrFByOffset(allocOffset(name
, 2, 1, Float
));
256 void CGPUProgramParams::set3f(const std::string
&name
, float f0
, float f1
, float f2
)
258 float *f
= getPtrFByOffset(allocOffset(name
, 3, 1, Float
));
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
));
273 void CGPUProgramParams::set1i(const std::string
&name
, sint32 i0
)
275 sint32
*i
= getPtrIByOffset(allocOffset(name
, 1, 1, Int
));
279 void CGPUProgramParams::set2i(const std::string
&name
, sint32 i0
, sint32 i1
)
281 sint32
*i
= getPtrIByOffset(allocOffset(name
, 2, 1, Int
));
286 void CGPUProgramParams::set3i(const std::string
&name
, sint32 i0
, sint32 i1
, sint32 i2
)
288 sint32
*i
= getPtrIByOffset(allocOffset(name
, 3, 1, Int
));
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
));
303 void CGPUProgramParams::set1ui(const std::string
&name
, uint32 ui0
)
305 uint32
*ui
= getPtrUIByOffset(allocOffset(name
, 1, 1, UInt
));
309 void CGPUProgramParams::set2ui(const std::string
&name
, uint32 ui0
, uint32 ui1
)
311 uint32
*ui
= getPtrUIByOffset(allocOffset(name
, 2, 1, UInt
));
316 void CGPUProgramParams::set3ui(const std::string
&name
, uint32 ui0
, uint32 ui1
, uint32 ui2
)
318 uint32
*ui
= getPtrUIByOffset(allocOffset(name
, 3, 1, UInt
));
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
));
333 void CGPUProgramParams::set3f(const std::string
&name
, const NLMISC::CVector
& v
)
335 float *f
= getPtrFByOffset(allocOffset(name
, 3, 1, Float
));
341 void CGPUProgramParams::set4f(const std::string
&name
, const NLMISC::CVector
& v
, float f3
)
343 float *f
= getPtrFByOffset(allocOffset(name
, 4, 1, Float
));
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
;
359 void CGPUProgramParams::set4fv(const std::string
&name
, size_t num
, const float *src
)
361 float *f
= getPtrFByOffset(allocOffset(name
, 4, num
, Float
));
363 for (uint c
= 0; c
< nb
; ++c
)
367 void CGPUProgramParams::set4iv(const std::string
&name
, size_t num
, const sint32
*src
)
369 sint32
*i
= getPtrIByOffset(allocOffset(name
, 4, num
, Int
));
371 for (uint c
= 0; c
< nb
; ++c
)
375 void CGPUProgramParams::set4uiv(const std::string
&name
, size_t num
, const uint32
*src
)
377 uint32
*ui
= getPtrUIByOffset(allocOffset(name
, 4, num
, UInt
));
379 for (uint c
= 0; c
< nb
; ++c
)
383 void CGPUProgramParams::unset(const std::string
&name
)
385 size_t offset
= getOffset(name
);
386 if (offset
!= getEnd())
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
);
405 m_Meta
[offsetName
].Index
= index
;
408 if (index
>= m_Map
.size())
409 m_Map
.resize(index
+ 1, s_End
);
410 m_Map
[index
] = offsetName
;
412 else if (offsetIndex
!= getEnd())
415 m_Meta
[offsetIndex
].Name
= name
;
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
);
433 if (getCountByOffset(offset
) >= nbComponents
)
435 m_Meta
[offset
].Type
= type
;
436 m_Meta
[offset
].Size
= size
;
437 m_Meta
[offset
].Count
= count
;
440 if (getCountByOffset(offset
) < nbComponents
)
447 offset
= allocOffset(size
, count
, type
);
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
;
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
);
471 if (getCountByOffset(offset
) >= nbComponents
)
473 m_Meta
[offset
].Type
= type
;
474 m_Meta
[offset
].Size
= size
;
475 m_Meta
[offset
].Count
= count
;
478 if (getCountByOffset(offset
) < nbComponents
)
485 offset
= allocOffset(size
, count
, type
);
488 m_Meta
[offset
].Name
= name
;
490 // Store offset in map
491 m_MapName
[name
] = 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
;
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
);
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
;
517 m_First
= m_Last
= offset
;
521 nlassert(m_Meta
[m_Last
].Next
== s_End
); // code error otherwise
522 m_Meta
[m_Last
].Next
= offset
;
529 /// Return offset for specified index
530 size_t CGPUProgramParams::getOffset(uint index
) const
532 if (index
>= m_Map
.size())
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())
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
);
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
;
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
;
581 nlassert(m_Meta
[offset
].Prev
!= s_End
);
582 m_Meta
[m_Meta
[offset
].Prev
].Next
= m_Meta
[offset
].Next
;
586 } /* namespace NL3D */