Drawing rgb565 image in output_buffer using PVR

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: Drawing rgb565 image in output_buffer using PVR

Post by PH3NOM »

BB Hood wrote:Probably should have told you that in the beginning: viewtopic.php?p=1009854#p1009854

Did you do any DMA stuff yet?
Alright Ive just now got around to testing the PVR DMA transfers.
Here is a test I have made that decodes a Png texture and transfers to PVR using DMA:
http://www.megaupload.com/?d=67C2LYOR

Can anyone confirm this is the correct usage?
Here is the main bit, the full source is included in the link above:

Code: Select all

#include <dc/pvr.h>
#include <dc/video.h>
#include <malloc.h>

#include <png/png.h>
#include <zlib/zlib.h>

#define PVR_TEX_WIDTH 1024
#define PVR_TEX_HEIGHT 512

// PVR VRMA / DMA Pointers
pvr_ptr_t * pvr_vram_buffer;
ptr_t pvr_dma_cbdata;
pvr_dma_callback_t pvr_dma_callback;

// Decode A PNG texture from /cd/ into RAM, then transfer to VRAM using PVR DMA
static int png_load( char * file_name ) {

  // allocate memory to contain the decoded PNG texture; 32-byte aligned
  uint32 * png_dec_buffer __attribute__ ((aligned (32)));
  png_dec_buffer = memalign( 32, PVR_TEX_WIDTH * PVR_TEX_HEIGHT * 2 );
  pvr_vram_buffer = pvr_mem_malloc(PVR_TEX_WIDTH * PVR_TEX_HEIGHT * 2); 

  if (png_dec_buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // Decode the PNG file into main RAM	
  png_to_texture( file_name , png_dec_buffer, PNG_NO_ALPHA);

  // transfer the texture from RAM to VRAM using PVR DMA 
  pvr_txr_load_dma(png_dec_buffer, pvr_vram_buffer,
       PVR_TEX_WIDTH * PVR_TEX_HEIGHT * 2, 0, pvr_dma_callback, pvr_dma_cbdata);

}
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Re: Drawing rgb565 image in output_buffer using PVR

Post by BlackAura »

Essentially, that looks about right. Two comments though:

Code: Select all

  uint32 * png_dec_buffer __attribute__ ((aligned (32)));
  png_dec_buffer = memalign( 32, PVR_TEX_WIDTH * PVR_TEX_HEIGHT * 2 );
That first line probably doesn't do what you think. That's actually aligning the pointer itself to a 32 byte boundary, which is probably not what you meant. It's only the buffer itself that needs to be aligned (which the memalign function does for you).

Secondly - you need to flush the CPU's data cache. You will probably still have bits of the decoded image sitting in cache. Since a DMA transfer bypasses the CPU entirely, those pieces will be missing, replaced by whatever was in the buffer before you decoded the PNG.

You can use dcache_flush_range to force the data to be written out to RAM. If your buffer is larger than the data cache (16KB), you only need to flush the last 16KB.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: Drawing rgb565 image in output_buffer using PVR

Post by PH3NOM »

Thanks again BlackAura.

Ive looked over the SDL DC DMA video functions, and realized what you have said.

Code: Select all

     	dcache_flush_range((unsigned)out_buffer[0],vidWidth * vidHeight * 2);
		  while (!pvr_dma_ready());
        pvr_dma_transfer(out_buffer[0], pvr_decoded_frame, vidWidth * vidHeight * 2,
                          PVR_DMA_VRAM64, PVR_TXRLOAD_NONBLOCK, pvr_dma_callback, pvr_dma_cbdata);
On a separate thread, how does PVR VQ texture loading work?

Code: Select all

pvr_poly_cxt_txr(&Image_context, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE, 512, 512, pvr_vram_buffer, PVR_FILTER_BILINEAR);
produces this result:
source image ( 512x512 ):
Image

displayed image ( 640x480 ):
Image
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: Drawing rgb565 image in output_buffer using PVR

Post by BlueCrab »

KOS does not support VQ encoding textures at runtime (it would especially be far too slow if you were trying to use it to play video).
The flag you are using is for saying that the texture data is already VQ encoded (for instance, by the vqenc utility). Also, you have the Twiddled flag set, which would imply that you've twiddled the data as well, which is kinda stupid if you're just trying to render a video or something like that since that implies extra preprocessing as well.
nymus
DC Developer
DC Developer
Posts: 968
Joined: Tue Feb 11, 2003 4:12 pm
Location: In a Dream
Has thanked: 5 times
Been thanked: 6 times

Re: Drawing rgb565 image in output_buffer using PVR

Post by nymus »

^^^ wow! I'm amazed the image above loaded with vq still looks like the original from afar or through squinted eyes. It's like a visual confirmation of the compression level of the format! (eg distance from screen required to correctly form the original=compression?) Fascinating!
behold the mind
inspired by Dreamcast
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: Drawing rgb565 image in output_buffer using PVR

Post by PH3NOM »

BlueCrab wrote:KOS does not support VQ encoding textures at runtime (it would especially be far too slow if you were trying to use it to play video).
The flag you are using is for saying that the texture data is already VQ encoded (for instance, by the vqenc utility). Also, you have the Twiddled flag set, which would imply that you've twiddled the data as well, which is kinda stupid if you're just trying to render a video or something like that since that implies extra preprocessing as well.
Yeah :-) I know the texture I have uploaded is already VQ compressed. It is a RBG565 66kb 512x512 VQ Compressed .PVR texture.

For this example I am not trying to play video, just upload a VQ compressed texture and draw it on the PVR.

Is there more to it than just setting these flags in the pvr_poly_ctx_txr()?
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: Drawing rgb565 image in output_buffer using PVR

Post by BlueCrab »

Its possible that the image you're using has some sort of headers that you're not accounting for. I've never worked with VQ stuff any more than the example in KOS that deals with it does. The only thing I can suggest is to look at the vq example in the KOS tree.
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Re: Drawing rgb565 image in output_buffer using PVR

Post by BlackAura »

The VQ format is basically:

1 - A 256-entry dictionary, with each entry containing a 4 pixels (a 2x2 pixel square) in RGB565 format.
2 - A Set of 8-bit indexes into the directory.

Since you're getting a recognizable image, you've probably got the dictionary and data in the right place. If you'd missed a header or something, you'd probably get garbage.

Looks kind of like a twiddling problem. VQEnc can output both twiddled and un-twiddled textures, and I think it defaults to un-twiddled. Your image looks like the mess you get when you try to render an un-twiddled texture as a twiddled texture (as if it's been cut into small blocks, and the blocks have been scrambled).

Other than that, I don't remember anything tricky with the VQ format until you start trying to combine it with mip-maps.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: Drawing rgb565 image in output_buffer using PVR

Post by PH3NOM »

Yeah the problem has been solved now. Thanks for the help!

I was copying the header data with the image to the PVR. This resulted in the mixed up image posted above. :lol:
Now I seek past the header and only copy the image data, everything is displayed like it should.
Oh yeah those .pvr files were made with a different encoder.

When I used vqenc, the generated .vq files were good to load without worrying about the header.

Although, the VQ compression is quite apparent and does not produce desirable results.
Post Reply