forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need some help regarding CLUT texture mode

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Tue Feb 07, 2006 6:29 pm    Post subject: Need some help regarding CLUT texture mode Reply with quote

Hello devs, I've got a problem with getting a CLUT4 program to run as it should.

First off, why does the following code crash, but the latter not?
Code:

unsigned short __attribute__((aligned(16))) g_font_clut[16];

void clut_color( long color ) {
   unsigned short* clut = (unsigned short*)(((unsigned short)g_font_clut)|0x40000000);
   int i;
   for (i=0;i<16;i++)
      *(clut++) = ((i) << 12) | (color & 0xFFF);
}


But this won't crash:
Code:

unsigned int __attribute__((aligned(16))) g_font_clut[16];

void clut_color( long color ) {
   unsigned short* clut = (unsigned short*)(((unsigned int)g_font_clut)|0x40000000);
   int i;
   for (i=0;i<16;i++)
      *(clut++) = ((i) << 12) | (color & 0xFFF);
}

I suppose it's with the alignment, so that an array[16] of unsigned short cannot be aligned the way needed (aligned to 64 byte?)? I just want to make sure. If so, the notes in the sdk should be updated with correct alignment infos.

Then the other problem is, my texture won't be drawn correctly and I dug it out to the fact, that all indices drawn by GU from the texture are 0, even though when I just read through the texture array and print every index as int to a textfile, it shows correctly. So the problem must lie either in the texture upload, or in the texture mode parameters. I load the texture data from a file btw.
Code:

unsigned char __attribute__((aligned(16))) g_font_tex[256*128];

void drawstuff()
{
      sceGuClutMode(GU_PSM_4444,0,0xff,0); // 16-bit palette
      sceGuClutLoad((16/8),g_font_clut); // upload 2*8 entries (16)
      sceGuTexMode(GU_PSM_T4,0,0,0); // 4-bit image
      sceGuTexImage(0,256,256,256,g_font_tex);
      sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA);
      sceGuTexFilter(GU_NEAREST,GU_NEAREST);
      sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
      sceGuEnable( GU_BLEND );
...
}


With this code, when I draw the whole texture on the screen, it's just completely transparent, but when I turn off blending, the whole rect is in the color chosen with clut_color. That's why all indices drawn must be zero (thus the alpha in the CLUT being 0).

EDIT: It's not a problem of the texture cash or DCash, as I just verified.

And for some clarification needs: What parameters am I really supposed to give the sceGuTexImage function with a 4bit indexed texture like above? Is the texture width and buffer width really 256 or should the one or the other be 128 (byte width)?

Thanks for your help :)
Back to top
View user's profile Send private message Visit poster's website
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Tue Feb 07, 2006 8:06 pm    Post subject: Reply with quote

The palette-generation code you wrote crashes because you cast the pointer into an unsigned short, which will drop the top 16 bits of the address. The pointer should be case into something that matches the pointer-size (like unsigned int on PSP).
_________________
GE Dominator
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Feb 08, 2006 6:15 am    Post subject: Reply with quote

Ah, yes I see. Could have found that myself 8) Thanks for the info.

Still there's the problem with the texture not showing up correctly... it's really a hinderness. Any ideas there?
Back to top
View user's profile Send private message Visit poster's website
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Wed Feb 08, 2006 8:17 am    Post subject: Reply with quote

I have a suspicion the "num_blocks" parameter of sceGuClutLoad() depends on the format of the clut entries, rather than being a fixed /8 scaling. Try an RGB8888 clut, and/or playing with the num blocks parameter.
Back to top
View user's profile Send private message Visit poster's website
NPherno



Joined: 08 Feb 2006
Posts: 4

PostPosted: Wed Feb 08, 2006 7:18 pm    Post subject: Various Palette/CLUT Notes... Reply with quote

First, the ClutMode command's 3rd param isn't unknown... as the docs I last saw stated... none of them are.

Here's the documentation as I am aware of it...

sceGuClutMode(CLUTFORMAT, shift, mask, startentry);

This means you could load an 8Bit Indexed Texture, but with some calls use only the top 4 bits, and in other modes, use the bottom (play with shift if you want to see the effects). mask is literaly, after an index read & shift, the value is masked. The problem comes when you don't set the mask correctly (which appears to be your issue...). You only want 16 values... why use a 256 value mask? 0xF instead of 0xFF may end up being the solution (I initially defaulted to 0xFFFFFFFF, but wow... that didn't work at all... I got _only_ the low 4 bits of each index... maybe handy for you? :)

The mask has an odd effect that I've sort of gotten at above... even a 4bit index texture can read _much_ larger values into the CLUT indexing pipe... because if you mask at 0xFF for a CLUT4, you are getting _2_ pixels of index data... if you didn't load the CLUT correctly, you may be refering to CLUT entries that are zero... and well out of the range you are expecting.

the start entry is great... it allows for palette animation (1 CLUT page at a time...etc). A value of 0 means 0... a value of 1 means something depending on what format the CLUT is in... 4444 would be a 16 value offset, 8888 would be 8... basicly the same rules as the ClutLoad entry count value...

ClutLoad appears to need a bit more info too...

The entry count is defined as 32 bytes per value... so for a 16bit CLUT entry, you want sceGuClutLoad(1, ptr), for 16 entries ('cause each is 2 bytes, right?). For a ABGR (8888) CLUT, a value of 1 would get you only 8 CLUT entries loaded... so for a full 256 entires at 8bit index... you'd need to say '32' instead of 1 =-]

And when all else fails... change the order you do your state changes. Upload the texture, then set the mode, the load CLUT, or maybe load then mode... try them out... if _shouldn't_ matter... but I tend to think when you aren't seeing straight a few swapped lines of code might be the answer, and they often don't hurt.

N
Back to top
View user's profile Send private message
NPherno



Joined: 08 Feb 2006
Posts: 4

PostPosted: Wed Feb 08, 2006 7:48 pm    Post subject: Methods... Reply with quote

I forgot to say much about how I determined most of this stuff...

First, when you load an 8bit image with a perfectly valid palette, and get _nothing_, you get creative :)

I setup my Palette loaded to fill the palette with a fully opaque color per entry, where the reds go up (0->255), and the blues go down (255->0)...

Every pixel of my texture was set to it's linear address. That way, I could see _something_, and begin to play with the various parameters of the mode/load/etc calls. After that, you end up with a very clean mental map (after a few hours) of how things work.

I often wonder how some programmers get along without a solid sense of problem solving and just general 'hacking' skills. There's an ordered way to resolve almost any unknown...

N
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Feb 08, 2006 8:28 pm    Post subject: Reply with quote

Nice, thanks for all the enlightening informations :) I appreciate it.
I also finally got everything to work as I wanted, even though I didn't change the mask or the parameter for number of clut entries (Now I wonder why it still works, at least the latter, since I use 16bit palette entries and have 16 entries, so there should be 2*16 = 32byte / 8 = 4 'entries' submitted, however I call it with 16/8 = 2?).
Well, in the end my problem was that when I tried to use the blit sdk sample program for testing my stuff, I hadn't applied the path to the texture to load correctly. After this and some more playing around with the parameters I got something to display and then it was rather easy to fix finally. Thanks for all the help :)

Yet, I still don't understand the use for the fourth parameter of sceGuTexImage. Is it really always the same as the texture width? Or is it supposed to help when the image you send has a wider linesize than the actual texture? Like with 24bit bitmaps where bytesperline nonetheless is a mutiple of 32bit?
Back to top
View user's profile Send private message Visit poster's website
NPherno



Joined: 08 Feb 2006
Posts: 4

PostPosted: Thu Feb 09, 2006 3:51 am    Post subject: Reply with quote

Raphael = (Now I wonder why it still works, at least the latter, since I use 16bit palette entries and have 16 entries, so there should be 2*16 = 32byte / 8 = 4 'entries' submitted, however I call it with 16/8 = 2?)

I am not sure how you are getting the math you're using? :)

32bytes is 1 'entry' to ClutLoad. You need 16 palette slots... which is 32bytes, which is _1_ entry. So you are uploading twice what you need to.

As for GuTexImage... the 4th param is _critical_ for not only non-power-of-2 sized textures, as it allows you to define a stride that is closer to the literal size of the texture (it's always aligned to 16 bytes, regardless of pixel format), but also because it allows for packing tricks... such as textures loaded 'around' another texture's dead space (you know that 32pixel wasted space around the main display buffer? you _can_ use that with this...).

N
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Thu Feb 09, 2006 6:31 am    Post subject: Reply with quote

I mixed up the 32byte per entry with 8byte per entry. D'oh. Well you're right, if the GU sees only every 32byte as one single entry, and I have a 16 color 16bit palette, I'm supposed to submit 1 as a parameter. So with my current method I submit twice the entries needed, what isn't a problem because I defined my clut double the size in the first place (by defining unsigned int g_font_clut[16] instead of unsigned short). Should fix that for consistency, even tough it works currently. Thanks :)

So the 4th param is like I supposed it to be. Yet I wonder if it is to be submitted as pixelspace size or bytesize, i.e. with my 4bit texture is it supposed to be 256 (pixelsize) or 128 (bytesize)? It seems to make no difference with my program, but that could just be by coincidence.

BTW: I'd like to get more to know about using the wasted space of the framebuffer if you have any information on that :) My first guess would be to create a pointer to the begin of the waste in the first line and then submit the image with parameters (0,32,BUF_HEIGHT,512, ... )?
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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