(PSP) some improvements to the video driver

add support for paletted frame texture in VRAM.
This commit is contained in:
aliaspider 2014-03-17 00:22:13 +01:00
parent 035e9b0919
commit e060b67136

View File

@ -77,10 +77,13 @@ typedef struct __attribute__((packed)) psp1_sprite
typedef struct psp1_rgui_frame
{
void* dList;
psp1_sprite_t* frame_coords;
void* frame;
psp1_sprite_t* frame_coords;
bool active;
PspGeContext context_storage;
} psp1_rgui_frame_t;
typedef struct psp1_video
@ -125,15 +128,18 @@ static void *psp_init(const video_info_t *video,
sceGuInit();
psp->main_dList = memalign(16,64 * 1024); // TODO: use a better approximation of maximum display list size
psp->frame_dList = memalign(16,64 * 1024);
psp->rgui.dList = memalign(16,64 * 1024);
psp->frame_coords = memalign(64, 2 * sizeof(psp1_sprite_t));
psp->main_dList = memalign(16, 256); // make sure to allocate more space if bigger display lists are needed.
psp->frame_dList = memalign(16, 256);
psp->rgui.dList = memalign(16, 256);
psp->rgui.frame = memalign(16, 2 * 480 * 272);
psp->frame_coords = memalign(64, 1 * sizeof(psp1_sprite_t));
psp->rgui.frame_coords = memalign(64, 16 * sizeof(psp1_sprite_t));
memset(psp->frame_coords, 0, 2 * sizeof(psp1_sprite_t));
memset(psp->frame_coords , 0, 1 * sizeof(psp1_sprite_t));
memset(psp->rgui.frame_coords , 0, 16 * sizeof(psp1_sprite_t));
sceKernelDcacheWritebackInvalidateAll();
psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords);
psp->rgui.frame_coords = psp->frame_coords + 1;
psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords);
psp->rgui.frame_coords = TO_UNCACHED_PTR(psp->rgui.frame_coords);;
psp->frame_coords->v0.x = 60;
psp->frame_coords->v0.y = 0;
@ -276,7 +282,7 @@ error:
return (void*)-1;
}
//#define DISPLAY_FPS
#define DISPLAY_FPS
static bool psp_frame(void *data, const void *frame,
unsigned width, unsigned height, unsigned pitch, const char *msg)
@ -290,6 +296,9 @@ static bool psp_frame(void *data, const void *frame,
static int frames;
#endif
if (!width || !height)
return false;
sceGuSync(0, 0);
pspDebugScreenSetBase(psp->draw_buffer);
@ -312,6 +321,8 @@ static bool psp_frame(void *data, const void *frame,
if (psp->vsync)
sceDisplayWaitVblankStart();
#ifdef DISPLAY_FPS
frames++;
sceRtcGetCurrentTick(&currentTick);
@ -330,10 +341,6 @@ static bool psp_frame(void *data, const void *frame,
psp->draw_buffer = FROM_GU_POINTER(sceGuSwapBuffers());
g_extern.frame_count++;
/* frame dupes. */
if (frame == NULL)
return true;
psp->frame_coords->v0.x = (SCEGU_SCR_WIDTH - width * SCEGU_SCR_HEIGHT / height) / 2;
// psp->frame_coords->v0.y = 0;
// psp->frame_coords->v0.u = 0;
@ -346,18 +353,32 @@ static bool psp_frame(void *data, const void *frame,
sceGuStart(GU_DIRECT, psp->main_dList);
sceKernelDcacheWritebackRange(frame,pitch * height);
sceGuCopyImage(GU_PSM_5650, ((u32)frame & 0xF) >> psp->bpp_log2, 0, width, height, pitch >> psp->bpp_log2, (void*)((u32)frame & ~0xF), 0, 0, width, psp->texture);
if ((uint32_t)frame&0x04000000) // frame in VRAM ? texture/palette was set in core so draw directly
{
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, (void*)(psp->frame_coords));
}
else
{
if (frame!=NULL)
{
sceKernelDcacheWritebackRange(frame,pitch * height);
sceGuCopyImage(GU_PSM_5650, ((u32)frame & 0xF) >> psp->bpp_log2, 0, width, height, pitch >> psp->bpp_log2, (void*)((u32)frame & ~0xF), 0, 0, width, psp->texture);
}
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->texture);
sceGuCallList(psp->frame_dList);
if(psp->rgui.active)
sceGuCallList(psp->rgui.dList);
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->texture);
sceGuCallList(psp->frame_dList);
}
sceGuFinish();
if(psp->rgui.active)
{
sceGuSendList(GU_TAIL, psp->rgui.dList, &(psp->rgui.context_storage));
sceGuSync(0, 0);
}
return true;
}
@ -395,9 +416,13 @@ static void psp_free(void *data)
if (psp->frame_dList)
free(psp->frame_dList);
if (psp->frame_coords)
free(psp->frame_coords);
free(TO_CACHED_PTR(psp->frame_coords));
if (psp->rgui.frame_coords)
free(TO_CACHED_PTR(psp->rgui.frame_coords));
if (psp->rgui.dList)
free(psp->rgui.dList);
if (psp->rgui.frame)
free(psp->rgui.frame);
memset(psp, 0, sizeof(psp1_video_t));
@ -416,31 +441,53 @@ static void psp_set_rotation(void *data, unsigned rotation)
static void psp_set_texture_frame(void *data, const void *frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{
psp1_video_t *psp = (psp1_video_t*)data;
(void) rgb32;
(void) alpha;
psp->rgui.frame_coords->v0.x = 0;
psp->rgui.frame_coords->v0.y = 0;
psp->rgui.frame_coords->v0.u = 0;
psp->rgui.frame_coords->v0.v = 0;
int i;
psp1_video_t *psp = (psp1_video_t*)data;
#ifdef DEBUG
rarch_assert((width*height) < (480 * 272)); // psp->rgui.frame buffer size is (480 * 272)*2 Bytes
#endif
// rendering the rgui frame as a single sprite is slow
// so we render it as 16 vertical stripes instead
for (i=0;i<16;i++)
{
psp->rgui.frame_coords[i].v0.x = (i) * SCEGU_SCR_WIDTH / 16 ;
psp->rgui.frame_coords[i].v1.x = (i+1) * SCEGU_SCR_WIDTH / 16 ;
// psp->rgui.frame_coords[i].v0.y = 0;
psp->rgui.frame_coords[i].v1.y = SCEGU_SCR_HEIGHT ;
psp->rgui.frame_coords[i].v0.u = (i) * width / 16 ;
psp->rgui.frame_coords[i].v1.u = (i+1) * width / 16 ;
// psp->rgui.frame_coords[i].v0.v = 0;
psp->rgui.frame_coords[i].v1.v = height;
}
psp->rgui.frame_coords->v1.x = SCEGU_SCR_WIDTH;
psp->rgui.frame_coords->v1.y = SCEGU_SCR_HEIGHT;
psp->rgui.frame_coords->v1.u = width;
psp->rgui.frame_coords->v1.v = height;
sceKernelDcacheWritebackRange(frame,width * height * 2);
sceGuStart(GU_CALL, psp->rgui.dList);
sceGuStart(GU_DIRECT, psp->main_dList);
sceGuCopyImage(GU_PSM_4444, 0, 0, width, height, width, (void*)frame, 0, 0, width, psp->rgui.frame);
sceGuFinish();
sceGuStart(GU_SEND, psp->rgui.dList);
sceGuTexSync();
sceGuTexMode(GU_PSM_4444, 0, 0, GU_FALSE);
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, frame);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->rgui.frame);
sceGuEnable(GU_BLEND);
// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); // default blending
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, psp->rgui.frame_coords);
sceGuSync(GU_SYNC_LIST, 0);
;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 32, NULL, psp->rgui.frame_coords);
sceGuFinish();
}