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.
What graphics operations work on system memory?
Re: What graphics operations work on system memory?
you can see the lastest ppa source.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.
maybe it can help you
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):
Also, what's with the sceGuTexSync() calls? The old graphics.c file doesn't have a single one.
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(GU_PSM_8888, sx, sy, width, height>>1, PSP_LINE_SIZE<<1, (void *)(vram+PSP_LINE_SIZE*4), dx, dy>>1, PSP_LINE_SIZE, dest);
sceGuCopyImage(GU_PSM_8888, sx, sy, width, height>>1, PSP_LINE_SIZE<<1, (void *)vram, dx, dy>>1, PSP_LINE_SIZE, (void *)((unsigned int)dest + PSP_LINE_SIZE*262*4));
}
else
sceGuCopyImage(GU_PSM_8888, sx, sy, width, height, PSP_LINE_SIZE, (void *)vram, dx, dy, PSP_LINE_SIZE, dest);
sceGuFinish();
sceGuSync(0,0);
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