mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
(PSP) some improvements to the video driver
add support for paletted frame texture in VRAM.
This commit is contained in:
parent
035e9b0919
commit
e060b67136
@ -77,10 +77,13 @@ typedef struct __attribute__((packed)) psp1_sprite
|
|||||||
typedef struct psp1_rgui_frame
|
typedef struct psp1_rgui_frame
|
||||||
{
|
{
|
||||||
void* dList;
|
void* dList;
|
||||||
psp1_sprite_t* frame_coords;
|
void* frame;
|
||||||
|
psp1_sprite_t* frame_coords;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
|
PspGeContext context_storage;
|
||||||
|
|
||||||
} psp1_rgui_frame_t;
|
} psp1_rgui_frame_t;
|
||||||
|
|
||||||
typedef struct psp1_video
|
typedef struct psp1_video
|
||||||
@ -125,15 +128,18 @@ static void *psp_init(const video_info_t *video,
|
|||||||
sceGuInit();
|
sceGuInit();
|
||||||
|
|
||||||
|
|
||||||
psp->main_dList = memalign(16,64 * 1024); // TODO: use a better approximation of maximum display list size
|
psp->main_dList = memalign(16, 256); // make sure to allocate more space if bigger display lists are needed.
|
||||||
psp->frame_dList = memalign(16,64 * 1024);
|
psp->frame_dList = memalign(16, 256);
|
||||||
psp->rgui.dList = memalign(16,64 * 1024);
|
psp->rgui.dList = memalign(16, 256);
|
||||||
psp->frame_coords = memalign(64, 2 * sizeof(psp1_sprite_t));
|
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();
|
sceKernelDcacheWritebackInvalidateAll();
|
||||||
psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords);
|
psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords);
|
||||||
psp->rgui.frame_coords = psp->frame_coords + 1;
|
psp->rgui.frame_coords = TO_UNCACHED_PTR(psp->rgui.frame_coords);;
|
||||||
|
|
||||||
psp->frame_coords->v0.x = 60;
|
psp->frame_coords->v0.x = 60;
|
||||||
psp->frame_coords->v0.y = 0;
|
psp->frame_coords->v0.y = 0;
|
||||||
@ -276,7 +282,7 @@ error:
|
|||||||
return (void*)-1;
|
return (void*)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define DISPLAY_FPS
|
#define DISPLAY_FPS
|
||||||
|
|
||||||
static bool psp_frame(void *data, const void *frame,
|
static bool psp_frame(void *data, const void *frame,
|
||||||
unsigned width, unsigned height, unsigned pitch, const char *msg)
|
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;
|
static int frames;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!width || !height)
|
||||||
|
return false;
|
||||||
|
|
||||||
sceGuSync(0, 0);
|
sceGuSync(0, 0);
|
||||||
|
|
||||||
pspDebugScreenSetBase(psp->draw_buffer);
|
pspDebugScreenSetBase(psp->draw_buffer);
|
||||||
@ -312,6 +321,8 @@ static bool psp_frame(void *data, const void *frame,
|
|||||||
if (psp->vsync)
|
if (psp->vsync)
|
||||||
sceDisplayWaitVblankStart();
|
sceDisplayWaitVblankStart();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DISPLAY_FPS
|
#ifdef DISPLAY_FPS
|
||||||
frames++;
|
frames++;
|
||||||
sceRtcGetCurrentTick(¤tTick);
|
sceRtcGetCurrentTick(¤tTick);
|
||||||
@ -330,10 +341,6 @@ static bool psp_frame(void *data, const void *frame,
|
|||||||
psp->draw_buffer = FROM_GU_POINTER(sceGuSwapBuffers());
|
psp->draw_buffer = FROM_GU_POINTER(sceGuSwapBuffers());
|
||||||
g_extern.frame_count++;
|
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.x = (SCEGU_SCR_WIDTH - width * SCEGU_SCR_HEIGHT / height) / 2;
|
||||||
// psp->frame_coords->v0.y = 0;
|
// psp->frame_coords->v0.y = 0;
|
||||||
// psp->frame_coords->v0.u = 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);
|
sceGuStart(GU_DIRECT, psp->main_dList);
|
||||||
|
|
||||||
sceKernelDcacheWritebackRange(frame,pitch * height);
|
if ((uint32_t)frame&0x04000000) // frame in VRAM ? texture/palette was set in core so draw directly
|
||||||
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);
|
||||||
|
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);
|
sceGuClear(GU_COLOR_BUFFER_BIT);
|
||||||
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->texture);
|
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->texture);
|
||||||
sceGuCallList(psp->frame_dList);
|
sceGuCallList(psp->frame_dList);
|
||||||
|
}
|
||||||
if(psp->rgui.active)
|
|
||||||
sceGuCallList(psp->rgui.dList);
|
|
||||||
|
|
||||||
sceGuFinish();
|
sceGuFinish();
|
||||||
|
|
||||||
|
if(psp->rgui.active)
|
||||||
|
{
|
||||||
|
sceGuSendList(GU_TAIL, psp->rgui.dList, &(psp->rgui.context_storage));
|
||||||
|
sceGuSync(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,9 +416,13 @@ static void psp_free(void *data)
|
|||||||
if (psp->frame_dList)
|
if (psp->frame_dList)
|
||||||
free(psp->frame_dList);
|
free(psp->frame_dList);
|
||||||
if (psp->frame_coords)
|
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)
|
if (psp->rgui.dList)
|
||||||
free(psp->rgui.dList);
|
free(psp->rgui.dList);
|
||||||
|
if (psp->rgui.frame)
|
||||||
|
free(psp->rgui.frame);
|
||||||
|
|
||||||
memset(psp, 0, sizeof(psp1_video_t));
|
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,
|
static void psp_set_texture_frame(void *data, const void *frame, bool rgb32,
|
||||||
unsigned width, unsigned height, float alpha)
|
unsigned width, unsigned height, float alpha)
|
||||||
{
|
{
|
||||||
psp1_video_t *psp = (psp1_video_t*)data;
|
|
||||||
(void) rgb32;
|
(void) rgb32;
|
||||||
(void) alpha;
|
(void) alpha;
|
||||||
|
|
||||||
psp->rgui.frame_coords->v0.x = 0;
|
int i;
|
||||||
psp->rgui.frame_coords->v0.y = 0;
|
psp1_video_t *psp = (psp1_video_t*)data;
|
||||||
psp->rgui.frame_coords->v0.u = 0;
|
|
||||||
psp->rgui.frame_coords->v0.v = 0;
|
#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);
|
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);
|
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);
|
sceGuEnable(GU_BLEND);
|
||||||
|
|
||||||
// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); // default blending
|
// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); // default blending
|
||||||
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F);
|
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();
|
sceGuFinish();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user