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 

Problem with 4Bit Palletised Textures

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



Joined: 18 May 2008
Posts: 53

PostPosted: Tue May 05, 2009 7:28 pm    Post subject: Problem with 4Bit Palletised Textures Reply with quote

I was working on some texture conversion issues recently(I fixed one already) and I am having trouble locating the problem. The problem is with the N64's CI4 (4Bit Palletised) texture format the alpha when is not showing up... I've read about bugs using the GU_PSM_T4(thought it was the same) format and this is the format used by the CI4 format to display it. Could this/these bugs be affecting the alpha. If so what can be done? Should CI8 and GU_PSM_T8 have the same issue?(I don't think they do... but there is another issue there.)

BTW: It was J.F.'s thread here: http://forums.ps2dev.org/viewtopic.php?t=3741&postdays=0&postorder=asc&start=300 that clued me there might be a problem with using GU_PSM_T4. Anyone have his 4 to 8 bit palletised conversion code? (It might solve my problem as well.)
[/url]
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Wed May 06, 2009 4:58 am    Post subject: Reply with quote

The "problem" is with the pixel order. As per definition, four bit mode uses four bits for the palette index. That means there are two pixels in every byte. There are two ways that you can put two pixels into a byte: the first pixel can be bits 7 to 4 (msb to lsb), with the second being bits 3 to 0... this is the format everything I've ever worked on EXCEPT the PSP uses. What the PSP does is make the first pixel bits 3 to 0, and the second bits 7 to 4. This is the pixel data, not the palette. So when converting from a platform that uses the "normal" pixel order, you have to swap the nibbles of every byte (nibbles being four bits).

So is your problem with the palette, or the data? Having the nibbles in the wrong order means the image looks funny - a bit blurry with the edges wrong. The colors and alpha are correct as the palette isn't the problem. If you're having a problem with the colors and alpha, you may not be loading the palette before the rendering correctly. Maybe your offset and mask is wrong, or maybe you have the fields in the wrong order (remember that the N64 is big endian).
Back to top
View user's profile Send private message AIM Address
Kreationz



Joined: 18 May 2008
Posts: 53

PostPosted: Wed May 06, 2009 8:39 am    Post subject: Reply with quote

I think it may be the offset or the mask. I'm going through the code and the Problem is the Alpha not showing under palletised textures.

Edit: They show correct in the debugger, but are not rendered correctly.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Wed May 06, 2009 11:42 am    Post subject: Reply with quote

Or maybe you don't have the blend mode set right. Try looking at one of the alpha examples... look that you have all the enables and whatnot set correctly.
Back to top
View user's profile Send private message AIM Address
Kreationz



Joined: 18 May 2008
Posts: 53

PostPosted: Wed May 06, 2009 3:57 pm    Post subject: Reply with quote

J.F. wrote:
Or maybe you don't have the blend mode set right. Try looking at one of the alpha examples... look that you have all the enables and whatnot set correctly.


No, I know it's not a blend mode issue... it's either texture conversion or a core combiner issue. (Which could also be possible) I'm in the process of using Rice's code to help me rewrite and update DaedalusX64's. I fixed a conversion bug affecting OoT and other that had to do with the alpha and figured this was a similar issue. Those textures loaded correctly but the alpha got lost converting them to PSP format. The the Rev 359 changes below:

Old Code:
Code:
   static inline void ConvertRow( OutT * p_dst, const u8 * p_src_base, u32 offset, u32 width )
   {
      // Do two pixels at a time
      for (u32 x = 0; x < width; x+=2)
      {
         u8 b = p_src_base[offset ^ F];

         // Even
         p_dst[x + 0] = OutT( TwoToEight[(b & 0xc0) >> 6],
                         TwoToEight[(b & 0xc0) >> 6],
                         TwoToEight[(b & 0xc0) >> 6],
                         TwoToEight[(b & 0x30) >> 4] );   
         // Odd
         p_dst[x + 1] = OutT( TwoToEight[(b & 0x0c) >> 2],
                         TwoToEight[(b & 0x0c) >> 2],
                         TwoToEight[(b & 0x0c) >> 2],
                         TwoToEight[(b & 0x03)     ] );
         offset++;
      }

      if(width & 1)
      {
         u8 b = p_src_base[offset ^ F];

         // Even
         p_dst[width-1] = OutT( TwoToEight[(b & 0xc0) >> 6],
                           TwoToEight[(b & 0xc0) >> 6],
                           TwoToEight[(b & 0xc0) >> 6],
                           TwoToEight[(b & 0x30) >> 4] );   
      }


Became:

Code:
   static inline void ConvertRow( OutT * p_dst, const u8 * p_src_base, u32 offset, u32 width )
   {
      // Do two pixels at a time
      for (u32 x = 0; x < width; x+=2)
      {
         u8 b = p_src_base[offset ^ F];

         // Even
         p_dst[x + 0] = OutT( ThreeToEight[(b & 0xE0) >> 5],
                         ThreeToEight[(b & 0xE0) >> 5],
                         ThreeToEight[(b & 0xE0) >> 5],
                         OneToEight[(b & 0x10)   >> 4]);   
         // Odd
         p_dst[x + 1] = OutT( ThreeToEight[(b & 0x0E) >> 1],
                         ThreeToEight[(b & 0x0E) >> 1],
                         ThreeToEight[(b & 0x0E) >> 1],
                         OneToEight[(b & 0x01)     ] );
         offset++;
      }

      if(width & 1)
      {
         u8 b = p_src_base[offset ^ F];

         // Even
         p_dst[width-1] = OutT( ThreeToEight[(b & 0xE0) >> 5],
                         ThreeToEight[(b & 0xE0) >> 5],
                         ThreeToEight[(b & 0xE0) >> 5],
                         OneToEight[(b & 0x10)   >> 4]);   
      }
   }


Also had to add the stuff for ThreeToEight and OneToEight. It was causing the Alpha to get lost and the colors to be slightly off. I'm still thinking it's the same problem with the palletised textures, but there is a chance the Alpha is getting lost in the combiner but not likely.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Wed May 06, 2009 5:26 pm    Post subject: Reply with quote

Well, look at the four bit refresh in B2:

Code:
static unsigned int list[16384] __attribute__((aligned(16)));

struct texVertex
{
   unsigned short u, v;
   short x, y, z;
};

static void refresh4(void)
{
    int32 BLOCKH = 64;
    int32 BLOCKV = psp_screen_y <= 512 ? psp_screen_y : psp_screen_y / 2;
    int32 i, j;
   struct texVertex *vertices;

    // Mac 4bit chunky to PSP 4bit chunky
    uint32 *sp = (uint32 *)the_buffer;
    uint32 *dp = (uint32 *)((uint32)the_buffer + 768*576/2);
    for (j=0; j<576; j++)
        for (i=0; i<768/8; i++)
        {
            uint32 v = sp[j*768/8 + i];
            dp[j*768/8 + i] = (v>>4)&0x0F0F0F0F | (v<<4)&0xF0F0F0F0;
        }

   sceGuStart(GU_DIRECT,list);
   sceGuClutMode(GU_PSM_8888,0,0x0F,0);           // 32-bit palette, shift = 0, mask = 0x0F, start = 0
   sceGuClutLoad((16/(32/4)),clut256);             // upload 2 blocks (each block is 32 bytes / bytesPerColorEntry)
   sceGuEnable(GU_TEXTURE_2D);
   sceGuTexMode(GU_PSM_T4,0,0,0);
   sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
   sceGuTexFilter(GU_LINEAR, GU_LINEAR);

    for (j=0; j<psp_screen_y/BLOCKV; j++)
        for (i=0; i<psp_screen_x/BLOCKH; i++)
        {
            // set the texture block
            uint32 ts = (uint32)the_buffer + 768*576/2 + j * BLOCKV * 768 / 2 + i * BLOCKH / 2;
            sceGuTexImage(0, BLOCKH, 512, 768, (void *)ts);
            sceGuTexSync();

            vertices = (struct texVertex*)sceGuGetMemory(2 * sizeof(struct texVertex));
            // now draw the block with scaling
         vertices[0].u = 0;
            vertices[1].u = BLOCKH;

            vertices[0].v = 0;
            vertices[1].v = BLOCKV;

            vertices[0].x = d_x + i * BLOCKH * d_w / psp_screen_x;
            vertices[1].x = d_x + (i+1) * BLOCKH * d_w / psp_screen_x;

            if (vertices[1].x > (d_x + d_w))
                vertices[1].x = (d_x + d_w);

            vertices[0].y = d_y + j * BLOCKV * d_h / psp_screen_y;
            vertices[1].y = d_y + (j+1) * BLOCKV * d_h / psp_screen_y;

            if (vertices[1].y > (d_y + d_h))
                vertices[1].y = (d_y + d_h);

            vertices[0].z = 0;
            vertices[1].z = 0;

            sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D, 2,0,vertices);
        }
}


The 16 color palette is just the first sixteen entries of the 256 color palette. The important lines are:

Code:
   sceGuStart(GU_DIRECT,list);
   sceGuClutMode(GU_PSM_8888,0,0x0F,0);           // 32-bit palette, shift = 0, mask = 0x0F, start = 0
   sceGuClutLoad((16/(32/4)),clut256);             // upload 2 blocks (each block is 32 bytes / bytesPerColorEntry)
   sceGuEnable(GU_TEXTURE_2D);
   sceGuTexMode(GU_PSM_T4,0,0,0);
   sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
   sceGuTexFilter(GU_LINEAR, GU_LINEAR);


Note how we set the shift, mask, and offset into the palette, then load 2 blocks of palette entries. Note the texture mode is set to T4. Other than that, everything is pretty much the same as any other texture operation.

Note how the code starts by reversing the pixels in the bytes that make the source:

Code:
    for (j=0; j<576; j++)
        for (i=0; i<768/8; i++)
        {
            uint32 v = sp[j*768/8 + i];
            dp[j*768/8 + i] = (v>>4)&0x0F0F0F0F | (v<<4)&0xF0F0F0F0;
        }


That's that wacko PSP pixel order issue I was talking about. You can flip your pixels when the texture is built.
Back to top
View user's profile Send private message AIM Address
Kreationz



Joined: 18 May 2008
Posts: 53

PostPosted: Mon May 25, 2009 3:09 pm    Post subject: Reply with quote

Turns out it is in a combination of the combiner and the renderer.
Back to top
View user's profile Send private message
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