What graphics operations work on system memory?

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

Moderators: cheriff, TyRaNiD

Post Reply
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

What graphics operations work on system memory?

Post by J.F. »

I was looking at the fact that 720x480 uses too much memory to fit in EDRAM, so I was playing around with trying to do GU operations to system memory. While Copy Image works, GU Draw doesn't. It looks like the target of rendering operations HAS to be in EDRAM. Is this really the case? What operations are allowed with system memory as the destination?

Currently, my rendering is stuck with one 768x448 buffer with a Z buffer. That BARELY fits into EDRAM, and then I can blit the EDRAM buffer to the frame buffer in system memory. Assuming you HAVE to keep the destination in EDRAM I was thinking of going to a 768x240 buffer. That would leave me with EDRAM left for caching textures. It would also make it easier to support interlaced displays. Non-interlaced: do two blits with line width twice as wide as it really is to space the lines out. Interlaced: do two blits, one to each half of the frame as they're already separate. So each case is easily handled by two blits. You get half the vertical resolution, but at least it's full-screen.

EDIT: One caution about doing the "twice the line width" blits - the maximum x and y values are 1024. While the line width for source and dest can be bigger, the moment the x hits 1024, the blit transfers the data wrong. So don't offset the odd field by an x of 768 with a width of 1536. That doesn't work. You have to offset the source pointer by 768*4 and use an x of 0 and width of 1536. That works fine.
cooleyes
Posts: 123
Joined: Thu May 18, 2006 3:30 pm

Re: What graphics operations work on system memory?

Post by cooleyes »

J.F. wrote:I was looking at the fact that 720x480 uses too much memory to fit in EDRAM, so I was playing around with trying to do GU operations to system memory. While Copy Image works, GU Draw doesn't. It looks like the target of rendering operations HAS to be in EDRAM. Is this really the case? What operations are allowed with system memory as the destination?

Currently, my rendering is stuck with one 768x448 buffer with a Z buffer. That BARELY fits into EDRAM, and then I can blit the EDRAM buffer to the frame buffer in system memory. Assuming you HAVE to keep the destination in EDRAM I was thinking of going to a 768x240 buffer. That would leave me with EDRAM left for caching textures. It would also make it easier to support interlaced displays. Non-interlaced: do two blits with line width twice as wide as it really is to space the lines out. Interlaced: do two blits, one to each half of the frame as they're already separate. So each case is easily handled by two blits. You get half the vertical resolution, but at least it's full-screen.

EDIT: One caution about doing the "twice the line width" blits - the maximum x and y values are 1024. While the line width for source and dest can be bigger, the moment the x hits 1024, the blit transfers the data wrong. So don't offset the odd field by an x of 768 with a width of 1536. That doesn't work. You have to offset the source pointer by 768*4 and use an x of 0 and width of 1536. That works fine.
you can see the lastest ppa source.
maybe it can help you
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

O'tay! :)

EDIT: Well, that tells me I was right - you do the work in EDRAM and then blit it to the framebuffer in system memory. I do like how you separated the TV into its own set of routine. Very nice work there. However, I noticed that for interlaced mode, you blit it a line at a time in a loop. You might try something like this (how I do it at the moment):

Code: Select all

	guStart();
	if (laced)
	{
		sceGuCopyImage&#40;GU_PSM_8888, sx, sy, width, height>>1, PSP_LINE_SIZE<<1, &#40;void *&#41;&#40;vram+PSP_LINE_SIZE*4&#41;, dx, dy>>1, PSP_LINE_SIZE, dest&#41;;
		sceGuCopyImage&#40;GU_PSM_8888, sx, sy, width, height>>1, PSP_LINE_SIZE<<1, &#40;void *&#41;vram, dx, dy>>1, PSP_LINE_SIZE, &#40;void *&#41;&#40;&#40;unsigned int&#41;dest + PSP_LINE_SIZE*262*4&#41;&#41;;
	&#125;
	else
		sceGuCopyImage&#40;GU_PSM_8888, sx, sy, width, height, PSP_LINE_SIZE, &#40;void *&#41;vram, dx, dy, PSP_LINE_SIZE, dest&#41;;
	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0,0&#41;;
Also, what's with the sceGuTexSync() calls? The old graphics.c file doesn't have a single one.
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

sceGuTexSync() synchronizes the sceGuCopyImage() since it runs in parallel with any GE operation that you do. You call it before you use the copied data on the GE, so that you could wait for a memory buffer in GE memory to become available for re-use (if you blit from one and draw into another).
GE Dominator
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I guess in this case it's being used to say when the blit is done because the transfer is FROM GE memory, not TO it.
Post Reply