Vita: Fix scaling on PSTV when not using 720p

pull/12456/head
Francisco José García García 2021-05-29 19:05:35 +02:00
parent c226bd87f4
commit 35f7ef3cc2
1 changed files with 82 additions and 60 deletions

View File

@ -43,6 +43,7 @@ extern const SceGxmProgram texture_tint_f_gxp;
static vita2d_video_mode_data video_mode_data;
static vita2d_video_mode video_mode_initial;
static SceGxmMultisampleMode current_msaa = SCE_GXM_MULTISAMPLE_4X;
static int pgf_module_was_loaded = 0;
@ -157,6 +158,8 @@ vita2d_video_mode_data vita2d_get_video_mode_data(){
}
static int vita2d_switch_video_mode(vita2d_video_mode video_mode){
int i,x,y,err;
if(video_mode > video_mode_initial)
return -1;
switch (video_mode)
@ -164,7 +167,7 @@ static int vita2d_switch_video_mode(vita2d_video_mode video_mode){
case VITA2D_VIDEO_MODE_960x544:
video_mode_data.width = 960;
video_mode_data.height = 544;
video_mode_data.stride = 1280;
video_mode_data.stride = 960;
break;
case VITA2D_VIDEO_MODE_1280x720:
@ -181,6 +184,65 @@ static int vita2d_switch_video_mode(vita2d_video_mode video_mode){
clip_rect_x_max = video_mode_data.width;
clip_rect_y_max = video_mode_data.height;
if(renderTarget != NULL){
sceGxmDestroyRenderTarget(renderTarget);
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
// clear the buffer then deallocate
memset(displayBufferData[i], 0, video_mode_data.height*video_mode_data.stride*4);
gpu_free(displayBufferUid[i]);
}
}
// allocate memory and sync objects for display buffers
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
// allocate memory for display
displayBufferData[i] = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4*video_mode_data.stride*video_mode_data.height,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&displayBufferUid[i]);
// memset the buffer to black
for (y = 0; y < video_mode_data.height; y++) {
unsigned int *row = (unsigned int *)displayBufferData[i] + y*video_mode_data.stride;
for (x = 0; x < video_mode_data.width; x++) {
row[x] = 0xff000000;
}
}
// initialize a color surface for this display buffer
err = sceGxmColorSurfaceInit(
&displaySurface[i],
DISPLAY_COLOR_FORMAT,
SCE_GXM_COLOR_SURFACE_LINEAR,
(current_msaa == SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_NONE : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
video_mode_data.width,
video_mode_data.height,
video_mode_data.stride,
displayBufferData[i]);
}
// set up parameters
SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
renderTargetParams.flags = 0;
renderTargetParams.width = video_mode_data.width;
renderTargetParams.height = video_mode_data.height;
renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleMode = current_msaa;
renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1; // Invalid UID
// create the render target
err = sceGxmCreateRenderTarget(&renderTargetParams, &renderTarget);
VITA2D_DEBUG("sceGxmCreateRenderTarget(): 0x%08X\n", err);
matrix_init_orthographic(_vita2d_ortho_matrix, 0.0f, video_mode_data.width, video_mode_data.height, 0.0f, 0.0f, 1.0f);
return 0;
@ -198,7 +260,7 @@ static void display_callback(const void *callback_data)
framebuf.pixelformat = DISPLAY_PIXEL_FORMAT;
framebuf.width = video_mode_data.width;
framebuf.height = video_mode_data.height;
if(sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME)<0){
if(sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME) == SCE_DISPLAY_ERROR_INVALID_RESOLUTION){
if(video_mode_initial)
vita2d_switch_video_mode(VITA2D_VIDEO_MODE_960x544);
}
@ -258,7 +320,7 @@ static void _vita2d_make_fragment_programs(vita2d_fragment_programs *out,
static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMode msaa, vita2d_video_mode video_mode)
{
int err;
unsigned int i, x, y;
unsigned int i;
UNUSED(err);
if (vita2d_initialized) {
@ -267,12 +329,7 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
}
video_mode_initial = video_mode;
err = vita2d_switch_video_mode(video_mode);
if(err<0){
VITA2D_DEBUG("vita2d_switch_video_mode(): 0x%08X\n", err);
return err;
}
current_msaa = msaa;
SceGxmInitializeParams initializeParams;
memset(&initializeParams, 0, sizeof(SceGxmInitializeParams));
@ -329,51 +386,18 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
err = sceGxmCreateContext(&contextParams, &_vita2d_context);
VITA2D_DEBUG("sceGxmCreateContext(): 0x%08X\n", err);
// set up parameters
SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
renderTargetParams.flags = 0;
renderTargetParams.width = video_mode_data.width;
renderTargetParams.height = video_mode_data.height;
renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleMode = msaa;
renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1; // Invalid UID
err = vita2d_switch_video_mode(video_mode);
if(err<0){
VITA2D_DEBUG("vita2d_switch_video_mode(): 0x%08X\n", err);
return err;
}
// create the render target
err = sceGxmCreateRenderTarget(&renderTargetParams, &renderTarget);
VITA2D_DEBUG("sceGxmCreateRenderTarget(): 0x%08X\n", err);
vita2d_display_data displayData;
displayData.address = displayBufferData[0];
display_callback(&displayData);
// allocate memory and sync objects for display buffers
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
// allocate memory for display
displayBufferData[i] = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4*video_mode_data.stride*video_mode_data.height,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&displayBufferUid[i]);
// memset the buffer to black
for (y = 0; y < video_mode_data.height; y++) {
unsigned int *row = (unsigned int *)displayBufferData[i] + y*video_mode_data.stride;
for (x = 0; x < video_mode_data.width; x++) {
row[x] = 0xff000000;
}
}
// initialize a color surface for this display buffer
err = sceGxmColorSurfaceInit(
&displaySurface[i],
DISPLAY_COLOR_FORMAT,
SCE_GXM_COLOR_SURFACE_LINEAR,
(msaa == SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_NONE : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
video_mode_data.width,
video_mode_data.height,
video_mode_data.stride,
displayBufferData[i]);
// create a sync object that we will associate with this buffer
err = sceGxmSyncObjectCreate(&displayBufferSync[i]);
}
@ -383,11 +407,11 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
const unsigned int alignedHeight = ALIGN(video_mode_data.height, SCE_GXM_TILE_SIZEY);
unsigned int sampleCount = alignedWidth*alignedHeight;
unsigned int depthStrideInSamples = alignedWidth;
if (msaa == SCE_GXM_MULTISAMPLE_4X) {
if (current_msaa == SCE_GXM_MULTISAMPLE_4X) {
// samples increase in X and Y
sampleCount *= 4;
depthStrideInSamples *= 2;
} else if (msaa == SCE_GXM_MULTISAMPLE_2X) {
} else if (current_msaa == SCE_GXM_MULTISAMPLE_2X) {
// samples increase in Y only
sampleCount *= 2;
}
@ -572,7 +596,7 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
shaderPatcher,
clearFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
msaa,
current_msaa,
NULL,
clearVertexProgramGxp,
&clearFragmentProgram);
@ -731,8 +755,8 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err);
// Create variations of the fragment program based on blending mode
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_normal, &blend_info, msaa);
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_add, &blend_info_add, msaa);
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_normal, &blend_info, current_msaa);
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_add, &blend_info_add, current_msaa);
// Default to "normal" blending mode (non-additive)
vita2d_set_blend_mode_add(0);
@ -770,10 +794,6 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
if (pgf_module_was_loaded != SCE_SYSMODULE_LOADED)
sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
vita2d_display_data displayData;
displayData.address = displayBufferData[backBufferIndex];
display_callback(&displayData);
vita2d_initialized = 1;
return 1;
}
@ -795,7 +815,8 @@ int vita2d_init_advanced_with_msaa(unsigned int temp_pool_size, SceGxmMultisampl
void vita2d_wait_rendering_done()
{
sceGxmFinish(_vita2d_context);
if(vita2d_initialized)
sceGxmFinish(_vita2d_context);
}
int vita2d_fini()
@ -857,6 +878,7 @@ int vita2d_fini()
// destroy the render target
sceGxmDestroyRenderTarget(renderTarget);
renderTarget = NULL;
// destroy the _vita2d_context
sceGxmDestroyContext(_vita2d_context);