![]() |
| [[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]] |
|
|
#1 |
|
Posts: n/a
|
The other day with a co-worker (Leo Benaducci) we started a small contest: adding support for the swizzle operator, available in shader languages (hlsl, cg, glsl), to any standard Vector 2, 3 or 4 class in C++. Something like:
Code:
Leo swizzle with mini vector3 class: Code:
Code:
My version only uses macros, but has additional support for any operation (not just copying) and can use any vector 2, 3, or 4 classes. The only requirement is that vector class implements the [] operator to access vector elements. Enlight swizzle: Code:
Code:
Have fun! Enlight. |
|
|
|
#2 |
|
Valued Member
Join Date: Nov 2004
Location: Milan -ITALY-
Posts: 297
|
Within Leo's template:
Code:
Ciao ciao : )
___________________________________________
-Nautilus 1.551640271931635485e+1292913986 ? Why, that's: 2 ^ ((2 ^ (2 ^ ((2 ^ 2) + (2 ^ (2 - 2))))) - (2 ^ (2 - 2))). Now verify, please... |
|
|
|
|
|
#3 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
I believe that if statement is checking the endianness of the machine. You see it sets an integer to 255 and then checks its first byte, which will be 255 on a little-endian machine and 0 on a big-endian one.
However, the cast should really be to unsigned char, as signed char can't hold the value 255 (although bitwise-and may be ignoring signed/unsigned differences anyway).
___________________________________________
Currently working at Sucker Punch reedbeta.com - OpenGL demos and other projects Luabridge - a lightweight, dependency-free C++/Lua binding library. CD Lite - an unobtrusive, minimal CD player application for Windows. |
|
|
|
|
|
#4 |
|
Valued Member
Join Date: Nov 2004
Location: Milan -ITALY-
Posts: 297
|
I didn't notice. Right you are.
Ciao ciao : )
___________________________________________
-Nautilus 1.551640271931635485e+1292913986 ? Why, that's: 2 ^ ((2 ^ (2 ^ ((2 ^ 2) + (2 ^ (2 - 2))))) - (2 ^ (2 - 2))). Now verify, please... |
|
|
|
|
|
#5 |
|
DevMaster Staff
Join Date: Sep 2005
Location: The Netherlands
Posts: 1,442
|
Hmm, it looks a bit inefficient with the strings and all. For the second implementation, you should at least put the code of the macro's inside a do {...} while(0) block. Otherwise you could get in serious problems when using things like if-statments without braces.
My version: Code:
Of course you could generate combinations like _xxy etc. to get rid of the comma's. The cool thing of this implementation is that, because it uses compile-time constants, you could even make use of compiler instrinsics to permute actual SSE registers.
___________________________________________
C++ addict - Currently working on: the 3D engine for Tomb Raider: Underworld and Deus Ex 3. |
|
|
|
|
|
#6 |
|
New Member
Join Date: Jun 2007
Location: Argentina
Posts: 25
|
Not inefficient at all. Check the assembler output. Do the code as you wish, the assembly output is perfect in both cases, although I didn't tried your code...
|
|
|
|
|
|
#7 |
|
New Member
Join Date: Aug 2008
Posts: 3
|
i'm not sure why you say that, check the generated asm
Code:
do you think there is a faster way to do this? |
|
|
|
|
|
#8 |
|
New Member
Join Date: Aug 2008
Location: Argentina
Posts: 1
|
I Like most Leo's Solution, seems to be more clear for the programmer, at least for me (a noob one
), and more OO kind.Greetings! |
|
|
|
|
|
#9 |
|
Senior Member
Join Date: Aug 2004
Location: Århus, Denmark
Posts: 688
|
They both suffer from the fact that they rely on strings:
b.swz(aaa, a, bbb); SW4(a,beer,=,b,good); both statements will compile just fine, and chrash at runtime.
___________________________________________
"Stupid bug! You go squish now!!" - Homer Simpson |
|
|
|
|
|
#10 |
|
New Member
Join Date: Aug 2008
Posts: 3
|
sorry, but both codes can send compile time asserts
|
|
|
|
|
|
#11 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
Kenneth's right; there's no compile-time protection against using letters outside the 'w' to 'z' range. Although with the Enlight version, due to the '& 3' in the macro, any other letters will get silently remapped into the 'w'-'z' range; that's slightly better than the Leo version, in which other letters will result in runtime out-of-bounds array accesses.
To fix this, you could add compile-time asserts that each character is within the expected range. Here is a bit of code to do a compile-time assert (from boost): Code:
(The real one is slightly more complicated, as it is designed to work outside of a function scope, but that gives you the idea.)
___________________________________________
Currently working at Sucker Punch reedbeta.com - OpenGL demos and other projects Luabridge - a lightweight, dependency-free C++/Lua binding library. CD Lite - an unobtrusive, minimal CD player application for Windows. |
|
|
|
|
|
#12 |
|
New Member
Join Date: Aug 2008
Posts: 3
|
here is it, out of bounds protection
Code:
and the asm Code:
Last edited by leobenaducci : 08-01-2008 at 03:34 PM. |
|
|
|
|
|
#13 | |
|
Senior Member
Join Date: Aug 2004
Location: Århus, Denmark
Posts: 688
|
Quote:
![]() Anyways, I tried to create some kind of swizzle support for a float4 class I was working on, but didn't have much luck. After seeing this thread, I decided to go back and give it another go, and finally succeeded. Here it is, in its entirety: Code:
Using the supplied defines, it is now possible to write code like this (which is pretty close to Cg): Code:
which results in the following output: 'f1' : 1.000000, 2.000000, 3.000000, 4.000000And finally, the generated assembly (without all the printf calls): Code:
___________________________________________
"Stupid bug! You go squish now!!" - Homer Simpson Last edited by Kenneth Gorking : 08-02-2008 at 06:49 AM. |
|
|
|
|
|
|
#14 |
|
Senior Member
Join Date: Aug 2004
Location: Århus, Denmark
Posts: 688
|
A small adendum to the above: Instead of the single 'shuffle' function, there should be two. A read-only, and a read-write version.
Code:
This way you can't accidentally perform operations like 'v1.xyxy = float4(1234)'
___________________________________________
"Stupid bug! You go squish now!!" - Homer Simpson |
|
|
|
|
|
#15 | |
|
New Member
Join Date: Jun 2007
Location: Argentina
Posts: 25
|
Quote:
No, it is fine! It should NOT compile anything because it has bad syntax: Code:
Now, about your work on the swizzle operator, I'm just amazed, I didn't imagine someone would get *that* far... I didn't try it out yet, but looks amazing, great work, specially for using 128 bit registers. |
|
|
|
|
|
|
#16 | ||
|
Senior Member
Join Date: Aug 2004
Location: Århus, Denmark
Posts: 688
|
Quote:
![]() Instead of just doing nothing, maybe you should use a compile-time assert to alert the user to his mistake? Quote:
![]()
___________________________________________
"Stupid bug! You go squish now!!" - Homer Simpson |
||
|
|
|
|
|
#17 |
|
DevMaster Staff
Join Date: Sep 2005
Location: The Netherlands
Posts: 1,442
|
Btw, it's pretty pointless to make template integer arguments const
![]()
___________________________________________
C++ addict - Currently working on: the 3D engine for Tomb Raider: Underworld and Deus Ex 3. |
|
|
|
|
|
#18 |
|
New Member
Join Date: Mar 2006
Posts: 26
|
I have also implemented swizzle operator in my math library (glm.g-truc.net)
My implementation is based on a third party class that only contain references. My implementation is based on GLSL syntax so that we could do something like this: vec4 v1(1, 2, 3, 4); vec4 v2(1); v2.yzx = v1.xyz + v1.yzx; Here is some detail of the implementation... so annoying to do because of the #defines like yzx that wrap function calls. I have no SSE optimization yet for this. I will definitely come back on this post to have a closer look of your implementation! ![]() Enjoy: Code:
Last edited by Reedbeta : 08-07-2008 at 10:09 AM. |
|
|
|
|
|
#19 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
Groove, thanks for your post, but please use the [code]...[/code] tags.
![]()
___________________________________________
Currently working at Sucker Punch reedbeta.com - OpenGL demos and other projects Luabridge - a lightweight, dependency-free C++/Lua binding library. CD Lite - an unobtrusive, minimal CD player application for Windows. |
|
|
|
|
|
#20 |
|
New Member
Join Date: Mar 2006
Posts: 26
|
Sorry for that I'll try to remember for next time !
Thanks ! |
|
|
|
|
|
#21 |
|
New Member
Join Date: Sep 2008
Location: Vancouver
Posts: 1
|
Hi Groove,
Wouldn't using the intermediate references cause pointers to be created and extra overhead in the assembly code? The GLM library looks awesome! Keep up the good work. Eric |
|
|
|
|
|
#22 |
|
New Member
Join Date: Mar 2006
Posts: 26
|
Some people were already afraid of that but using references provide to compiler that support cross function optimizations to just skip them all:
Have a look on this: vec2 v1(1.0); vec2 v2(2.0); vec2 v3(3.0); The following is just the asm code for this line: v1.xy = vec2(v2.xy) + vec2(v3.xy); GCC 3.4.5: Code:
GCC 4.3.0: Code:
with SSE Code:
VC8 Code:
With SSE Code:
GCC 3.4.5 show the problem you point. But GCC 3.x didn't supported cross function optimizations. It gets available since GCC 4.1 I think. Maybe some with GCC 4.0. With Vistua Studioit is supported for ages, even Visual C++ 6 but I'm not sure, under the name whole program optimizations. I'm doing my best to keep up GLM and GLM 0.8.x will be a good step for this. GLSL 1.30 support indeed but also lot of internal improvements ![]() |
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|