 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Mon Apr 07, 2008 4:58 am Post subject: [WIP] A very special (and weird) template library for VFPU |
|
|
I'm working on a special VFPU lib for C++, using template classes a lot.
The main idea is to let g++ to allocate vfpu registers and try to compute without the need to struggle with the assembly code. But the drawback is the way you write the algorithm using vfpu, because it would appear to most people very weird.
that code :
| Code: |
#include "vfpu.h"
extern "C" void vector2d_sample_linear(float *vector_result, float *vector_source, float *vector_target, float &alpha)
{
// load scalar alpha in a new register
typedef vfpu_scalar_load< vfpu_scalar_new_reg < > >
load_alpha, step1;
// load 2d vector source in a new register
typedef vfpu_vector_2d_load< vfpu_vector_new_reg < step1 > >
load_vector_source, step2;
// load 2d vector target in a new register
typedef vfpu_vector_2d_load< vfpu_vector_new_reg < step2 > >
load_vector_target, step3;
// saturated one's complement : { 1-alpha, alpha } = { (1.0 - alpha)[0..1], alpha[0..1] }
typedef vfpu_vector_2d_socp_result< load_alpha, step3 >
compute_alpha_and_one_minus_alpha, step4;
typedef vfpu_vector_2d_scl_result< load_vector_source, vfpu_vector_2d_component< compute_alpha_and_one_minus_alpha, 0 >, step4 >
scale_source_vector_with_one_minus_alpha, step5;
typedef vfpu_vector_2d_scl_result< load_vector_target, vfpu_vector_2d_component< compute_alpha_and_one_minus_alpha, 1 >, step5 >
scale_target_vector_with_alpha, step6;
// Vs * (1.0 - alpha)[0..1] + Vd * alpha[0..1]
typedef vfpu_vector_2d_add_result< scale_source_vector_with_one_minus_alpha, scale_target_vector_with_alpha, step6 >
add_vectors_source_and_target, step7;
// and store to vector result
typedef vfpu_vector_2d_store< add_vectors_source_and_target, step7 >
store_vector_result;
// execute
load_alpha _1(alpha);
load_vector_source _2(*vector_source);
load_vector_target _3(*vector_target);
compute_alpha_and_one_minus_alpha();
scale_source_vector_with_one_minus_alpha();
scale_target_vector_with_alpha();
add_vectors_source_and_target();
store_vector_result _(*vector_result);
} |
gives me :
| Code: | 00000018 <vector2d_sample_linear>:
// load scalar alpha in a new register
18: c8e00000 lv.s S000.s,0(a3)
// load 2d vector source in a new register
1c: c8a10000 lv.s S010.s,0(a1)
20: c8a10005 lv.s S011.s,4(a1)
// load 2d vector target in a new register
24: c8c20000 lv.s S020.s,0(a2)
28: c8c20005 lv.s S021.s,4(a2)
// saturated one's complement : { 1-alpha, alpha } = { (1.0 - alpha)[0..1], alpha[0..1] }
2c: d0450103 vsocp.s C030.p,S000.s
// scale vector source with 1-alpha
30: 65030184 vscl.p C100.p,C010.p,S030.s
// scale vector target with alpha
34: 65230285 vscl.p C110.p,C020.p,S031.s
// add vectors source and target to vector result
38: 60050486 vadd.p C120.p,C100.p,C110.p
// store vector result
3c: e8860000 sv.s S120.s,0(a0)
40: e8860005 sv.s S121.s,4(a0)
// exit function
44: 03e00008 jr ra
48: 00000000 nop |
which is pretty good for what i was expected.
I dunno if somebody may be interested in this library.
Sure, there is still a lot of job to do.
NOTE :
any vfpu_vector_2d_XXX template class has an optional template parameter named "clobbered" (those ones named "stepN" in my example) which allows g++ to remember which VFPU registers were "allocated". This is the main reason why we need so many typedefs and this weird syntax. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Thu Apr 10, 2008 8:21 am Post subject: |
|
|
in loop, it is not bad :
| Code: | extern "C" void vector_2d_sample_linear(float *vector_result, float *vector_source, float *vector_target, float &alpha, int n)
{
typedef vfpu_vector_new_register< > vector_source_reg;
typedef vfpu_vector_new_register< vector_source_reg > vector_target_reg;
typedef vfpu_scalar_new_register< vector_target_reg > alpha_reg;
// saturated one's complement : { 1-alpha, alpha } = { (1.0 - K)[0..1], K[0..1] }
typedef vfpu_vector_2d_socp_result< alpha_reg >
alpha_and_one_minus_alpha;
typedef vfpu_vector_2d_scl_result< vector_source_reg, vfpu_vector_2d_component< alpha_and_one_minus_alpha, 0 > >
scaled_vector_source_with_one_minus_alpha;
typedef vfpu_vector_2d_scl_result< vector_target_reg, vfpu_vector_2d_component< alpha_and_one_minus_alpha, 1 >, scaled_vector_source_with_one_minus_alpha >
scaled_vector_target_with_alpha;
// Vs * (1.0 - K)[0..1] + Vd * K[0..1]
typedef vfpu_vector_2d_add_result< scaled_vector_source_with_one_minus_alpha, scaled_vector_target_with_alpha >
result;
// load alpha
vfpu_scalar_load(alpha_reg(), alpha);
// saturate alpha between 0 and 1 then compute one minus alpha
alpha_and_one_minus_alpha();
// for n vectors
for (int i = 0; i < n; vector_result+=2)
{
// load source and target vectors
vfpu_vector_2d_load(vector_source_reg(), vector_source[0], vector_source[1]);
vfpu_vector_2d_load(vector_target_reg(), vector_target[0], vector_target[1]);
vector_source+=2;
// compute new source and target vectors
scaled_vector_source_with_one_minus_alpha();
scaled_vector_target_with_alpha();
vector_target+=2;
++i;
// and add them to get the result vector
vfpu_vector_2d_store(result(), vector_result[0], vector_result[1]);
}
} |
gives me :
| Code: | 00000030 <vector_2d_sample_linear>:
30: c8e20000 lv.s S020.s,0(a3)
34: d0450203 vsocp.s C030.p,S020.s
38: 1900000f blez t0,78 <vector_2d_sample_linear+0x48>
3c: 00001021 move v0,zero
40: c8a00000 lv.s S000.s,0(a1)
44: c8a00005 lv.s S001.s,4(a1)
48: c8c10000 lv.s S010.s,0(a2)
4c: c8c10005 lv.s S011.s,4(a2)
50: 24a50008 addiu a1,a1,8
54: 65030084 vscl.p C100.p,C000.p,S030.s
58: 65230185 vscl.p C110.p,C010.p,S031.s
5c: 24c60008 addiu a2,a2,8
60: 24420001 addiu v0,v0,1
64: 60050486 vadd.p C120.p,C100.p,C110.p
68: e8860000 sv.s S120.s,0(a0)
6c: e8860005 sv.s S121.s,4(a0)
70: 1502fff3 bne t0,v0,40 <vector_2d_sample_linear+0x10>
74: 24840008 addiu a0,a0,8
78: 03e00008 jr ra
7c: 00000000 nop |
some integer increments are inserted between vfpu instruction, that's very good for reducing lantency between vfpu instructions.
Last edited by hlide on Fri Apr 11, 2008 5:59 am; edited 1 time in total |
|
| Back to top |
|
 |
gauri
Joined: 20 Jan 2008 Posts: 35 Location: Belarus
|
Posted: Thu Apr 10, 2008 3:42 pm Post subject: |
|
|
so implementin intrinsics didn't prove itself really feasible?
can you share the whole library? i'm really interested in that. _________________ Freelance game industry veteran. 8] |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Fri Apr 11, 2008 5:56 am Post subject: |
|
|
| gauri wrote: | so implementin intrinsics didn't prove itself really feasible?
can you share the whole library? i'm really interested in that. |
this is a very HUGE work to add intrinsics.
I plan to share this library as soon as possible. But it is too early to release it as I want to experiment with it and find different ways to implement this library in the most efficient way. When I started it that last weekend, I was just playing and I didn't really expect such a result without having to tweak psp-gcc for vfpu.
By the way, it seems psp-as is buggy for vfpu :
"vmov.p C010, C002" works fine but not "vmov.p $1, $64" whereas they are strictly the same thing. I have an error with a vfpu register $64 or above. It is such a pity because I really need to use the '$' register notation for my library. :/ |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Mon Apr 21, 2008 11:09 am Post subject: |
|
|
| gauri wrote: | so implementin intrinsics didn't prove itself really feasible?
can you share the whole library? i'm really interested in that. |
ok, still not complete. I was mainly trying to make a 2d lib using vfpu but there is no reason not to extend it to a 3d or quaternion lib. I'm not totally satisfied with it, but i can see it as a good start.
svn://svn2.assembla.com/svn/pspvftl/trunk/pspvftl/ |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|