VFPU: vf2in and vi2f

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

VFPU: vf2in and vi2f

Post by Tinnus »

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!!! :)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Yes.
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
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

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 :)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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?
Yes.
As for vdot, where does it put the result (since the dest reg is a vector)?
No, the destination register is a single register (s***).
Also can the VFPU do Outer Products? If so, how?
I suppose you refer to the cross-product of two 3D-vectors:
vcrsp.t
Thanks in advance again :)
No problem :)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

Yes I mean the cross product. And thanks for clarifying the dot product destination register and all the rest :)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

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...
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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...
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).

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
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

Because I'm working on emulating something that stores stuff internally as fixed-point.

Namely, one of the SNES coprocessors.

But that's not that big of a problem, I'll just do the >>'s in C after converting.
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

Just one more :)

Are there any instructions to move data to/from the general and VFPU registers? Or must I move data to memory first? (ugh)
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

Thanks again! :)

Now, do you know of any place I can get a *full* list of the VFPU ops? For example, none of the ones that I've seen until now have mfv/mtv/vcrsp/vim...
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

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.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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

&#123;"mtv",     "t,?d0z",		0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2,	0,		AL	&#125;,
&#123;"mfv",     "t,?d0z",		0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0,	AL	&#125;,
&#123;"vrcp.q",  "?x3z,?s3y",	0xd0108080, 0xffff8080, RD_C2,		0,		AL	&#125;,
&#123;"viim.s",  "?t0d,j",		0xdf000000, 0xff800000, RD_C2,		0,		AL	&#125;,
They're all there, you just need to find them ;) (ps, I misspelled the viim.s instruction in my privious post)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

Hmm, but how do I know what they do and what params they take?

Also any information on vcmp? I guess it does a comparison, but where is the result stored?
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

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.

Code: Select all

&#123;"mtv",     "t,?d0z",		0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2,	0,		AL	&#125;,
&#123;"mfv",     "t,?d0z",		0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0,	AL	&#125;,
&#123;"vrcp.q",  "?x3z,?s3y",	0xd0108080, 0xffff8080, RD_C2,		0,		AL	&#125;,
&#123;"viim.s",  "?t0d,j",		0xdf000000, 0xff800000, RD_C2,		0,		AL	&#125;,
They're all there, you just need to find them ;) (ps, I misspelled the viim.s instruction in my privious post)
okay, let's try to make some synopsys :

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

&#123;"vf2in.s", "?d0m,?s0s,?b",     0xd2000000, 0xffe08080, RD_C2,          0,              AL      &#125;,
&#123;"vf2iz.s", "?d0m,?s0s,?b",     0xd2200000, 0xffe08080, RD_C2,          0,              AL      &#125;,
&#123;"vf2iu.s", "?d0m,?s0s,?b",     0xd2400000, 0xffe08080, RD_C2,          0,              AL      &#125;,
&#123;"vf2id.s", "?d0m,?s0s,?b",     0xd2600000, 0xffe08080, RD_C2,          0,              AL      &#125;,
&#123;"vi2f.s",  "?d0d,?s0w,?b",     0xd2800000, 0xffe08080, RD_C2,          0,              AL      &#125;,

i'm pretty clueless with "?b"
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

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
check this out:
http://hitmen.c02.at/files/yapspd/psp_d ... tml#sec4.9
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

adrahil 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
check this out:
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.

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&#91;4-1&#93; |    | vfpu_rs&#91;6-0&#93;  |   | vfpu_rd&#91;6-0&#93; |
+----------------------+-------------+----+---------------+---+--------------+

  Float to Int, Truncated

    vf2iz.s %vfpu_rd, %vfpu_rs, scale   ; Truncate and Convert Float to Integer &#40;Single&#41;
    vf2iz.p %vfpu_rd, %vfpu_rs, scale   ; Truncate and Convert Float to Integer &#40;Pair&#41;
    vf2iz.t %vfpu_rd, %vfpu_rs, scale   ; Truncate and Convert Float to Integer &#40;Triple&#41;
    vf2iz.q %vfpu_rd, %vfpu_rs, scale   ; Truncate and Convert Float to Integer &#40;Quad&#41;

        %vfpu_rs&#58;	VFPU Vector Source Register &#40;&#91;s|p|t|q&#93;reg 0..127&#41;
        %vfpu_rd&#58;	VFPU Vector Destination Register &#40;&#91;s|p|t|q&#93;reg 0..127&#41;
        scale&#58;		Multiply by &#40;2^scale&#41; before converting to Float

    vfpu_regs&#91;%vfpu_rd&#93; <- &#40;int&#41; &#40;2^scale * vfpu_regs&#91;%vfpu_rs&#93;&#41;
*/
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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
vi2f.* converts 32bit integers to floats, the last argument is a shift (by right afaik)
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
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

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 :

Code: Select all

ulv.t   C000, 0&#40;a0&#41;
vi2f.t  C000, C000, 4
... do some calculation with vfpu
Should I need to convert a 3D vector of float to a 3D of fix point (1, 27, 4) f for storing purpose, do :

Code: Select all

... do some calculation with vfpu
vf2iz.t C000, C000, 4
usv.t   C000, 0&#40;a0&#41;
I'm not wrong, Am I ?
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

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.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

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.
Well, emulation is one of the cases were you are forced, so yes :)
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Post Reply