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 

Depth Buffer Layout

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



Joined: 18 Aug 2005
Posts: 204

PostPosted: Wed Sep 28, 2005 7:40 am    Post subject: Depth Buffer Layout Reply with quote

This Codelet will generate two depth buffer dumps. The first contains pixels width z=x and the second one pixels with z=y. Compile using one of the demo Makefiles:

Code:

#include <pspctrl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include <GLES/egl.h>
#include <GLES/gl.h>

#define EGLCHK(x) x
#define GLCHK(x) x


static const EGLint attrib_list [] = {
   EGL_RED_SIZE, 8,
   EGL_GREEN_SIZE, 8,
   EGL_BLUE_SIZE, 8,
   EGL_ALPHA_SIZE, 8,
   EGL_DEPTH_SIZE, 16,
   EGL_NONE
};


struct clear_vertex { short x, y, z; };

#include "../pspgl_internal.h"

static
void set_depth_pixel (int x, int y, int z)
{
   struct pspgl_dlist *dlist = pspgl_curctx->dlist_current;
   struct clear_vertex *vbuf = pspgl_dlist_insert_space(dlist, 2 * sizeof(struct clear_vertex));

   vbuf[0].x = x;
   vbuf[0].y = y;
   vbuf[0].z = z;

   vbuf[1].x = x+1;
   vbuf[1].y = y+1;
   vbuf[1].z = z;

   /* enable clear mode */
   sendCommandi(211, 1 | (1 << 10));

   /* draw array */
   sendCommandi(18, 0x800100);              /* xform: 2D, vertex format: RGB8888 (uint32), xyz (int16) */
   sendCommandi(16, (((unsigned long) vbuf) >> 8) & 0xf0000); /* vertex array BASE */
   sendCommandi(1, ((unsigned long) vbuf) & 0xffffff);        /* vertex array, Adress */
   sendCommandiUncached(4, (6 << 16) | 2);            /* sprite (type 6), 2 vertices */

   /* leave clear mode */
   sendCommandi(211, 0);
}


int main(int argc, char* argv[])
{
   EGLDisplay dpy;
   EGLConfig config;
   EGLint num_configs;
   EGLContext ctx;
   EGLSurface surface;
   unsigned int x, y;

   /* pass NativeDisplay=0, we only have one screen... */
   EGLCHK(dpy = eglGetDisplay(0));
   EGLCHK(eglInitialize(dpy, NULL, NULL));
   EGLCHK(eglChooseConfig(dpy, attrib_list, &config, 1, &num_configs));
   EGLCHK(ctx = eglCreateContext(dpy, config, NULL, NULL));
   EGLCHK(surface = eglCreateWindowSurface(dpy, config, 0, NULL));
   EGLCHK(eglMakeCurrent(dpy, surface, surface, ctx));

/* swap bytes so that they look in order in the hex-editor... */
#define swap16(val) (((unsigned) val << 8) | ((unsigned) val >> 8))

   for (y=0; y<272-1; y++) {
      for (x=0; x<480-1; x++) {
         set_depth_pixel(x, y, swap16(x));
         GLCHK(glFinish());
      }
   }

   __pspgl_vram_dump();

   for (y=0; y<272-1; y++) {
      for (x=0; x<480-1; x++) {
         set_depth_pixel(x, y, swap16(y));
         GLCHK(glFinish());
      }
   }

   __pspgl_vram_dump();

   EGLCHK(eglTerminate(dpy));
   return 0;
}



Isolate the two depth buffer dumps into seperate files and watch the hexdump:

Code:

$ dd if=/Volumes/PSP/pspgl.ge of=/tmp/depthmap-x bs=1 count=278528 skip=1114128
$ dd if=/Volumes/PSP/pspgl.ge of=/tmp/depthmap-y bs=1 count=278528 skip=3211296
$ hexdump -v /tmp/depthmap-x | less
$ hexdump -v /tmp/depthmap-y | less




The depth buffer seems to be laid out like this:

vertical y rows are sorted 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x18, 0x1a, ... , 0x1f, 0x10, 0x11, ... , 0x16, 0x17, ...

horizontal x pixels are sorted in 16-pixel-blocks (32 bytes), beginning in this order: 16-31, 272-287, 0-15, 256-271, 48-63, 304-319, 32-47, 288-303, 80-95, 336-351, 64-79, ...

This may look confusing on a first look, but if we consider byte-swapped address lines and the power-of-two requirement it seems logical.

This codelet does xy-to-adress-in-depthbuffer conversion:

Code:

/* compile using: gcc -Wall -g -O0 -o xy2adr xy2adr.c */
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
   int x = strtol(argv[1], NULL, 0);
   int y = strtol(argv[2], NULL, 0);
   int adr;

   adr = (2*512) * (y ^ 8);
   adr |= (x >> 3) & 0x20;
   adr |= ((x & 0xf0) << 2) ^ 0x40;
   adr |= (x & 0xf) << 1;

   printf(" adr 0x%08x: x = %d/0x%04x, y = %d/0x%04x\n", adr, x, x, y, y);

   return 0;
}




This one the other way round:

Code:

/* compile using: gcc -Wall -g -O0 -o adr2xy adr2xy.c */
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
   int adr = strtol(argv[1], NULL, 0);
   int x, y;

   y = (adr >> 10) ^ 8;
   x =  (adr & 0x20) << 3;
   x |= ((adr >> 2) & 0xf0) ^ 0x10;
   x |= (adr >> 1) & 0xf;

   printf(" adr 0x%08x: x = %d/0x%04x, y = %d/0x%04x\n", adr, x, x, y, y);

   return 0;
}



In a real project one probably wants to use tight loops for reordering, but with this information it should be possible to implement depth-buffer based shadow effects and the like.
Back to top
View user's profile Send private message
ector



Joined: 12 May 2005
Posts: 195

PostPosted: Wed Sep 28, 2005 8:19 am    Post subject: Reply with quote

Nice one!
Excellent for lens flares ;)

These functions belong in the SDK, imho.
_________________
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 Sep 29, 2005 3:55 am    Post subject: Reply with quote

This is very close to the swizzled texture arrangement, isn't it?
Back to top
View user's profile Send private message Visit poster's website
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Thu Sep 29, 2005 10:58 pm    Post subject: Reply with quote

not really... swizzled (or tiled) textures are optimized for local access and better use of texture cache for small triangles, I can't see much advantage in the depth buffer ordering... anybody else?
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