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 

Fast 565 RGB->BGR Conversion Needed
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Wed Oct 12, 2005 2:12 pm    Post subject: Fast 565 RGB->BGR Conversion Needed Reply with quote

Does anyone have code for quickly converting RGB to BGR on the fly. The best I've been able to make is this (and the color is still somewhat off):
Code:
// Color correction (aligned)
u32 *fbcc = (u32 *)PspFrameBuffer;
u32 *fbcce = (u32 *)(PspFrameBuffer + ((SCREEN_WIDTH * SCREEN_HEIGHT) >> 1));
while (fbcc < fbcce)
{
   *fbcc = (*fbcc & 0x07e007e0) | ((*fbcc & 0xf800f800) >> 11) | ((*fbcc & 0x001f001f) << 11);
   fbcc++;
}

Any help would be greatly appreciated. And feel free to suggest crazy GU or assembly functions that I've never even dreamed of.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Wed Oct 12, 2005 5:26 pm    Post subject: Re: Fast 565 RGB->BGR Conversion Needed Reply with quote

ChaosKnight wrote:
Does anyone have code for quickly converting RGB to BGR on the fly. The best I've been able to make is this (and the color is still somewhat off):

First question is whether you're using cached or uncached pointers here. Is this the real framebuffer, or something in system memory? Because uncached reads are going to be pretty slow.

The other thing you should do is read the value into a local before playing with it:
Code:
{
    u32 pix = *fbcc;
    *fbcc = (pix & 0x07e007e0) | ((pix & 0xf800f800) >> 11) | ((pix & 0x001f001f) << 11);
}


Also, its unclear what SCREEN_WIDTH is. If you're using the real framebuffer, which has a width of 512 pixels, then you'll end up converting quite a few invisible ones, since only 480 are visible.

The VFPU may have instructions to help with this, or at least be able to operate in larger chunks. That will need more investigation though.
Back to top
View user's profile Send private message Visit poster's website
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Wed Oct 12, 2005 9:31 pm    Post subject: Re: Fast 565 RGB->BGR Conversion Needed Reply with quote

jsgf wrote:
First question is whether you're using cached or uncached pointers here. Is this the real framebuffer, or something in system memory? Because uncached reads are going to be pretty slow.

This is not the real framebuffer, but rather in system memory.
jsgf wrote:
Also, its unclear what SCREEN_WIDTH is. If you're using the real framebuffer, which has a width of 512 pixels, then you'll end up converting quite a few invisible ones, since only 480 are visible.

SCREEN_WIDTH = 480, HEIGHT = 272.

To be honest, at this point my problem is not so much speed as it is the conversion itself does not result in the proper colors being generated. It's close, but not exact. I have very little experiance with 565 comparitively speaking to my experiance with 8 bit or 24/32 bit modes. The 565 packing is still quite foriegn to me.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
Saotome



Joined: 03 Apr 2004
Posts: 182

PostPosted: Wed Oct 12, 2005 9:55 pm    Post subject: Reply with quote

jsgf wrote:
The other thing you should do is read the value into a local before playing with it

actually the compiler does that allready (I've checked the generated asm code).

but that should be faster:
Code:

   u32 pix0,pix1;
   // Color correction (aligned)
   u32 *fbcc = (u32 *)PspFrameBuffer;
   u32 *fbcce = (u32 *)(PspFrameBuffer + ((SCREEN_WIDTH * SCREEN_HEIGHT) >> 1));
   while (fbcc < fbcce)
   {
      pix0 = *fbcc;
      pix1 = *(fbcc+1);
      *fbcc = (pix0 & 0x07e007e0) | ((pix0 & 0xf800f800) >> 11) | ((pix0 & 0x001f001f) << 11);
      *(fbcc+1) = (pix1 & 0x07e007e0) | ((pix1 & 0xf800f800) >> 11) | ((pix1 & 0x001f001f) << 11);
      fbcc += 2;
      
   }

the compiler interleaves the two "instruction streams" so that most of the instructions are executed as a pair (in one cycle). see here for more info.

ChaosKnight wrote:
To be honest, at this point my problem is not so much speed as it is the conversion itself does not result in the proper colors being generated

are you sure the color format is really 565 for both, source and destination buffer?
_________________
infj
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Wed Oct 12, 2005 10:58 pm    Post subject: Reply with quote

I guess I should have just posted all the code straight out, so here it is with Saotome's mod in it:
Code:
// Video setup
#define FB_TYPE                 u16
#define PSP_MODE                GU_PSM_5650
#define MAC_MODE                FLAYOUT_HOST_565
#define PIXEL_SIZE              2
#define SCREEN_WIDTH            480
#define SCREEN_HEIGHT           272
#define PSP_LINE_SIZE           512
#define MAC_COLOR_MODE          VMODE_16BIT
#define PSP_COLOR_MODE          PSP_DISPLAY_PIXEL_FORMAT_565
#define FRAMEBUFFER_SIZE        (PSP_LINE_SIZE * SCREEN_HEIGHT * PIXEL_SIZE)
FB_TYPE *g_vram_base = (FB_TYPE *)(0x40000000 | 0x04000000);
static unsigned int __attribute__((aligned(16))) list[256];
static int dispBufferNumber;
inline FB_TYPE *getVramDrawBuffer()
{
   return ((!dispBufferNumber) ? g_vram_base + (FRAMEBUFFER_SIZE >> 1) : g_vram_base);
}

// Basilisk display configuration
static FB_TYPE __attribute__((aligned(16))) PspFrameBuffer[SCREEN_WIDTH * SCREEN_HEIGHT];

/*
 *  Initialization
 */

bool VideoInit(bool classic)
{
#if !DEBUG
   // guInit - Taken from initGraphics() in graphics.c from LUAPlayer
        sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT);

        dispBufferNumber = 0;
        sceDisplayWaitVblankStart();
   sceDisplaySetFrameBuf((void*) g_vram_base, PSP_LINE_SIZE, PSP_COLOR_MODE, 1);

        sceGuInit();

        sceGuStart(GU_DIRECT, list);
        sceGuDrawBuffer(PSP_MODE, (void*)FRAMEBUFFER_SIZE, PSP_LINE_SIZE);
        sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void*)0, PSP_LINE_SIZE);
        sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
        sceGuDepthBuffer((void*) 0x110000, PSP_LINE_SIZE);
        sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2));
        sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
        sceGuDepthRange(0xc350, 0x2710);
        sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
        sceGuEnable(GU_SCISSOR_TEST);
        sceGuAlphaFunc(GU_GREATER, 0, 0xff);
        sceGuEnable(GU_ALPHA_TEST);
        sceGuDepthFunc(GU_GEQUAL);
        sceGuEnable(GU_DEPTH_TEST);
        sceGuFrontFace(GU_CW);
        sceGuShadeModel(GU_SMOOTH);
        sceGuEnable(GU_CULL_FACE);
        sceGuEnable(GU_TEXTURE_2D);
        sceGuTexMode(PSP_MODE, 0, 0, 0);
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
        sceGuTexFilter(GU_NEAREST, GU_NEAREST);
        sceGuAmbientColor(0xffffffff);
        sceGuFinish();
        sceGuSync(0, 0);

        sceDisplayWaitVblankStart();
        sceGuDisplay(1);
#endif
   // Configure the Basilisk II framebuffer.
   VideoMonitor.x = SCREEN_WIDTH;
   VideoMonitor.y = SCREEN_HEIGHT;
   VideoMonitor.mode = MAC_COLOR_MODE;
   VideoMonitor.bytes_per_row = SCREEN_WIDTH * PIXEL_SIZE;
   VideoMonitor.mac_frame_base = MacFrameBaseMac;

   MacFrameBaseHost = (uint8 *)PspFrameBuffer;
   MacFrameSize = VideoMonitor.bytes_per_row * VideoMonitor.y;
   MacFrameLayout = MAC_MODE;

   // Done.
   D(bug("video "));
   return true;
}

void video_set_palette(unsigned char *p)
{
   D(bug("video_set_palette called\n"));
}

/*
 *  Deinitialization
 */

void VideoExit(void)
{
#if !DEBUG
   sceGuTerm();
#endif
}


/*
 *  Video message handling
 */

void VideoInterrupt(void)
{
   // Color correction (aligned)
   u32 pix0,pix1;
   u32 *fbcc = (u32 *)PspFrameBuffer;
   u32 *fbcce = (u32 *)(PspFrameBuffer + ((SCREEN_WIDTH * SCREEN_HEIGHT) >> 1));
   while (fbcc < fbcce)
   {
      pix0 = *fbcc;
      pix1 = *(fbcc+1);
      *fbcc = (pix0 & 0x07e007e0) | ((pix0 & 0xf800f800) >> 11) | ((pix0 & 0x001f001f) << 11);
      *(fbcc+1) = (pix1 & 0x07e007e0) | ((pix1 & 0xf800f800) >> 11) | ((pix1 & 0x001f001f) << 11);
      fbcc += 2;
   }
#if !DEBUG
   // blitImageToScreen(...) with some modifications.
   FB_TYPE* vram = getVramDrawBuffer();
   sceKernelDcacheWritebackInvalidateAll();
   sceGuStart(GU_DIRECT,list);
   sceGuCopyImage(PSP_MODE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
      SCREEN_WIDTH, PspFrameBuffer, 0, 0, PSP_LINE_SIZE, vram);
   sceGuFinish();
   sceGuSync(0,0);
   
   // flipScreen()
   sceGuSwapBuffers();
   sceDisplaySetFrameBuf(vram, PSP_LINE_SIZE, PSP_COLOR_MODE, 1);
   dispBufferNumber ^= 1;
#endif
}

_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Wed Oct 12, 2005 11:08 pm    Post subject: Reply with quote

be sure that your color buffers are word-aligned, or you decrease performance by unaligned load/store instructions. Using uncached accesses should also improve performance and avoid cache-pollution, but requires flushing the cache before starting the conversion.

Using the VFPU you can further increase memory throughput, by loading 4 32-bit-words at once, maybe the overall performance is still better (especially for unaligned buffers, since you need to do only a single unaligned load/store for 8 pixels), even when moving values to GPRs for shift/and/or. The VFPU instruction set contains instructions named vt5650.q, vt5551.q and vt4444.q, but we still have no idea how they work, maybe they're related.

Another problem is right now that some lv.q cause exceptions when the loaded bit pattern is not a valid floating point number, we need to find out how to switch this off using the VFPU control registers. For fast unaligned loads on use lvl.q/lvr.q.
Back to top
View user's profile Send private message
memon



Joined: 03 Oct 2005
Posts: 63

PostPosted: Wed Oct 12, 2005 11:11 pm    Post subject: Reply with quote

Couldn't you use the source 565 as a paletted texture and get the conversion 'for free'? Sure that hogs 256Kb of video memory, but since you don't need it anyway for the emulator you loose nothing :)
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Wed Oct 12, 2005 11:16 pm    Post subject: Reply with quote

memon wrote:
Couldn't you use the source 565 as a paletted texture and get the conversion 'for free'? Sure that hogs 256Kb of video memory, but since you don't need it anyway for the emulator you loose nothing :)

Interesting. I wouldn't know how to go about doing that, could you enlighten me?
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Wed Oct 12, 2005 11:25 pm    Post subject: Reply with quote

ah, yes... nice idea, too. just st up a color lookup table (LUT) with 65535 entries where the color components of entries at each index are swapped by the formula you implemented above.
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Wed Oct 12, 2005 11:29 pm    Post subject: Reply with quote

That's really brilliant. However, I need to get the formula right. So back OT, does anyone have a working RGB->BGR 565 formula.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Wed Oct 12, 2005 11:32 pm    Post subject: Reply with quote

clut[i] = (i & 0x07e0) | ((i & 0xf800) >> 11) | ((i & 0x001f) << 11);

looks right to me. haven't tested it, though. Copy the table to VRAM, if possible, to keep memory bandwidth free for other code. i and clut[i] should be unsigned.
Back to top
View user's profile Send private message
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Thu Oct 13, 2005 1:21 am    Post subject: Re: Fast 565 RGB->BGR Conversion Needed Reply with quote

ChaosKnight wrote:
To be honest, at this point my problem is not so much speed as it is the conversion itself does not result in the proper colors being generated. It's close, but not exact. I have very little experiance with 565 comparitively speaking to my experiance with 8 bit or 24/32 bit modes. The 565 packing is still quite foriegn to me.


It looks fine to me. I'm using the same shifts and masks to do it in PSPGL. How is it coming out wrong? Are blue and red obviously interchanged? Something else?

Are you sure its 565, and not 5551 or 4444?

J
Back to top
View user's profile Send private message Visit poster's website
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 1:59 am    Post subject: Re: Fast 565 RGB->BGR Conversion Needed Reply with quote

jsgf wrote:
It looks fine to me. I'm using the same shifts and masks to do it in PSPGL. How is it coming out wrong? Are blue and red obviously interchanged? Something else?

Are you sure its 565, and not 5551 or 4444?

It's coming out purple. But now it's red again because I'm not sure how to apply the CLUT to the sceGuCopyImage()... I create the CLUT first thing off, then I do this after sceGuInit()
Code:
        sceGuClutMode(PSP_MODE, 0, 0, 0);
        sceGuClutLoad(8192, (void *)&PspCLUT);

Do I need to do this for every render? Sorry for my GU n00bishness, but if even someone had a link to a sample or article decribing this sort of thing would be nice.

As far as the 555 or 565, see the code above to find this:
Code:
#define PSP_MODE                GU_PSM_5650
#define MAC_MODE                FLAYOUT_HOST_565
...
#define PSP_COLOR_MODE          PSP_DISPLAY_PIXEL_FORMAT_565

_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Thu Oct 13, 2005 2:08 am    Post subject: Re: Fast 565 RGB->BGR Conversion Needed Reply with quote

ChaosKnight wrote:
It's coming out purple. But now it's red again because I'm not sure how to apply the CLUT to the sceGuCopyImage()...

I don't think you can; sceGuCopyImage is just a bit-for-bit copy. You need to set your image up as a texture, and then draw a textured sprite. See samples/gu/sprite/sprite.c for a guide. The main difference from what you're doing now is that you'll need to arrange your image to have a stride of 512 pixels wide, because the texture unit can only handle textures with power of 2 dimensions. You don't need to worry about making the texture 512 pixels high because you won't be drawing the parts below 272 rows.
Back to top
View user's profile Send private message Visit poster's website
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Thu Oct 13, 2005 2:30 am    Post subject: Reply with quote

sdk/samples/gu/blit/blit.c is maybe easier to understand.
Back to top
View user's profile Send private message
Arwin



Joined: 12 Jul 2005
Posts: 426

PostPosted: Thu Oct 13, 2005 2:34 am    Post subject: Reply with quote

While we're on this topic, I think we also need either a virtual screen of 640x480 or scaling of 640x480 to 480x272. Maybe efficient to combine the two routines, but it's no doubt something ChaosKnight wouldn't mind having some help with (I don't know anything about graphics myself, anyway).
Back to top
View user's profile Send private message
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Thu Oct 13, 2005 2:37 am    Post subject: Reply with quote

when you blit using the texture unit you can scale on-the-fly. When enabling linear interpolation, a copy to VRAM (using sceGuCopyImage) before rendering the texture could minimize the required bandwidth (direct access to system RAM for linear interpolated textures means 4 accesses per texel instead of one).

Last edited by holger on Thu Oct 13, 2005 4:28 am; edited 1 time in total
Back to top
View user's profile Send private message
sHARD>>



Joined: 05 Oct 2005
Posts: 10

PostPosted: Thu Oct 13, 2005 4:13 am    Post subject: Reply with quote

Arwin wrote:
While we're on this topic, I think we also need either a virtual screen of 640x480 or scaling of 640x480 to 480x272. Maybe efficient to combine the two routines, but it's no doubt something ChaosKnight wouldn't mind having some help with (I don't know anything about graphics myself, anyway).


Since it's already been proven that Mac OS is actually comfortable with any resolution, why not just make the option to double the screen size to twice that of the PSP (960x544)? Not sure if full screen games would work so well, but at least you can still preserve the aspect ratio. The Bochs port is ugly and harder to use partly due to it's destroying of the aspect ratio. Most applications would support this resolution without being cut off, as System 7 was designed to be compatable with the Macintosh SE, which I believe has a height of somewhere around 538. I'll check Apple docs and get back to you on that.
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 5:15 am    Post subject: Reply with quote

sHARD>> wrote:
Arwin wrote:
While we're on this topic, I think we also need either a virtual screen of 640x480 or scaling of 640x480 to 480x272. Maybe efficient to combine the two routines, but it's no doubt something ChaosKnight wouldn't mind having some help with (I don't know anything about graphics myself, anyway).


Since it's already been proven that Mac OS is actually comfortable with any resolution, why not just make the option to double the screen size to twice that of the PSP (960x544)? Not sure if full screen games would work so well, but at least you can still preserve the aspect ratio. The Bochs port is ugly and harder to use partly due to it's destroying of the aspect ratio. Most applications would support this resolution without being cut off, as System 7 was designed to be compatable with the Macintosh SE, which I believe has a height of somewhere around 538. I'll check Apple docs and get back to you on that.

This is my thinking as well. I will attempt to do the doubling and rescaling once I get it on a texture to start out with.

Thanks all.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
sHARD>>



Joined: 05 Oct 2005
Posts: 10

PostPosted: Thu Oct 13, 2005 5:29 am    Post subject: Reply with quote

I surfed around, the SE uses a display with 512 x 342 pixels, so any application designed for System 7 should work great on that low resolution, I know almost everything works on my SE at least.
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 6:30 am    Post subject: Reply with quote

Ok, now it's a texture (as in blit.c) and everything is working, just as fast as before but still it does not seem to be using the CLUT. I will post my code here:
Code:
// Video setup
#define FB_TYPE                 u16
#define PSP_MODE                GU_PSM_5650
#define MAC_MODE                FLAYOUT_HOST_565
#define SLICE_SIZE              64
#define PIXEL_SIZE              2
#define SCREEN_WIDTH            480
#define SCREEN_HEIGHT           272
#define PSP_LINE_SIZE           512
#define BII_SCR_WIDTH           480
#define BII_SCR_HEIGHT          272
#define MAC_COLOR_MODE          VMODE_16BIT
#define PSP_COLOR_MODE          PSP_DISPLAY_PIXEL_FORMAT_565
#define PSP_COLOR_MODE2         GU_COLOR_5650
#define FRAMEBUFFER_SIZE        (PSP_LINE_SIZE * SCREEN_HEIGHT * PIXEL_SIZE)
FB_TYPE *g_vram_base = (FB_TYPE *)(0x40000000 | 0x04000000);
static unsigned int __attribute__((aligned(16))) list[256];
static int dispBufferNumber;
inline FB_TYPE *getVramDrawBuffer()
{
   return ((!dispBufferNumber) ? g_vram_base + (FRAMEBUFFER_SIZE >> 1) : g_vram_base);
}
struct Vertex
{
   unsigned short u, v;
   unsigned short color;
   short x, y, z;
};

// Basilisk display configuration
static FB_TYPE __attribute__((aligned(16))) PspCLUT[65536];
static FB_TYPE __attribute__((aligned(16))) PspFrameBuffer[PSP_LINE_SIZE * SCREEN_HEIGHT];

/*
 *  Initialization
 */

bool VideoInit(bool classic)
{
#if !DEBUG
   // Build color lookup table
   for (int i = 0; i < 65536; i++)
      PspCLUT[i] = (i & 0x07e0) | ((i & 0xf800) >> 11) | ((i & 0x001f) << 11);

   sceGuInit();

   // setup
   sceGuStart(GU_DIRECT, list);
   sceGuDrawBuffer(PSP_MODE, (void*)0, PSP_LINE_SIZE);
   sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void*)0x88000, PSP_LINE_SIZE);
   sceGuDepthBuffer((void*)0x110000, PSP_LINE_SIZE);
   sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2));
   sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
   sceGuDepthRange(0xc350, 0x2710);
   sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
   sceGuEnable(GU_SCISSOR_TEST);
   sceGuFrontFace(GU_CW);
   sceGuEnable(GU_TEXTURE_2D);
   sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
        sceGuClutMode(PSP_MODE, 0, 0, 0);
        sceGuClutLoad(8192, (void *)&PspCLUT);
   sceGuFinish();
   sceGuSync(0,0);

   sceDisplayWaitVblankStart();
   sceGuDisplay(1);
#endif

   // Configure the Basilisk II framebuffer.
   VideoMonitor.x = BII_SCR_WIDTH;
   VideoMonitor.y = BII_SCR_HEIGHT;
   VideoMonitor.mode = MAC_COLOR_MODE;
   VideoMonitor.bytes_per_row = PSP_LINE_SIZE * PIXEL_SIZE;
   VideoMonitor.mac_frame_base = MacFrameBaseMac;

   MacFrameSize = VideoMonitor.bytes_per_row * VideoMonitor.y;
   MacFrameLayout = MAC_MODE;
   MacFrameBaseHost = (uint8 *)PspFrameBuffer;

   // Done.
   D(bug("video "));
   return true;
}

void video_set_palette(unsigned char *p)
{
   D(bug("video_set_palette called\n"));
}

/*
 *  Deinitialization
 */

void VideoExit(void)
{
#if !DEBUG
   sceGuTerm();
#endif
}


/*
 *  Video message handling
 */

void VideoInterrupt(void)
{
   unsigned int j;
   struct Vertex* vertices;

   sceGuStart(GU_DIRECT,list);
   sceGuTexMode(PSP_MODE, 0, 0, 0);
   sceGuTexImage(0, PSP_LINE_SIZE, PSP_LINE_SIZE, PSP_LINE_SIZE, PspFrameBuffer);
   sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
   sceGuTexFilter(GU_NEAREST, GU_NEAREST);
   sceGuTexScale(1.0f / ((float)PSP_LINE_SIZE), 1.0f / ((float)PSP_LINE_SIZE));
   sceGuTexOffset(0.0f, 0.0f);
   sceGuAmbientColor(0xffffffff);
        sceGuClutMode(PSP_MODE, 0, 0, 0);

   // do a striped blit (takes the page-cache into account)
   for (j = 0; j < BII_SCR_WIDTH; j = j + SLICE_SIZE)
   {
      vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex));

      vertices[0].u = j; vertices[0].v = 0;
      vertices[0].color = 0;
      vertices[0].x = j; vertices[0].y = 0; vertices[0].z = 0;
      vertices[1].u = j + SLICE_SIZE; vertices[1].v = BII_SCR_HEIGHT;
      vertices[1].color = 0;
      vertices[1].x = j + SLICE_SIZE; vertices[1].y = BII_SCR_HEIGHT; vertices[1].z = 0;

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

   sceGuFinish();
   sceGuSync(0,0);

   sceGuSwapBuffers();
}


Hopefully I am just forgetting something ignorant. Also you will see some extra defines, I tried to double up the video size and have the texture automatically scale down but it just resulted in a black screen (mostly due to a lack of understanding on my part, there are a lot of moving parts in this code).
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Thu Oct 13, 2005 7:51 am    Post subject: Reply with quote

ChaosKnight wrote:

Code:

   sceGuTexMode(PSP_MODE, 0, 0, 0);
   sceGuTexImage(0, PSP_LINE_SIZE, PSP_LINE_SIZE, PSP_LINE_SIZE, PspFrameBuffer);


You need to set the texture mode to GU_PSM_T16 - 16 bit palette lookup.

J
Back to top
View user's profile Send private message Visit poster's website
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 8:23 am    Post subject: Reply with quote

jsgf wrote:
You need to set the texture mode to GU_PSM_T16 - 16 bit palette lookup.

J

This results in a black screen. Are there any other spots I need to setup? I looked through the CLUT example but to no avail.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Thu Oct 13, 2005 8:31 am    Post subject: Reply with quote

Code:
sceGuClutLoad(8192, (void *)&PspCLUT);

should read
Code:
sceGuClutLoad(8192, (void *)&PspCLUT[0]);

or
Code:
sceGuClutLoad(8192, (void *)PspCLUT);
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 8:43 am    Post subject: Reply with quote

holger wrote:
Code:
sceGuClutLoad(8192, (void *)&PspCLUT);

should read
Code:
sceGuClutLoad(8192, (void *)&PspCLUT[0]);

or
Code:
sceGuClutLoad(8192, (void *)PspCLUT);

Good catch, I feel pretty foolish about now.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 9:18 am    Post subject: Reply with quote

I think I have this 99% done. Looks like the screen was black both because I did not have a CLUT properly loaded, but also because the PSP needs to be in 8888 color mode to do this. Which makes perfect sense. Tricky thing is now my clut is turning the screen black and aqua. Of course my #1 culprit is this code:
Code:
   // Build color lookup table
   for (int i = 0; i < 65536; i++)
      PspCLUT[i] = (i & 0x07e0) | ((i & 0xf800) >> 11) | ((i & 0x001f) << 11);

Is this correct for building a CLUT?
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
ector



Joined: 12 May 2005
Posts: 195

PostPosted: Thu Oct 13, 2005 11:12 am    Post subject: Reply with quote

Your problem is that the CLUT memory on-chip is only 512 (or possibly 1024?) bytes as far as I can tell.
You can't use a 65536-color palette.
_________________
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.
Back to top
View user's profile Send private message
jsgf



Joined: 12 Jul 2005
Posts: 254

PostPosted: Thu Oct 13, 2005 11:23 am    Post subject: Reply with quote

ector wrote:
Your problem is that the CLUT memory on-chip is only 512 (or possibly 1024?) bytes as far as I can tell.

Should be at least 1024, otherwise you wouldn't be able to have a 256x32bpp colour table. So does that mean the CLUT is uploaded when you execute command 196, rather than simply setting a pointer for later use?
Quote:
You can't use a 65536-color palette.

I wonder why the hardware (apparently) supports 16 and 32 bit index formats then?
Back to top
View user's profile Send private message Visit poster's website
ector



Joined: 12 May 2005
Posts: 195

PostPosted: Thu Oct 13, 2005 11:46 am    Post subject: Reply with quote

jsgf wrote:
ector wrote:
Your problem is that the CLUT memory on-chip is only 512 (or possibly 1024?) bytes as far as I can tell.

Should be at least 1024, otherwise you wouldn't be able to have a 256x32bpp colour table. So does that mean the CLUT is uploaded when you execute command 196, rather than simply setting a pointer for later use?
Quote:
You can't use a 65536-color palette.

I wonder why the hardware (apparently) supports 16 and 32 bit index formats then?


Yeah oops didn't think properly there... of course it's at least 1024b.
But yeah i'm pretty sure that it gets uploaded. Making an additional read over the memory bus every time the chip needed a color would be too slow.

Don't know what the big index formats would be useful for, other than crude pixel skipping :P
_________________
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.
Back to top
View user's profile Send private message
ChaosKnight



Joined: 14 Apr 2005
Posts: 142
Location: Florida, USA

PostPosted: Thu Oct 13, 2005 12:01 pm    Post subject: Reply with quote

So then i'm back to doing a while on my buffer to convert blocks of 2px?

-- EDIT --
Went back to Saotome's formula and I discovered something interesting. It was working this whole time but didn't seem like it. I will explain. The video is rendered on two differant threads simultaniously. Basilisk II has access to the "framebuffer" and that was the same one i was working with. So foolishly two threads were touching it at the same time, making the picture purple (red + blue). I created another buffer and used Saotome's method to write to it, which now results in perfect color but a severe slowdown... so here's the question... How do I get a block of memory on VRAM? do I just have to point to a certain address? If so what is that address and how much space am I allowed to use within it. It seems i'm only using ~265K for a buffer, so it's pretty small yet, but I wish to experiment with larger resolutions and scaling.
_________________
w00t
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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