VFPU: vf2in and vi2f
VFPU: vf2in and vi2f
Does anyone know how the vf2in/vi2f functions work? Do they just convert a bunch of float values to int's/int's to float's, in the sense that after vf2in the VFPU regs now contain numbers coded like 32-bit signed int's instead of floats and I could then just store them back to memory and use as int's? Or in the case of vi2f I can just load int's into a VFPU register and that will convert them to floats?
If yes, that's SOOOOOOO great!!! :)
If yes, that's SOOOOOOO great!!! :)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Yes.
There are also other vf2i versions for different rounding methods. Dunno exactly from the top of my head though.
There are also other vf2i versions for different rounding methods. Dunno exactly from the top of my head though.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Thanks! :)
Now taking the opportunity, how do vmul/vdot/vdiv work? Do vmul and vdiv just multiply each part of the 2 vectors and put them at the respective place for the destination one? As for vdot, where does it put the result (since the dest reg is a vector)?
Also can the VFPU do Outer Products? If so, how?
Thanks in advance again :)
Now taking the opportunity, how do vmul/vdot/vdiv work? Do vmul and vdiv just multiply each part of the 2 vectors and put them at the respective place for the destination one? As for vdot, where does it put the result (since the dest reg is a vector)?
Also can the VFPU do Outer Products? If so, how?
Thanks in advance again :)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Yes.Tinnus wrote: Now taking the opportunity, how do vmul/vdot/vdiv work? Do vmul and vdiv just multiply each part of the 2 vectors and put them at the respective place for the destination one?
No, the destination register is a single register (s***).As for vdot, where does it put the result (since the dest reg is a vector)?
I suppose you refer to the cross-product of two 3D-vectors:Also can the VFPU do Outer Products? If so, how?
vcrsp.t
No problem :)Thanks in advance again :)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
OK. Last question :)
I just found out you can put a scale value in vf2i and vi2f, but can't you use a negative scale? ie: like you were doing a shift to the right.
I tried but the assembler complained about "improper scale: some-big-number". I think he expects an unsigned value and got a big number since -12 in unsigned codification would turn out big.
Being able to scale down would be great for fixed-point...
I just found out you can put a scale value in vf2i and vi2f, but can't you use a negative scale? ie: like you were doing a shift to the right.
I tried but the assembler complained about "improper scale: some-big-number". I think he expects an unsigned value and got a big number since -12 in unsigned codification would turn out big.
Being able to scale down would be great for fixed-point...
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Yeah, only positive shifts. You can work around that though, by loading a immediate into a single register (vim.s s000, 1024) and just scaling your vector with vscl.q by the reciprocal (vrcp.s s000, s000). In that case it would be the same as a shift right by 10 (though somewhat slower).Tinnus wrote:OK. Last question :)
I just found out you can put a scale value in vf2i and vi2f, but can't you use a negative scale? ie: like you were doing a shift to the right.
I tried but the assembler complained about "improper scale: some-big-number". I think he expects an unsigned value and got a big number since -12 in unsigned codification would turn out big.
Being able to scale down would be great for fixed-point...
PS: For what fixed-point when it's just a hassle to work with on vfpu? Why not use float?
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
mtv $rs, $rd // move to vector, $rs -> $rd, $rs = mips register, $rd = single vfpu register
mfv $rd, $rs // move from vector, $rs -> $rd, $rd =mips register, $rs = single vfpu register
mfv $rd, $rs // move from vector, $rs -> $rd, $rd =mips register, $rs = single vfpu register
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
You could dig them out from here: http://svn.ps2dev.org/filedetails.php?r ... rev=0&sc=0
Look under the "/* Sony Allegrex VFPU instructions. */" section.
Look under the "/* Sony Allegrex VFPU instructions. */" section.
adrahil wrote:You could dig them out from here: http://svn.ps2dev.org/filedetails.php?r ... rev=0&sc=0
Look under the "/* Sony Allegrex VFPU instructions. */" section.
Code: Select all
{"mtv", "t,?d0z", 0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2, 0, AL },
{"mfv", "t,?d0z", 0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0, AL },
{"vrcp.q", "?x3z,?s3y", 0xd0108080, 0xffff8080, RD_C2, 0, AL },
{"viim.s", "?t0d,j", 0xdf000000, 0xff800000, RD_C2, 0, AL },
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Some educated guessing plus try&error. I already thought about writing up all my findings so far to document the VFPU ops. Might be a good idea, but time-consuming.
vcmp stores the result of the compare in the cc (conditional register), which in turn can be checked on and branched with bc*f? (branch conditional* on false = if (!cc)) or bc*t? (branch conditional* on true = if (cc)) [I'm not sure what the possible l at the ? might mean]. There are versions for * = 0-3 (ie there are 4 conditional registers) but I'm yet to find out when exactly which one is used (I had luck with c1 in my current project).
The arguments of vcmp.* are CMP, rs, rd where CMP can be something like EQ (equals), LT/GT (lower/greater then), LE/GE (lower/greater or equal). rs and rd are single or vector registers, depending on * being .s or something else.
vcmp stores the result of the compare in the cc (conditional register), which in turn can be checked on and branched with bc*f? (branch conditional* on false = if (!cc)) or bc*t? (branch conditional* on true = if (cc)) [I'm not sure what the possible l at the ? might mean]. There are versions for * = 0-3 (ie there are 4 conditional registers) but I'm yet to find out when exactly which one is used (I had luck with c1 in my current project).
The arguments of vcmp.* are CMP, rs, rd where CMP can be something like EQ (equals), LT/GT (lower/greater then), LE/GE (lower/greater or equal). rs and rd are single or vector registers, depending on * being .s or something else.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
okay, let's try to make some synopsys :Raphael wrote:adrahil wrote:You could dig them out from here: http://svn.ps2dev.org/filedetails.php?r ... rev=0&sc=0
Look under the "/* Sony Allegrex VFPU instructions. */" section.They're all there, you just need to find them ;) (ps, I misspelled the viim.s instruction in my privious post)Code: Select all
{"mtv", "t,?d0z", 0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2, 0, AL }, {"mfv", "t,?d0z", 0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0, AL }, {"vrcp.q", "?x3z,?s3y", 0xd0108080, 0xffff8080, RD_C2, 0, AL }, {"viim.s", "?t0d,j", 0xdf000000, 0xff800000, RD_C2, 0, AL },
viim.s S000, 10 <==> S000 = 10;
vfim.s S000, 0.5 <==> S000 = 0.5;
mtv v0, S000 <==> S000= *((float *)&v0); // XFER W/O CONVERSION
mfv v0, S000 <==> v0 = *((int *)&S000); // XFER W/O CONVERSION
Am I right ?
What do the following instructions :
vi2f.s S000.s,S001.s,1
vf2in.s S000.s,S001.s,1
vf2iz.s S000.s,S001.s,1
vf2iu.s S000.s,S001.s,1
vf2id.s S000.s,S001.s,1
Code: Select all
{"vf2in.s", "?d0m,?s0s,?b", 0xd2000000, 0xffe08080, RD_C2, 0, AL },
{"vf2iz.s", "?d0m,?s0s,?b", 0xd2200000, 0xffe08080, RD_C2, 0, AL },
{"vf2iu.s", "?d0m,?s0s,?b", 0xd2400000, 0xffe08080, RD_C2, 0, AL },
{"vf2id.s", "?d0m,?s0s,?b", 0xd2600000, 0xffe08080, RD_C2, 0, AL },
{"vi2f.s", "?d0d,?s0w,?b", 0xd2800000, 0xffe08080, RD_C2, 0, AL },
i'm pretty clueless with "?b"
check this out:vi2f.s S000.s,S001.s,1
vf2in.s S000.s,S001.s,1
vf2iz.s S000.s,S001.s,1
vf2iu.s S000.s,S001.s,1
vf2id.s S000.s,S001.s,1
http://hitmen.c02.at/files/yapspd/psp_d ... tml#sec4.9
oh well, you may be sure it would be the first right place where I go to find my answers but this link DOESN'T answer my questions. That is, what are the exact operations of thoses instructions ? If someone does know it, it would be interesting to make it public here, because I did try them but I have curious results which don't help me.adrahil wrote:check this out:vi2f.s S000.s,S001.s,1
vf2in.s S000.s,S001.s,1
vf2iz.s S000.s,S001.s,1
vf2iu.s S000.s,S001.s,1
vf2id.s S000.s,S001.s,1
http://hitmen.c02.at/files/yapspd/psp_d ... tml#sec4.9
EDIT: ok, found some clues in vfpu_ops.h (libpspvgum)
Code: Select all
/*
+----------------------+-------------+----+---------------+---+--------------+
|31 21 | 20 16 | 15 | 14 8 | 7 | 6 0 |
+----------------------+-------------+----+---------------+---+--------------+
| opcode 0xd2200000 | scale[4-1] | | vfpu_rs[6-0] | | vfpu_rd[6-0] |
+----------------------+-------------+----+---------------+---+--------------+
Float to Int, Truncated
vf2iz.s %vfpu_rd, %vfpu_rs, scale ; Truncate and Convert Float to Integer (Single)
vf2iz.p %vfpu_rd, %vfpu_rs, scale ; Truncate and Convert Float to Integer (Pair)
vf2iz.t %vfpu_rd, %vfpu_rs, scale ; Truncate and Convert Float to Integer (Triple)
vf2iz.q %vfpu_rd, %vfpu_rs, scale ; Truncate and Convert Float to Integer (Quad)
%vfpu_rs: VFPU Vector Source Register ([s|p|t|q]reg 0..127)
%vfpu_rd: VFPU Vector Destination Register ([s|p|t|q]reg 0..127)
scale: Multiply by (2^scale) before converting to Float
vfpu_regs[%vfpu_rd] <- (int) (2^scale * vfpu_regs[%vfpu_rs])
*/
vi2f.* converts 32bit integers to floats, the last argument is a shift (by right afaik)hlide wrote:vi2f.s S000.s,S001.s,1
vf2in.s S000.s,S001.s,1
vf2iz.s S000.s,S001.s,1
vf2iu.s S000.s,S001.s,1
vf2id.s S000.s,S001.s,1
the vf2iX.* are float to int functions with different rounding methods.
n is nearest (round), (the rest I'm not sure any more, but should be easy to check out) z is trunc, u ceil and d floor. There the last argument is a shift left (done after the conversion I think).
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Thanx Raphael !
Should I need to convert a 3D vector of fix point (1, 27, 4) to a 3D vector of float for some calculations, do :
Should I need to convert a 3D vector of float to a 3D of fix point (1, 27, 4) f for storing purpose, do :
I'm not wrong, Am I ?
Should I need to convert a 3D vector of fix point (1, 27, 4) to a 3D vector of float for some calculations, do :
Code: Select all
ulv.t C000, 0(a0)
vi2f.t C000, C000, 4
... do some calculation with vfpu
Code: Select all
... do some calculation with vfpu
vf2iz.t C000, C000, 4
usv.t C000, 0(a0)
If you insist to store your vertices as ints (or are forced to), then you'd need to convert them yes, but I wouldn't recommend it. Better store everything as floats and work with them. Also note, that short/char vectors need an extra conversion step with vi2(u)s, vi2(u)c and reverse. Again, avoid those at any cost, it's ugly to work with them (but those conversions could come handy if you convert your internal models to non-float GU vertices for faster rendering).
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Well, emulation is one of the cases were you are forced, so yes :)hlide wrote:you're right, but as far as I know GTE (coprocessor 2 in PSX) use those kind of storage, so I was planning to use VFPU to emulate GTE.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl