Textures in VRAM

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Mr.Modem
Posts: 28
Joined: Wed Sep 21, 2005 4:43 am

Textures in VRAM

Post by Mr.Modem »

I'm working on a Sprite/Tile engine. I've modified the blit example to use 5551 pixel format. So far everything is good. But I want the textures to be in VRAM. This is my code:

Code: Select all

#include <pspkernel.h>





unsigned short __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; pixels&#91;SPRITE_HEIGHT*SPRITE_WIDTH&#93;;
unsigned short __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; swizzled_pixels&#91;SPRITE_HEIGHT*SPRITE_WIDTH&#93;;
unsigned short *pixels2;

struct Vertex
&#123;
	unsigned short u, v;
	unsigned short color;
	float x, y, z;
&#125;;

void advancedBlit&#40;float sx, float sy, int sw, int sh, float dx, float dy&#41;
&#123;
	int start, end;

	// blit maximizing the use of the texture-cache

	/*
		the texture cache is 8kB. It is used in the following fashions&#58;
		4-bit&#58; 128x128
		8-bit&#58; 128x64
		16-bit&#58; 64x64
		32-bit&#58; 64x32

		swizzling your input will give more than 100% increase in speed
	*/

	for &#40;start = sx, end = sx+sw; start < end; start += SLICE_SIZE, dx += SLICE_SIZE&#41;
	&#123;
		struct Vertex* vertices = &#40;struct Vertex*&#41;sceGuGetMemory&#40;2 * sizeof&#40;struct Vertex&#41;&#41;;
		int width = &#40;start + SLICE_SIZE&#41; < end ? SLICE_SIZE &#58; end-start;

		vertices&#91;0&#93;.u = start; vertices&#91;0&#93;.v = sy;
		vertices&#91;0&#93;.color = 0;
		vertices&#91;0&#93;.x = dx; vertices&#91;0&#93;.y = dy; vertices&#91;0&#93;.z = 0;

		vertices&#91;1&#93;.u = start + width; vertices&#91;1&#93;.v = sy + sh;
		vertices&#91;1&#93;.color = 0;
		vertices&#91;1&#93;.x = dx + width; vertices&#91;1&#93;.y = dy + sh; vertices&#91;1&#93;.z = 0;

		sceGuDrawArray&#40;GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_5551|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices&#41;;
	&#125;
&#125;

void swizzle_fast&#40;u8* out, const u8* in, unsigned int width, unsigned int height&#41;
&#123;
   unsigned int blockx, blocky;
   unsigned int j;
 
   unsigned int width_blocks = &#40;width / 16&#41;;
   unsigned int height_blocks = &#40;height / 8&#41;;
 
   unsigned int src_pitch = &#40;width-16&#41;/4;
   unsigned int src_row = width * 8;
 
   const u8* ysrc = in;
   u32* dst = &#40;u32*&#41;out;
 
   for &#40;blocky = 0; blocky < height_blocks; ++blocky&#41;
   &#123;
      const u8* xsrc = ysrc;
      for &#40;blockx = 0; blockx < width_blocks; ++blockx&#41;
      &#123;
         const u32* src = &#40;u32*&#41;xsrc;
         for &#40;j = 0; j < 8; ++j&#41;
         &#123;
            *&#40;dst++&#41; = *&#40;src++&#41;;
            *&#40;dst++&#41; = *&#40;src++&#41;;
            *&#40;dst++&#41; = *&#40;src++&#41;;
            *&#40;dst++&#41; = *&#40;src++&#41;;
            src += src_pitch;
         &#125;
         xsrc += 16;
     &#125;
     ysrc += src_row;
   &#125;
&#125;

void InitGFX&#40;&#41;
&#123;
	sceGuInit&#40;&#41;;

	// setup
	sceGuStart&#40;GU_DIRECT,list&#41;;
	sceGuDrawBuffer&#40;GU_PSM_5551,&#40;void*&#41;0,512&#41;;
	sceGuDispBuffer&#40;480,272,&#40;void*&#41;0x44000,512&#41;;
	sceGuDepthBuffer&#40;&#40;void*&#41;0x88000,512&#41;;
	sceGuOffset&#40;2048 - &#40;480/2&#41;,2048 - &#40;272/2&#41;&#41;;
	sceGuViewport&#40;2048,2048,480,272&#41;;
	sceGuDepthRange&#40;0xc350,0x2710&#41;;
	sceGuScissor&#40;0,0,480,272&#41;;
	sceGuEnable&#40;GU_SCISSOR_TEST&#41;;
	sceGuFrontFace&#40;GU_CW&#41;;
	sceGuEnable&#40;GU_TEXTURE_2D&#41;;
	sceGuClear&#40;GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT&#41;;
	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0,0&#41;;

	sceDisplayWaitVblankStart&#40;&#41;;
	sceGuDisplay&#40;1&#41;;
&#125;

int main&#40;int argc, char* argv&#91;&#93;&#41;
&#123;
	float x = 0,y = 0;
	int i;

	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;
	
	InitGFX&#40;&#41;;
	

	for&#40;i=0;i<SPRITE_WIDTH*SPRITE_HEIGHT;i++&#41;&#123;
		pixels&#91;i&#93; = 0xFC00;
	&#125;
	

	swizzle_fast&#40;&#40;u8*&#41;swizzled_pixels,&#40;const u8*&#41;pixels,SPRITE_WIDTH*2,SPRITE_HEIGHT&#41;; 
	// 512*2 because swizzle operates in bytes, and each pixel in a 16-bit texture is 2 bytes
	
	sceGuCopyImage&#40;GU_PSM_5551,0,0,SPRITE_WIDTH,SPRITE_HEIGHT,SPRITE_WIDTH,swizzled_pixels,0,0,SPRITE_WIDTH,&#40;sceGeEdramGetAddr&#40;&#41;+512*272*2*3&#41;&#41;;
	
	pixels2 = sceGeEdramGetAddr&#40;&#41;+512*272*2*3;

	sceKernelDcacheWritebackAll&#40;&#41;;

	while &#40;!done&#41;
	&#123;
		SceCtrlData pad;
		sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
		if&#40;&#40;pad.Buttons & PSP_CTRL_RIGHT&#41; && x<479-SPRITE_WIDTH&#41;x+=2;
		if&#40;&#40;pad.Buttons & PSP_CTRL_LEFT&#41; && x>1&#41;x-=2;
		if&#40;&#40;pad.Buttons & PSP_CTRL_UP&#41; && y>1&#41;y-=2;
		if&#40;&#40;pad.Buttons & PSP_CTRL_DOWN&#41; && y<271-SPRITE_HEIGHT&#41;y+=2;

		sceGuStart&#40;GU_DIRECT,list&#41;;

		sceGuTexMode&#40;GU_PSM_5551,0,0,1&#41;; // 16-bit RGBA
		sceGuTexImage&#40;0,SPRITE_WIDTH,SPRITE_HEIGHT,SPRITE_WIDTH,pixels2&#41;; 
		sceGuTexFunc&#40;GU_TFX_REPLACE,GU_TCC_RGBA&#41;; // don't get influenced by any vertex colors
		sceGuTexFilter&#40;GU_NEAREST,GU_NEAREST&#41;; // point-filtered sampling

		sceGuClearColor&#40;0&#41;;
		sceGuClear&#40;GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT&#41;;
		
		advancedBlit&#40;0,0,SPRITE_WIDTH,SPRITE_HEIGHT,x,y&#41;;

		sceGuFinish&#40;&#41;;
		sceGuSync&#40;0,0&#41;;

//		sceDisplayWaitVblankStart&#40;&#41;;
		sceGuSwapBuffers&#40;&#41;;
		
		
	&#125;

	sceGuTerm&#40;&#41;;

	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;
The app starts but I get a black screen. I guess I'm doing something wrong when I copy the texture to VRAM. I guess this is a pretty noobish question but I couldn't find anything that helps me in the forum.
rinco
Posts: 255
Joined: Fri Jan 21, 2005 2:12 pm
Location: Canberra, Australia

Post by rinco »

Perhaps one of these will help you out:
- sync your tex with sceGuTexSync
- lose the color variable (and of course GU_COLOR_5551)
- sceKernelDcacheWritebackAll before the sceGuCopyImage
- pass swizzled_pixels to sceGuTexImage, not the drawbuffer (render the drawbuffer to the drawbuffer?!?)

otherwise it looks good. checkout that new psp2d lib in python, or the craziness in sdl_video for more ideas.
Mr.Modem
Posts: 28
Joined: Wed Sep 21, 2005 4:43 am

Post by Mr.Modem »

Thanks but it didn't help! Anyway I've solved the problem. I looked at the fileassistant code and found what I had missed. After the swizzle my code look like this:

Code: Select all

	sceKernelDcacheWritebackAll&#40;&#41;;
	sceGuStart&#40;GU_DIRECT,list&#41;;
	pixels2 = sceGeEdramGetAddr&#40;&#41;+512*272*2*3;
	sceGuCopyImage&#40;GU_PSM_5551,0,0,SPRITE_WIDTH,SPRITE_HEIGHT,SPRITE_WIDTH,swizzled_pixels,0,0,SPRITE_WIDTH,pixels2&#41;;
	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0,0&#41;;
How stupid, I forgot the SceGuStart. Anyway thanks for replying!
Post Reply