From f7c9bc4e615b80414121b271ae55362bc94a7fe3 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Tue, 15 Jan 2019 01:08:28 +0100 Subject: [PATCH 1/2] Make GFX PS2 support palette in the cores --- gfx/drivers/ps2_gfx.c | 60 +++++++++----------- libretro-common/include/libretro.h | 1 + libretro-common/include/libretro_gskit_ps2.h | 55 ++++++++++++++++++ 3 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 libretro-common/include/libretro_gskit_ps2.h diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index e8df01d4e5..aab0c8f021 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -21,6 +21,7 @@ #include #include #include +#include "../../libretro-common/include/libretro_gskit_ps2.h" #define GS_TEXT GS_SETREG_RGBAQ(0x80,0x80,0x80,0x80,0x00) // turn white GS Screen #define GS_BLACK GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00) // turn white GS Screen @@ -34,6 +35,7 @@ typedef struct ps2_video GSTEXTURE *menuTexture; GSTEXTURE *coreTexture; bool clearVRAM; + struct retro_hw_render_interface_gskit_ps2 iface; /* Palette in the cores */ bool menuVisible; bool fullscreen; @@ -87,6 +89,11 @@ static void init_ps2_video(ps2_video_t *ps2) ps2->gsGlobal = init_GSGlobal(); ps2->menuTexture = prepare_new_texture(); ps2->coreTexture = prepare_new_texture(); + + /* Used for cores that supports palette */ + ps2->iface.interface_type = RETRO_HW_RENDER_INTERFACE_GSKIT_PS2; + ps2->iface.interface_version = RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION; + ps2->iface.coreTexture = ps2->coreTexture; } static void deinitTexture(GSTEXTURE *texture) @@ -97,26 +104,6 @@ static void deinitTexture(GSTEXTURE *texture) texture->Clut = NULL; } -static void color_correction32(uint32_t *buffer, uint32_t dimensions) -{ - uint32_t i; - uint32_t x32; - for (i = 0; i < dimensions; i++) { - x32 = buffer[i]; - buffer[i] = ((x32 >> 16) & 0xFF) | ((x32 << 16) & 0xFF0000) | (x32 & 0xFF00FF00); - } -} - -static void color_correction16(uint16_t *buffer, uint32_t dimensions) -{ - uint32_t i; - uint16_t x16; - for (i = 0; i < dimensions; i++) { - x16 = buffer[i]; - buffer[i] = (x16 & 0x8000) | ((x16 << 10) & 0x7C00) | ((x16 >> 1) & 0x3E0) | ((x16 >> 11) & 0x1F); - } -} - static bool texture_need_prepare(GSTEXTURE *texture, int width, int height, int PSM) { return texture->Width != width || texture->Height != height || texture->PSM != PSM; @@ -125,17 +112,6 @@ static bool texture_need_prepare(GSTEXTURE *texture, int width, int height, int static void transfer_texture(GSTEXTURE *texture, const void *frame, int width, int height, int PSM, int filter, bool color_correction) { - if (color_correction) { - int pixels = width * height; - if (PSM == GS_PSM_CT32) { - uint32_t *buffer = (uint32_t *)frame; - color_correction32(buffer, pixels); - } else { - uint16_t *buffer = (uint16_t *)frame; - color_correction16(buffer, pixels); - } - } - texture->Width = width; texture->Height = height; texture->PSM = PSM; @@ -150,6 +126,12 @@ static void vram_alloc(GSGLOBAL *gsGlobal, GSTEXTURE *texture) if(texture->Vram == GSKIT_ALLOC_ERROR) { printf("VRAM Allocation Failed. Will not upload texture.\n"); } + + if (texture->Clut) { + /* Right now just supporting 16 x 16 = 256 colours */ + size = gsKit_texture_size(16, 16, texture->ClutPSM); + texture->VramClut = gsKit_vram_alloc(gsGlobal, size , GSKIT_ALLOC_USERBUFFER); + } } static void prim_texture(GSGLOBAL *gsGlobal, GSTEXTURE *texture, int zPosition, bool force_aspect) @@ -190,7 +172,7 @@ static void prim_texture(GSGLOBAL *gsGlobal, GSTEXTURE *texture, int zPosition, static void clearVRAMIfNeeded(ps2_video_t *ps2, void *frame, int width, int height) { if (!ps2->clearVRAM) { - if(frame) { + if(frame && frame != RETRO_HW_FRAME_BUFFER_VALID) { bool coreVRAMClear = false; coreVRAMClear = texture_need_prepare(ps2->coreTexture, width, height, ps2->PSM); ps2->clearVRAM = ps2->clearVRAM || coreVRAMClear; @@ -263,7 +245,9 @@ static bool ps2_gfx_frame(void *data, const void *frame, clearVRAMIfNeeded(ps2, frame, width, height); if (frame) { - transfer_texture(ps2->coreTexture, frame, width, height, ps2->PSM, ps2->core_filter, 1); + if (frame != RETRO_HW_FRAME_BUFFER_VALID){ /* Checking if the transfer is done in the core */ + transfer_texture(ps2->coreTexture, frame, width, height, ps2->PSM, ps2->core_filter, 1); + } if(ps2->clearVRAM) { vram_alloc(ps2->gsGlobal, ps2->coreTexture); } @@ -430,6 +414,14 @@ static void ps2_set_osd_msg(void *data, font_driver_render_msg(video_info, font, msg, params); } +static bool ps2_get_hw_render_interface(void* data, + const struct retro_hw_render_interface** iface) +{ + ps2_video_t* ps2 = (ps2_video_t*)data; + *iface = (const struct retro_hw_render_interface*)&ps2->iface; + return true; +} + static const video_poke_interface_t ps2_poke_interface = { NULL, /* get_flags */ NULL, /* set_coords */ @@ -453,7 +445,7 @@ static const video_poke_interface_t ps2_poke_interface = { NULL, /* grab_mouse_toggle */ NULL, /* get_current_shader */ NULL, /* get_current_software_framebuffer */ - NULL /* get_hw_render_interface */ + ps2_get_hw_render_interface /* get_hw_render_interface */ }; static void ps2_gfx_get_poke_interface(void *data, diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 4e1a9785ba..8fc8845811 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1207,6 +1207,7 @@ enum retro_hw_render_interface_type RETRO_HW_RENDER_INTERFACE_D3D10 = 2, RETRO_HW_RENDER_INTERFACE_D3D11 = 3, RETRO_HW_RENDER_INTERFACE_D3D12 = 4, + RETRO_HW_RENDER_INTERFACE_GSKIT_PS2 = 5, RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX }; diff --git a/libretro-common/include/libretro_gskit_ps2.h b/libretro-common/include/libretro_gskit_ps2.h new file mode 100644 index 0000000000..5a8406aa92 --- /dev/null +++ b/libretro-common/include/libretro_gskit_ps2.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro API header (libretro_d3d.h) + * --------------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the + * "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_GSKIT_PS2_H_ +#define LIBRETRO_GSKIT_PS2_H_ + +#include "libretro.h" + +#if defined(PS2) + +#include + +#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 1 + +struct retro_hw_render_interface_gskit_ps2 +{ + /* Must be set to RETRO_HW_RENDER_INTERFACE_GSKIT_PS2. */ + enum retro_hw_render_interface_type interface_type; + /* Must be set to RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION. */ + unsigned interface_version; + + /* Opaque handle to the GSKit_PS2 backend in the frontend + * which must be passed along to all function pointers + * in this interface. + */ + GSTEXTURE *coreTexture; +}; +typedef struct retro_hw_render_interface_gskit_ps2 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2; + +#endif + +#endif /* LIBRETRO_GSKIT_PS2_H_ */ From 3706aa99041b5fa5f92b4ec7f960289417b0c3fd Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Tue, 15 Jan 2019 19:34:00 +0100 Subject: [PATCH 2/2] ClearVRAM detection improved --- gfx/drivers/ps2_gfx.c | 1 + libretro-common/include/libretro_gskit_ps2.h | 1 + 2 files changed, 2 insertions(+) diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index aab0c8f021..5971c53676 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -418,6 +418,7 @@ static bool ps2_get_hw_render_interface(void* data, const struct retro_hw_render_interface** iface) { ps2_video_t* ps2 = (ps2_video_t*)data; + ps2->iface.clearTexture = ps2->clearVRAM; *iface = (const struct retro_hw_render_interface*)&ps2->iface; return true; } diff --git a/libretro-common/include/libretro_gskit_ps2.h b/libretro-common/include/libretro_gskit_ps2.h index 5a8406aa92..e1e978d4c5 100644 --- a/libretro-common/include/libretro_gskit_ps2.h +++ b/libretro-common/include/libretro_gskit_ps2.h @@ -47,6 +47,7 @@ struct retro_hw_render_interface_gskit_ps2 * in this interface. */ GSTEXTURE *coreTexture; + bool clearTexture; }; typedef struct retro_hw_render_interface_gskit_ps2 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2;