(PSL1GHT) Add improvements to the RSX driver (#14965)

* remove var error in psl1ght input

* (psl1ght) add modern_alpha_blend and modern_opaque rsx shaders

* (psl1ght) add perf improvements to the rsx driver

* add rsx gfx for psl1ght

* (psl1ght) set rsx as a compatible video driver

* Do xmb menu scaling for psl1ght

* (psl1ght) update Makefile to use latest shaders and more UI menu options
This commit is contained in:
OsirizX 2023-02-09 23:29:45 -08:00 committed by GitHub
parent 9195de67c0
commit 0549223677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 550 additions and 205 deletions

View File

@ -53,12 +53,14 @@ else
GIT = git.exe
endif
SHADER_OBJS = gfx/drivers/rsx_shaders/vpshader_basic.vpo.o \
gfx/drivers/rsx_shaders/fpshader_basic.fpo.o
SHADER_OBJS = gfx/drivers/rsx_shaders/modern_opaque.vpo.o \
gfx/drivers/rsx_shaders/modern_opaque.fpo.o \
gfx/drivers/rsx_shaders/modern_alpha_blend.vpo.o \
gfx/drivers/rsx_shaders/modern_alpha_blend.fpo.o
LIBCO_OBJ = libretro-common/libco/ps3.o
OBJ = $(SHADER_OBJS) $(LIBCO_OBJ) griffin/griffin.o
OBJ = $(SHADER_OBJS) $(LIBCO_OBJ) libretro-common/memmap/memmap.o griffin/griffin.o
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
@ -78,12 +80,11 @@ SHARED_FLAGS += -DHAVE_MENU \
-DRARCH_CONSOLE \
-DHAVE_OVERLAY \
-DHAVE_HEADSET \
-DHAVE_CG \
-DHAVE_CG_RUNTIME_COMPILER \
-DHAVE_SYSMODULES \
-DHAVE_SYSUTILS \
-DHAVE_RARCH_EXEC \
-DHAVE_MOUSE \
-DHAVE_LIGHTGUN \
-DHAVE_ZLIB \
-DHAVE_RPNG \
-DHAVE_GRIFFIN=1 \
@ -99,8 +100,15 @@ SHARED_FLAGS += -DHAVE_MENU \
-DHAVE_MULTIMAN \
-DHAVE_MEMINFO \
-DHAVE_RGUI \
-DHAVE_XMB \
-DHAVE_OZONE \
-DHAVE_GFX_WIDGETS \
-DHAVE_MENU_BUFFER \
-DHAVE_FREETYPE \
-DHAVE_CORE_INFO_CACHE
-DHAVE_CORE_INFO_CACHE \
-DHAVE_7ZIP \
-D_7ZIP_ST
CFLAGS += -std=gnu99 $(SHARED_FLAGS)
CXXFLAGS += $(SHARED_FLAGS)

View File

@ -3071,7 +3071,8 @@ static bool check_menu_driver_compatibility(settings_t *settings)
string_is_equal(video_driver, "vulkan") ||
string_is_equal(video_driver, "metal") ||
string_is_equal(video_driver, "ctr") ||
string_is_equal(video_driver, "vita2d")
string_is_equal(video_driver, "vita2d") ||
string_is_equal(video_driver, "rsx")
)
return true;

View File

@ -30,17 +30,30 @@
#include "../../retroarch.h"
#include "../video_coord_array.h"
#define MAX_BUFFERS 2
#define MAX_MENU_BUFFERS 2
#define RSX_MAX_BUFFERS 2
#define RSX_MAX_MENU_BUFFERS 2
#define RSX_MAX_TEXTURES 4
#define RSX_MAX_SHADERS 2
#define RSX_MAX_VERTICES 4
#define RSX_MAX_TEXTURE_VERTICES 4096 // Set > 0 for preallocated texture vertices
#define RSX_MAX_FONT_VERTICES 8192
#define GFX_MAX_SHADERS RSX_MAX_SHADERS
/* Shader objects */
extern const u8 vpshader_basic_vpo_end[];
extern const u8 vpshader_basic_vpo[];
extern const u32 vpshader_basic_vpo_size;
extern const u8 modern_opaque_vpo_end[];
extern const u8 modern_opaque_vpo[];
extern const u32 modern_opaque_vpo_size;
extern const u8 modern_opaque_fpo_end[];
extern const u8 modern_opaque_fpo[];
extern const u32 modern_opaque_fpo_size;
extern const u8 fpshader_basic_fpo_end[];
extern const u8 fpshader_basic_fpo[];
extern const u32 fpshader_basic_fpo_size;
extern const u8 modern_alpha_blend_vpo_end[];
extern const u8 modern_alpha_blend_vpo[];
extern const u32 modern_alpha_blend_vpo_size;
extern const u8 modern_alpha_blend_fpo_end[];
extern const u8 modern_alpha_blend_fpo[];
extern const u32 modern_alpha_blend_fpo_size;
typedef struct
{
@ -51,10 +64,9 @@ typedef struct
float offset[4];
} rsx_viewport_t;
typedef struct
typedef struct __attribute__((aligned(128)))
{
float x, y, z;
float nx, ny, nz;
float x, y;
float u, v;
float r, g, b, a;
} rsx_vertex_t;
@ -84,9 +96,9 @@ typedef struct
typedef struct {
video_viewport_t vp;
rsxBuffer buffers[MAX_BUFFERS];
rsxBuffer buffers[RSX_MAX_BUFFERS];
#if defined(HAVE_MENU_BUFFER)
rsxBuffer menuBuffers[MAX_MENU_BUFFERS];
rsxBuffer menuBuffers[RSX_MAX_MENU_BUFFERS];
int menuBuffer;
#endif
int currentBuffer, nextBuffer;
@ -103,27 +115,33 @@ typedef struct {
u32* depth_buffer;
#if defined(HAVE_MENU_BUFFER)
gcmSurface surface[MAX_BUFFERS+MAX_MENU_BUFFERS];
gcmSurface surface[RSX_MAX_BUFFERS+RSX_MAX_MENU_BUFFERS];
#else
gcmSurface surface[MAX_BUFFERS];
gcmSurface surface[RSX_MAX_BUFFERS];
#endif
rsx_texture_t texture;
int tex_index;
rsx_texture_t texture[RSX_MAX_TEXTURES];
rsx_texture_t menu_texture;
rsx_vertex_t *vertices;
u32 pos_offset;
u32 uv_offset;
u32 col_offset;
rsxProgramConst *proj_matrix;
rsxProgramAttrib* pos_index;
rsxProgramAttrib* col_index;
rsxProgramAttrib* uv_index;
rsxProgramAttrib* tex_unit;
void *vp_ucode;
void *fp_ucode;
rsxVertexProgram *vpo;
rsxFragmentProgram *fpo;
u32 *fp_buffer;
u32 fp_offset;
rsx_vertex_t *texture_vertices;
int vert_idx;
int texture_vert_idx;
int font_vert_idx;
u32 pos_offset[RSX_MAX_SHADERS];
u32 uv_offset[RSX_MAX_SHADERS];
u32 col_offset[RSX_MAX_SHADERS];
rsxProgramConst *proj_matrix[RSX_MAX_SHADERS];
rsxProgramConst *bgcolor[RSX_MAX_SHADERS];
rsxProgramAttrib *pos_index[RSX_MAX_SHADERS];
rsxProgramAttrib *col_index[RSX_MAX_SHADERS];
rsxProgramAttrib *uv_index[RSX_MAX_SHADERS];
rsxProgramAttrib *tex_unit[RSX_MAX_SHADERS];
void *vp_ucode[RSX_MAX_SHADERS];
void *fp_ucode[RSX_MAX_SHADERS];
rsxVertexProgram *vpo[RSX_MAX_SHADERS];
rsxFragmentProgram *fpo[RSX_MAX_SHADERS];
u32 *fp_buffer[RSX_MAX_SHADERS];
u32 fp_offset[RSX_MAX_SHADERS];
math_matrix_4x4 mvp, mvp_no_rot;
float menu_texture_alpha;
@ -141,9 +159,6 @@ typedef struct {
bool shared_context_use;
video_info_t video_info;
struct video_tex_info tex_info; /* unsigned int alignment */
struct video_tex_info prev_info[GFX_MAX_TEXTURES]; /* unsigned alignment */
struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS]; /* unsigned alignment */
} rsx_t;
#endif

View File

@ -300,11 +300,11 @@ static void rsx_init_render_target(rsx_t *rsx, rsxBuffer * buffer, int id)
static void rsx_init_vertices(rsx_t *rsx)
{
rsx->vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * 4);
rsx->vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * RSX_MAX_VERTICES); /* vertices for menu and core */
rsx->vert_idx = 0;
rsx->vertices[0].x = 0.0f;
rsx->vertices[0].y = 0.0f;
rsx->vertices[0].z = 0.0f;
rsx->vertices[0].u = 0.0f;
rsx->vertices[0].v = 1.0f;
rsx->vertices[0].r = 1.0f;
@ -314,7 +314,6 @@ static void rsx_init_vertices(rsx_t *rsx)
rsx->vertices[1].x = 1.0f;
rsx->vertices[1].y = 0.0f;
rsx->vertices[1].z = 0.0f;
rsx->vertices[1].u = 1.0f;
rsx->vertices[1].v = 1.0f;
rsx->vertices[1].r = 1.0f;
@ -324,7 +323,6 @@ static void rsx_init_vertices(rsx_t *rsx)
rsx->vertices[2].x = 0.0f;
rsx->vertices[2].y = 1.0f;
rsx->vertices[2].z = 0.0f;
rsx->vertices[2].u = 0.0f;
rsx->vertices[2].v = 0.0f;
rsx->vertices[2].r = 1.0f;
@ -334,7 +332,6 @@ static void rsx_init_vertices(rsx_t *rsx)
rsx->vertices[3].x = 1.0f;
rsx->vertices[3].y = 1.0f;
rsx->vertices[3].z = 0.0f;
rsx->vertices[3].u = 1.0f;
rsx->vertices[3].v = 0.0f;
rsx->vertices[3].r = 1.0f;
@ -342,35 +339,57 @@ static void rsx_init_vertices(rsx_t *rsx)
rsx->vertices[3].b = 1.0f;
rsx->vertices[3].a = 1.0f;
rsxAddressToOffset(&rsx->vertices[0].x, &rsx->pos_offset);
rsxAddressToOffset(&rsx->vertices[0].u, &rsx->uv_offset);
rsxAddressToOffset(&rsx->vertices[0].r, &rsx->col_offset);
#if RSX_MAX_TEXTURE_VERTICES > 0
/* Using preallocated texture vertices */
rsx->texture_vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * RSX_MAX_TEXTURE_VERTICES);
rsx->texture_vert_idx = 0;
#endif
}
static void rsx_init_shader(rsx_t *rsx)
{
u32 fpsize = 0;
u32 vpsize = 0;
rsx->vp_ucode = NULL;
rsx->fp_ucode = NULL;
rsx->vpo = (rsxVertexProgram *)vpshader_basic_vpo;
rsx->fpo = (rsxFragmentProgram *)fpshader_basic_fpo;
rsxVertexProgramGetUCode(rsx->vpo, &rsx->vp_ucode, &vpsize);
rsxFragmentProgramGetUCode(rsx->fpo, &rsx->fp_ucode, &fpsize);
rsx->fp_buffer = (u32 *)rsxMemalign(64, fpsize);
if (!rsx->fp_buffer)
rsx->vp_ucode[VIDEO_SHADER_MENU] = NULL;
rsx->fp_ucode[VIDEO_SHADER_MENU] = NULL;
rsx->vpo[VIDEO_SHADER_MENU] = (rsxVertexProgram *)modern_opaque_vpo;
rsx->fpo[VIDEO_SHADER_MENU] = (rsxFragmentProgram *)modern_opaque_fpo;
rsxVertexProgramGetUCode(rsx->vpo[VIDEO_SHADER_MENU], &rsx->vp_ucode[VIDEO_SHADER_MENU], &vpsize);
rsxFragmentProgramGetUCode(rsx->fpo[VIDEO_SHADER_MENU], &rsx->fp_ucode[VIDEO_SHADER_MENU], &fpsize);
rsx->fp_buffer[VIDEO_SHADER_MENU] = (u32 *)rsxMemalign(64, fpsize);
if (!rsx->fp_buffer[VIDEO_SHADER_MENU])
{
RARCH_LOG("failed to allocate fp_buffer\n");
return;
}
memcpy(rsx->fp_buffer, rsx->fp_ucode, fpsize);
rsxAddressToOffset(rsx->fp_buffer ,&rsx->fp_offset);
memcpy(rsx->fp_buffer[VIDEO_SHADER_MENU], rsx->fp_ucode[VIDEO_SHADER_MENU], fpsize);
rsxAddressToOffset(rsx->fp_buffer[VIDEO_SHADER_MENU], &rsx->fp_offset[VIDEO_SHADER_MENU]);
rsx->proj_matrix[VIDEO_SHADER_MENU] = rsxVertexProgramGetConst(rsx->vpo[VIDEO_SHADER_MENU], "modelViewProj");
rsx->pos_index[VIDEO_SHADER_MENU] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_MENU], "position");
rsx->col_index[VIDEO_SHADER_MENU] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_MENU], "color");
rsx->uv_index[VIDEO_SHADER_MENU] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_MENU], "texcoord");
rsx->tex_unit[VIDEO_SHADER_MENU] = rsxFragmentProgramGetAttrib(rsx->fpo[VIDEO_SHADER_MENU], "texture");
rsx->proj_matrix = rsxVertexProgramGetConst(rsx->vpo, "modelViewProj");
rsx->pos_index = rsxVertexProgramGetAttrib(rsx->vpo, "position");
rsx->col_index = rsxVertexProgramGetAttrib(rsx->vpo, "color");
rsx->uv_index = rsxVertexProgramGetAttrib(rsx->vpo, "texcoord");
rsx->tex_unit = rsxFragmentProgramGetAttrib(rsx->fpo, "texture");
rsx->vp_ucode[VIDEO_SHADER_STOCK_BLEND] = NULL;
rsx->fp_ucode[VIDEO_SHADER_STOCK_BLEND] = NULL;
rsx->vpo[VIDEO_SHADER_STOCK_BLEND] = (rsxVertexProgram *)modern_alpha_blend_vpo;
rsx->fpo[VIDEO_SHADER_STOCK_BLEND] = (rsxFragmentProgram *)modern_alpha_blend_fpo;
rsxVertexProgramGetUCode(rsx->vpo[VIDEO_SHADER_STOCK_BLEND], &rsx->vp_ucode[VIDEO_SHADER_STOCK_BLEND], &vpsize);
rsxFragmentProgramGetUCode(rsx->fpo[VIDEO_SHADER_STOCK_BLEND], &rsx->fp_ucode[VIDEO_SHADER_STOCK_BLEND], &fpsize);
rsx->fp_buffer[VIDEO_SHADER_STOCK_BLEND] = (u32 *)rsxMemalign(64, fpsize);
if (!rsx->fp_buffer[VIDEO_SHADER_STOCK_BLEND])
{
RARCH_LOG("failed to allocate fp_buffer\n");
return;
}
memcpy(rsx->fp_buffer[VIDEO_SHADER_STOCK_BLEND], rsx->fp_ucode[VIDEO_SHADER_STOCK_BLEND], fpsize);
rsxAddressToOffset(rsx->fp_buffer[VIDEO_SHADER_STOCK_BLEND], &rsx->fp_offset[VIDEO_SHADER_STOCK_BLEND]);
rsx->proj_matrix[VIDEO_SHADER_STOCK_BLEND] = rsxVertexProgramGetConst(rsx->vpo[VIDEO_SHADER_STOCK_BLEND], "modelViewProj");
rsx->pos_index[VIDEO_SHADER_STOCK_BLEND] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_STOCK_BLEND], "position");
rsx->col_index[VIDEO_SHADER_STOCK_BLEND] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_STOCK_BLEND], "color");
rsx->uv_index[VIDEO_SHADER_STOCK_BLEND] = rsxVertexProgramGetAttrib(rsx->vpo[VIDEO_SHADER_STOCK_BLEND], "texcoord");
rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND] = rsxFragmentProgramGetAttrib(rsx->fpo[VIDEO_SHADER_STOCK_BLEND], "texture");
rsx->bgcolor[VIDEO_SHADER_STOCK_BLEND] = rsxFragmentProgramGetConst(rsx->fpo[VIDEO_SHADER_STOCK_BLEND], "bgcolor");
}
static void* rsx_init(const video_info_t* video,
@ -384,9 +403,6 @@ static void* rsx_init(const video_info_t* video,
memset(rsx, 0, sizeof(rsx_t));
rsx->texture.data = NULL;
rsx->menu_texture.data = NULL;
rsx->context = rsx_init_screen(rsx);
const gfx_ctx_driver_t* ctx_driver = rsx_get_context(rsx);
@ -397,29 +413,34 @@ static void* rsx_init(const video_info_t* video,
rsx->ctx_driver = ctx_driver;
rsx->video_info = *video;
for (i = 0; i < MAX_BUFFERS; i++)
for (i = 0; i < RSX_MAX_BUFFERS; i++)
{
rsx_make_buffer(&rsx->buffers[i], rsx->width, rsx->height, i);
rsx_init_render_target(rsx, &rsx->buffers[i], i);
}
#if defined(HAVE_MENU_BUFFER)
for (i = 0; i < MAX_MENU_BUFFERS; i++)
for (i = 0; i < RSX_MAX_MENU_BUFFERS; i++)
{
rsx_make_buffer(&rsx->menuBuffers[i], rsx->width, rsx->height, i+MAX_BUFFERS);
rsx_init_render_target(rsx, &rsx->menuBuffers[i], i+MAX_BUFFERS);
rsx_make_buffer(&rsx->menuBuffers[i], rsx->width, rsx->height, i+RSX_MAX_BUFFERS);
rsx_init_render_target(rsx, &rsx->menuBuffers[i], i+RSX_MAX_BUFFERS);
}
#endif
rsx->texture.height = rsx->height;
rsx->texture.width = rsx->width;
for (i = 0; i < RSX_MAX_TEXTURES; i++)
{
rsx->texture[i].data = NULL;
rsx->texture[i].height = rsx->height;
rsx->texture[i].width = rsx->width;
}
rsx->menu_texture.data = NULL;
rsx->menu_texture.height = rsx->height;
rsx->menu_texture.width = rsx->width;
rsx_init_shader(rsx);
rsx_init_vertices(rsx);
rsx_flip(rsx->context, MAX_BUFFERS - 1);
rsx_flip(rsx->context, RSX_MAX_BUFFERS - 1);
rsx->vp.x = 0;
rsx->vp.y = 0;
@ -484,6 +505,101 @@ static void rsx_set_projection(rsx_t *rsx,
matrix_4x4_multiply(rsx->mvp, rot, rsx->mvp_no_rot);
}
static void rsx_update_viewport(rsx_t* rsx,
video_frame_info_t *video_info)
{
unsigned temp_width = rsx->width;
unsigned temp_height = rsx->height;
int x = 0;
int y = 0;
float device_aspect = ((float)temp_width) / temp_height;
float width = temp_width;
float height = temp_height;
settings_t *settings = config_get_ptr();
bool video_scale_integer = settings->bools.video_scale_integer;
unsigned aspect_ratio_idx = settings->uints.video_aspect_ratio_idx;
if (video_scale_integer)
{
video_viewport_get_scaled_integer(&rsx->vp, temp_width,
temp_height, video_driver_get_aspect_ratio(), rsx->keep_aspect);
width = rsx->vp.width;
height = rsx->vp.height;
}
else if (rsx->keep_aspect)
{
float desired_aspect = video_driver_get_aspect_ratio();
if ( (rsx->rotation == ORIENTATION_VERTICAL) ||
(rsx->rotation == ORIENTATION_FLIPPED_ROTATED))
{
device_aspect = 1.0 / device_aspect;
width = temp_height;
height = temp_width;
}
#if defined(HAVE_MENU)
if (aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
x = video_info->custom_vp_x;
y = video_info->custom_vp_y;
width = video_info->custom_vp_width;
height = video_info->custom_vp_height;
}
else
#endif
{
float delta;
if ((fabsf(device_aspect - desired_aspect) < 0.0001f))
{
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
else if (device_aspect > desired_aspect)
{
delta = (desired_aspect / device_aspect - 1.0f)
/ 2.0f + 0.5f;
x = (int)roundf(width * (0.5f - delta));
width = (unsigned)roundf(2.0f * width * delta);
}
else
{
delta = (device_aspect / desired_aspect - 1.0f)
/ 2.0f + 0.5f;
y = (int)roundf(height * (0.5f - delta));
height = (unsigned)roundf(2.0f * height * delta);
}
if ( (rsx->rotation == ORIENTATION_VERTICAL) ||
(rsx->rotation == ORIENTATION_FLIPPED_ROTATED)
)
{
x = (temp_width - width) * 0.5f;
y = (temp_height - height) * 0.5f;
}
}
rsx->vp.x = x;
rsx->vp.y = y;
rsx->vp.width = width;
rsx->vp.height = height;
}
else
{
rsx->vp.x = 0;
rsx->vp.y = 0;
rsx->vp.width = width;
rsx->vp.height = height;
}
rsx->vp.width += rsx->vp.width&0x1;
rsx->vp.height += rsx->vp.height&0x1;
rsx->should_resize = false;
}
static void rsx_set_viewport(void *data, unsigned viewport_width,
unsigned viewport_height, bool force_full, bool allow_rotate)
{
@ -633,9 +749,13 @@ static void rsx_unload_texture(void *data,
bool threaded, uintptr_t handle)
{
rsx_texture_t *texture = (rsx_texture_t *)handle;
if (texture) {
if (texture)
{
#if 0
/* TODO fix crash on loading core */
if(texture->data)
rsxFree(texture->data);
#endif
free(texture);
}
}
@ -772,7 +892,7 @@ static void rsx_load_texture_data(rsx_t* rsx, rsx_texture_t *texture,
bool rgb32, bool menu, enum texture_filter_type filter_type)
{
u32 mag_filter, min_filter;
u8 *texbuffer = (u8 *)texture->data;
u8 *texbuffer;
const u8 *data = (u8 *)frame;
if (!texture->data)
@ -781,6 +901,7 @@ static void rsx_load_texture_data(rsx_t* rsx, rsx_texture_t *texture,
rsxAddressToOffset(texture->data, &texture->offset);
}
texbuffer = (u8 *)texture->data;
memcpy(texbuffer, data, height * pitch);
texture->tex.format = (rgb32 ? GCM_TEXTURE_FORMAT_A8R8G8B8 :
@ -826,10 +947,19 @@ static void rsx_load_texture_data(rsx_t* rsx, rsx_texture_t *texture,
static void rsx_set_texture(rsx_t* rsx, rsx_texture_t *texture)
{
rsxInvalidateTextureCache(rsx->context, GCM_INVALIDATE_TEXTURE);
rsxLoadTexture(rsx->context, rsx->tex_unit->index, &texture->tex);
rsxTextureControl(rsx->context, rsx->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxTextureFilter(rsx->context, rsx->tex_unit->index, 0, texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
rsxTextureWrapMode(rsx->context, rsx->tex_unit->index, texture->wrap_s, texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
rsxLoadTexture(rsx->context, rsx->tex_unit[VIDEO_SHADER_MENU]->index, &texture->tex);
rsxTextureControl(rsx->context, rsx->tex_unit[VIDEO_SHADER_MENU]->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxTextureFilter(rsx->context, rsx->tex_unit[VIDEO_SHADER_MENU]->index, 0, texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
rsxTextureWrapMode(rsx->context, rsx->tex_unit[VIDEO_SHADER_MENU]->index, texture->wrap_s, texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
}
static void rsx_set_menu_texture(rsx_t* rsx, rsx_texture_t *texture)
{
rsxInvalidateTextureCache(rsx->context, GCM_INVALIDATE_TEXTURE);
rsxLoadTexture(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, &texture->tex);
rsxTextureControl(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxTextureFilter(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, 0, texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
rsxTextureWrapMode(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, texture->wrap_s, texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
}
static void rsx_clear_surface(rsx_t* rsx)
@ -864,33 +994,62 @@ static void rsx_clear_surface(rsx_t* rsx)
static void rsx_draw_vertices(rsx_t* rsx)
{
if (rsx->should_resize)
rsx_set_viewport(rsx, rsx->width, rsx->height, false, true);
int end_vert_idx = rsx->vert_idx + 4;
if (end_vert_idx > RSX_MAX_VERTICES)
{
rsx->vert_idx = 0;
end_vert_idx = rsx->vert_idx + 4;
}
rsx_vertex_t *vertices = &rsx->vertices[rsx->vert_idx];
rsx->vertices[0].r = 1.0f;
rsx->vertices[0].g = 1.0f;
rsx->vertices[0].b = 1.0f;
rsx->vertices[0].a = 1.0f;
rsx->vertices[1].r = 1.0f;
rsx->vertices[1].g = 1.0f;
rsx->vertices[1].b = 1.0f;
rsx->vertices[1].a = 1.0f;
rsx->vertices[2].r = 1.0f;
rsx->vertices[2].g = 1.0f;
rsx->vertices[2].b = 1.0f;
rsx->vertices[2].a = 1.0f;
rsx->vertices[3].r = 1.0f;
rsx->vertices[3].g = 1.0f;
rsx->vertices[3].b = 1.0f;
rsx->vertices[3].a = 1.0f;
vertices[rsx->vert_idx+0].x = 0.0f;
vertices[rsx->vert_idx+0].y = 0.0f;
vertices[rsx->vert_idx+0].u = 0.0f;
vertices[rsx->vert_idx+0].v = 1.0f;
vertices[rsx->vert_idx+0].r = 1.0f;
vertices[rsx->vert_idx+0].g = 1.0f;
vertices[rsx->vert_idx+0].b = 1.0f;
vertices[rsx->vert_idx+0].a = 1.0f;
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index->index, 0, rsx->pos_offset, sizeof(rsx_vertex_t), 3, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index->index, 0, rsx->uv_offset, sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index->index, 0, rsx->col_offset, sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
vertices[rsx->vert_idx+1].x = 1.0f;
vertices[rsx->vert_idx+1].y = 0.0f;
vertices[rsx->vert_idx+1].u = 1.0f;
vertices[rsx->vert_idx+1].v = 1.0f;
vertices[rsx->vert_idx+1].r = 1.0f;
vertices[rsx->vert_idx+1].g = 1.0f;
vertices[rsx->vert_idx+1].b = 1.0f;
vertices[rsx->vert_idx+1].a = 1.0f;
rsxLoadVertexProgram(rsx->context, rsx->vpo, rsx->vp_ucode);
rsxSetVertexProgramParameter(rsx->context, rsx->vpo, rsx->proj_matrix, (float *)&rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(rsx->context, rsx->fpo, rsx->fp_offset, GCM_LOCATION_RSX);
vertices[rsx->vert_idx+2].x = 0.0f;
vertices[rsx->vert_idx+2].y = 1.0f;
vertices[rsx->vert_idx+2].u = 0.0f;
vertices[rsx->vert_idx+2].v = 0.0f;
vertices[rsx->vert_idx+2].r = 1.0f;
vertices[rsx->vert_idx+2].g = 1.0f;
vertices[rsx->vert_idx+2].b = 1.0f;
vertices[rsx->vert_idx+2].a = 1.0f;
vertices[rsx->vert_idx+3].x = 1.0f;
vertices[rsx->vert_idx+3].y = 1.0f;
vertices[rsx->vert_idx+3].u = 1.0f;
vertices[rsx->vert_idx+3].v = 0.0f;
vertices[rsx->vert_idx+3].r = 1.0f;
vertices[rsx->vert_idx+3].g = 1.0f;
vertices[rsx->vert_idx+3].b = 1.0f;
vertices[rsx->vert_idx+3].a = 1.0f;
rsxAddressToOffset(&vertices[rsx->vert_idx].x, &rsx->pos_offset[VIDEO_SHADER_MENU]);
rsxAddressToOffset(&vertices[rsx->vert_idx].u, &rsx->uv_offset[VIDEO_SHADER_MENU]);
rsxAddressToOffset(&vertices[rsx->vert_idx].r, &rsx->col_offset[VIDEO_SHADER_MENU]);
rsx->vert_idx = end_vert_idx;
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[VIDEO_SHADER_MENU]->index, 0, rsx->pos_offset[VIDEO_SHADER_MENU], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[VIDEO_SHADER_MENU]->index, 0, rsx->uv_offset[VIDEO_SHADER_MENU], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[VIDEO_SHADER_MENU]->index, 0, rsx->col_offset[VIDEO_SHADER_MENU], sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxLoadVertexProgram(rsx->context, rsx->vpo[VIDEO_SHADER_MENU], rsx->vp_ucode[VIDEO_SHADER_MENU]);
rsxSetVertexProgramParameter(rsx->context, rsx->vpo[VIDEO_SHADER_MENU], rsx->proj_matrix[VIDEO_SHADER_MENU], (float *)&rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(rsx->context, rsx->fpo[VIDEO_SHADER_MENU], rsx->fp_offset[VIDEO_SHADER_MENU], GCM_LOCATION_RSX);
rsxClearSurface(rsx->context, GCM_CLEAR_Z);
rsxDrawVertexArray(rsx->context, GCM_TYPE_TRIANGLE_STRIP, 0, 4);
@ -899,33 +1058,62 @@ static void rsx_draw_vertices(rsx_t* rsx)
#if defined(HAVE_MENU)
static void rsx_draw_menu_vertices(rsx_t* rsx)
{
if (rsx->should_resize)
rsx_set_viewport(rsx, rsx->width, rsx->height, false, true);
int end_vert_idx = rsx->vert_idx + 4;
if (end_vert_idx > RSX_MAX_VERTICES)
{
rsx->vert_idx = 0;
end_vert_idx = rsx->vert_idx + 4;
}
rsx_vertex_t *vertices = &rsx->vertices[rsx->vert_idx];
rsx->vertices[0].r = 1.0f;
rsx->vertices[0].g = 1.0f;
rsx->vertices[0].b = 1.0f;
rsx->vertices[0].a = rsx->menu_texture_alpha;
rsx->vertices[1].r = 1.0f;
rsx->vertices[1].g = 1.0f;
rsx->vertices[1].b = 1.0f;
rsx->vertices[1].a = rsx->menu_texture_alpha;
rsx->vertices[2].r = 1.0f;
rsx->vertices[2].g = 1.0f;
rsx->vertices[2].b = 1.0f;
rsx->vertices[2].a = rsx->menu_texture_alpha;
rsx->vertices[3].r = 1.0f;
rsx->vertices[3].g = 1.0f;
rsx->vertices[3].b = 1.0f;
rsx->vertices[3].a = rsx->menu_texture_alpha;
vertices[rsx->vert_idx+0].x = 0.0f;
vertices[rsx->vert_idx+0].y = 0.0f;
vertices[rsx->vert_idx+0].u = 0.0f;
vertices[rsx->vert_idx+0].v = 1.0f;
vertices[rsx->vert_idx+0].r = 1.0f;
vertices[rsx->vert_idx+0].g = 1.0f;
vertices[rsx->vert_idx+0].b = 1.0f;
vertices[rsx->vert_idx+0].a = rsx->menu_texture_alpha;
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index->index, 0, rsx->pos_offset, sizeof(rsx_vertex_t), 3, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index->index, 0, rsx->uv_offset, sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index->index, 0, rsx->col_offset, sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
vertices[rsx->vert_idx+1].x = 1.0f;
vertices[rsx->vert_idx+1].y = 0.0f;
vertices[rsx->vert_idx+1].u = 1.0f;
vertices[rsx->vert_idx+1].v = 1.0f;
vertices[rsx->vert_idx+1].r = 1.0f;
vertices[rsx->vert_idx+1].g = 1.0f;
vertices[rsx->vert_idx+1].b = 1.0f;
vertices[rsx->vert_idx+1].a = rsx->menu_texture_alpha;
rsxLoadVertexProgram(rsx->context, rsx->vpo, rsx->vp_ucode);
rsxSetVertexProgramParameter(rsx->context, rsx->vpo, rsx->proj_matrix, (float *)&rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(rsx->context, rsx->fpo, rsx->fp_offset, GCM_LOCATION_RSX);
vertices[rsx->vert_idx+2].x = 0.0f;
vertices[rsx->vert_idx+2].y = 1.0f;
vertices[rsx->vert_idx+2].u = 0.0f;
vertices[rsx->vert_idx+2].v = 0.0f;
vertices[rsx->vert_idx+2].r = 1.0f;
vertices[rsx->vert_idx+2].g = 1.0f;
vertices[rsx->vert_idx+2].b = 1.0f;
vertices[rsx->vert_idx+2].a = rsx->menu_texture_alpha;
vertices[rsx->vert_idx+3].x = 1.0f;
vertices[rsx->vert_idx+3].y = 1.0f;
vertices[rsx->vert_idx+3].u = 1.0f;
vertices[rsx->vert_idx+3].v = 0.0f;
vertices[rsx->vert_idx+3].r = 1.0f;
vertices[rsx->vert_idx+3].g = 1.0f;
vertices[rsx->vert_idx+3].b = 1.0f;
vertices[rsx->vert_idx+3].a = rsx->menu_texture_alpha;
rsxAddressToOffset(&vertices[rsx->vert_idx].x, &rsx->pos_offset[VIDEO_SHADER_STOCK_BLEND]);
rsxAddressToOffset(&vertices[rsx->vert_idx].u, &rsx->uv_offset[VIDEO_SHADER_STOCK_BLEND]);
rsxAddressToOffset(&vertices[rsx->vert_idx].r, &rsx->col_offset[VIDEO_SHADER_STOCK_BLEND]);
rsx->vert_idx = end_vert_idx;
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->pos_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->uv_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->col_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxLoadVertexProgram(rsx->context, rsx->vpo[VIDEO_SHADER_STOCK_BLEND], rsx->vp_ucode[VIDEO_SHADER_STOCK_BLEND]);
rsxSetVertexProgramParameter(rsx->context, rsx->vpo[VIDEO_SHADER_STOCK_BLEND], rsx->proj_matrix[VIDEO_SHADER_STOCK_BLEND], (float *)&rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(rsx->context, rsx->fpo[VIDEO_SHADER_STOCK_BLEND], rsx->fp_offset[VIDEO_SHADER_STOCK_BLEND], GCM_LOCATION_RSX);
rsxSetBlendEnable(rsx->context, GCM_TRUE);
rsxSetBlendFunc(rsx->context, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA);
@ -945,18 +1133,18 @@ static void rsx_update_screen(rsx_t* gcm)
if (gcm->menu_frame_enable)
{
buffer = &gcm->menuBuffers[gcm->menuBuffer];
gcm->menuBuffer = (gcm->menuBuffer+1)%MAX_MENU_BUFFERS;
gcm->nextBuffer = MAX_BUFFERS + gcm->menuBuffer;
gcm->menuBuffer = (gcm->menuBuffer+1)%RSX_MAX_MENU_BUFFERS;
gcm->nextBuffer = RSX_MAX_BUFFERS + gcm->menuBuffer;
}
else
{
buffer = &gcm->buffers[gcm->currentBuffer];
gcm->currentBuffer = (gcm->currentBuffer+1)%MAX_BUFFERS;
gcm->currentBuffer = (gcm->currentBuffer+1)%RSX_MAX_BUFFERS;
gcm->nextBuffer = gcm->currentBuffer;
}
#else
buffer = &gcm->buffers[gcm->currentBuffer];
gcm->currentBuffer = (gcm->currentBuffer+1)%MAX_BUFFERS;
gcm->currentBuffer = (gcm->currentBuffer+1)%RSX_MAX_BUFFERS;
gcm->nextBuffer = gcm->currentBuffer;
#endif
@ -984,13 +1172,36 @@ static bool rsx_frame(void* data, const void* frame,
#ifdef HAVE_GFX_WIDGETS
bool widgets_active = video_info->widgets_active;
#endif
bool draw = false;
if (gcm->should_resize)
rsx_update_viewport(gcm, video_info);
rsx_viewport_t vp;
vp.min = 0.0f;
vp.max = 1.0f;
vp.x = gcm->vp.x;
vp.y = gcm->height - gcm->vp.y - gcm->vp.height;
vp.w = gcm->vp.width;
vp.h = gcm->vp.height;
vp.scale[0] = vp.w*0.5f;
vp.scale[1] = vp.h*-0.5f;
vp.scale[2] = (vp.max - vp.min)*0.5f;
vp.scale[3] = 0.0f;
vp.offset[0] = vp.x + vp.w*0.5f;
vp.offset[1] = vp.y + vp.h*0.5f;
vp.offset[2] = (vp.max + vp.min)*0.5f;
vp.offset[3] = 0.0f;
rsxSetViewport(gcm->context, vp.x, vp.y, vp.w, vp.h, vp.min, vp.max, vp.scale, vp.offset);
if(frame && width && height)
{
rsx_load_texture_data(gcm, &gcm->texture, frame, width, height, pitch, gcm->rgb32, false,
gcm->tex_index = ((gcm->tex_index + 1) % RSX_MAX_TEXTURES);
rsx_load_texture_data(gcm, &gcm->texture[gcm->tex_index], frame, width, height, pitch, gcm->rgb32, false,
gcm->smooth ? TEXTURE_FILTER_LINEAR : TEXTURE_FILTER_NEAREST);
rsx_set_texture(gcm, &gcm->texture);
rsx_set_texture(gcm, &gcm->texture[gcm->tex_index]);
rsx_draw_vertices(gcm);
draw = true;
}
#ifdef HAVE_MENU
@ -999,8 +1210,9 @@ static bool rsx_frame(void* data, const void* frame,
menu_driver_frame(menu_is_alive, video_info);
if (gcm->menu_texture.data)
{
rsx_set_texture(gcm, &gcm->menu_texture);
rsx_set_menu_texture(gcm, &gcm->menu_texture);
rsx_draw_menu_vertices(gcm);
draw = true;
}
};
@ -1022,8 +1234,15 @@ static bool rsx_frame(void* data, const void* frame,
#if 0
/* TODO: translucid menu */
#endif
if (draw)
{
/* Only update when we draw to prevent flickering when core frame duping is enabled */
rsx_update_screen(gcm);
rsx_clear_surface(gcm);
}
gcm->vert_idx = 0;
gcm->texture_vert_idx = 0;
gcm->font_vert_idx = 0;
return true;
}
@ -1051,23 +1270,30 @@ static void rsx_free(void* data)
rsxClearSurface(gcm->context, GCM_CLEAR_Z);
gcmSetWaitFlip(gcm->context);
for (i = 0; i < MAX_BUFFERS; i++)
rsxFree(gcm->buffers[i].ptr);
#if defined(HAVE_MENU_BUFFER)
for (i = 0; i < MAX_MENU_BUFFERS; i++)
rsxFree(gcm->menuBuffers[i].ptr);
#endif
#if 0
/* TODO fix crash on loading core */
if (gcm->vertices)
rsxFree(gcm->vertices);
if (gcm->texture.data)
rsxFree(gcm->texture.data);
if (gcm->texture_vertices)
rsxFree(gcm->texture_vertices);
for (i = 0; i < RSX_MAX_TEXTURES; i++)
{
if (gcm->texture[i].data)
rsxFree(gcm->texture[i].data);
}
if (gcm->menu_texture.data)
rsxFree(gcm->menu_texture.data);
for (i = 0; i < RSX_MAX_BUFFERS; i++)
rsxFree(gcm->buffers[i].ptr);
#if defined(HAVE_MENU_BUFFER)
for (i = 0; i < RSX_MAX_MENU_BUFFERS; i++)
rsxFree(gcm->menuBuffers[i].ptr);
#endif
if (gcm->depth_buffer)
rsxFree(gcm->depth_buffer);
if (gcm->fp_buffer)
rsxFree(gcm->fp_buffer);
#endif
#if 0
rsxFinish(gcm->context, 1);

View File

@ -0,0 +1,14 @@
void main
(
uniform sampler2D texture,
uniform float4 bgcolor,
float2 texcoord : TEXCOORD0,
float4 color : COLOR,
out float4 oColor : COLOR
)
{
if (bgcolor.a > 0.0)
oColor = bgcolor;
else
oColor = tex2D(texture, texcoord) * color;
}

View File

@ -0,0 +1,15 @@
void main
(
float2 texcoord,
float2 position,
float4 color,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
out float2 oTexCoord : TEXCOORD0,
out float4 oColor : COLOR
)
{
oPosition = mul(float4(position, 0.0, 1.0), modelViewProj);
oTexCoord = texcoord;
oColor = color;
}

View File

@ -0,0 +1,9 @@
void main
(
uniform sampler2D texture,
float2 texcoord : TEXCOORD0,
out float4 oColor : COLOR
)
{
oColor = float4(tex2D(texture, texcoord).rgb, 1.0);
}

View File

@ -0,0 +1,15 @@
void main
(
float2 texcoord,
float2 position,
float4 color,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
out float2 oTexCoord : TEXCOORD0,
out float4 oColor : COLOR
)
{
oPosition = mul(float4(position, 0.0, 1.0), modelViewProj);
oTexCoord = texcoord;
oColor = color;
}

View File

@ -67,6 +67,8 @@ static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
const float *color = NULL;
rsx_t *rsx = (rsx_t*)data;
rsx_viewport_t vp;
int end_vert_idx;
rsx_vertex_t *vertices;
if (!rsx || !draw)
return;
@ -87,8 +89,8 @@ static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
vp.x = fabs(draw->x);
vp.y = fabs(rsx->height - draw->y - draw->height);
vp.w = (draw->width <= rsx->width) ? draw->width : rsx->width;
vp.h = (draw->height <= rsx->height) ? draw->height : rsx->height;
vp.w = MIN(draw->width, rsx->width);
vp.h = MIN(draw->height, rsx->height);
vp.min = 0.0f;
vp.max = 1.0f;
vp.scale[0] = vp.w*0.5f;
@ -103,29 +105,50 @@ static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
rsxSetViewport(rsx->context, vp.x, vp.y, vp.w, vp.h, vp.min, vp.max, vp.scale, vp.offset);
rsxInvalidateTextureCache(rsx->context, GCM_INVALIDATE_TEXTURE);
rsxLoadTexture(rsx->context, rsx->tex_unit->index, &texture->tex);
rsxTextureControl(rsx->context, rsx->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxTextureFilter(rsx->context, rsx->tex_unit->index, 0, texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
rsxTextureWrapMode(rsx->context, rsx->tex_unit->index, texture->wrap_s, texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
rsxLoadTexture(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, &texture->tex);
rsxTextureControl(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxTextureFilter(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, 0, texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
rsxTextureWrapMode(rsx->context, rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND]->index, texture->wrap_s, texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
for (i = 0; i < draw->coords->vertices; i++)
#if RSX_MAX_TEXTURE_VERTICES > 0
/* Using preallocated texture vertices uses better memory managment but may cause more flickering */
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
if (end_vert_idx > RSX_MAX_TEXTURE_VERTICES)
{
rsx->vertices[i].x = *vertex++;
rsx->vertices[i].y = *vertex++;
rsx->vertices[i].z = 0.0f;
rsx->vertices[i].u = *tex_coord++;
rsx->vertices[i].v = *tex_coord++;
rsx->vertices[i].r = *color++;
rsx->vertices[i].g = *color++;
rsx->vertices[i].b = *color++;
rsx->vertices[i].a = *color++;
rsx->texture_vert_idx = 0;
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
}
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index->index, 0, rsx->pos_offset, sizeof(rsx_vertex_t), 3, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index->index, 0, rsx->uv_offset, sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index->index, 0, rsx->col_offset, sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
vertices = &rsx->texture_vertices[rsx->texture_vert_idx];
#else
/* Smoother gfx at the cost of unmanaged rsx memory */
rsx->texture_vert_idx = 0;
end_vert_idx = draw->coords->vertices;
vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * draw->coords->vertices);
#endif
for (i = rsx->texture_vert_idx; i < end_vert_idx; i++)
{
vertices[i].x = *vertex++;
vertices[i].y = *vertex++;
vertices[i].u = *tex_coord++;
vertices[i].v = *tex_coord++;
vertices[i].r = *color++;
vertices[i].g = *color++;
vertices[i].b = *color++;
vertices[i].a = *color++;
}
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].x, &rsx->pos_offset[VIDEO_SHADER_STOCK_BLEND]);
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].u, &rsx->uv_offset[VIDEO_SHADER_STOCK_BLEND]);
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].r, &rsx->col_offset[VIDEO_SHADER_STOCK_BLEND]);
rsx->texture_vert_idx = end_vert_idx;
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->pos_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->uv_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[VIDEO_SHADER_STOCK_BLEND]->index, 0, rsx->col_offset[VIDEO_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxLoadVertexProgram(rsx->context, rsx->vpo[VIDEO_SHADER_STOCK_BLEND], rsx->vp_ucode[VIDEO_SHADER_STOCK_BLEND]);
rsxSetVertexProgramParameter(rsx->context, rsx->vpo[VIDEO_SHADER_STOCK_BLEND], rsx->proj_matrix[VIDEO_SHADER_STOCK_BLEND], (float *)&rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(rsx->context, rsx->fpo[VIDEO_SHADER_STOCK_BLEND], rsx->fp_offset[VIDEO_SHADER_STOCK_BLEND], GCM_LOCATION_RSX);
rsxSetVertexProgramParameter(rsx->context,
rsx->vpo, rsx->proj_matrix, (float *)&rsx->mvp_no_rot);
rsxClearSurface(rsx->context, GCM_CLEAR_Z);
rsxDrawVertexArray(rsx->context, GCM_TYPE_TRIANGLE_STRIP, 0, draw->coords->vertices);
}

View File

@ -85,11 +85,13 @@ static void rsx_font_free(void *data,
rsxClearSurface(font->rsx->context, GCM_CLEAR_Z);
gcmSetWaitFlip(font->rsx->context);
#if 0
/* TODO fix crash on loading core */
if (font->texture.data)
rsxFree(font->texture.data);
if (font->vertices)
rsxFree(font->vertices);
#endif
free(font);
}
@ -159,23 +161,20 @@ static void *rsx_font_init(void *data,
font->atlas = font->font_driver->get_atlas(font->font_data);
font->vpo = font->rsx->vpo;
font->fpo = font->rsx->fpo;
font->fp_ucode = font->rsx->fp_ucode;
font->vp_ucode = font->rsx->vp_ucode;
font->fp_offset = font->rsx->fp_offset;
font->vpo = font->rsx->vpo[VIDEO_SHADER_STOCK_BLEND];
font->fpo = font->rsx->fpo[VIDEO_SHADER_STOCK_BLEND];
font->fp_ucode = font->rsx->fp_ucode[VIDEO_SHADER_STOCK_BLEND];
font->vp_ucode = font->rsx->vp_ucode[VIDEO_SHADER_STOCK_BLEND];
font->fp_offset = font->rsx->fp_offset[VIDEO_SHADER_STOCK_BLEND];
font->proj_matrix = font->rsx->proj_matrix;
font->pos_index = font->rsx->pos_index;
font->uv_index = font->rsx->uv_index;
font->col_index = font->rsx->col_index;
font->tex_unit = font->rsx->tex_unit;
font->proj_matrix = font->rsx->proj_matrix[VIDEO_SHADER_STOCK_BLEND];
font->pos_index = font->rsx->pos_index[VIDEO_SHADER_STOCK_BLEND];
font->uv_index = font->rsx->uv_index[VIDEO_SHADER_STOCK_BLEND];
font->col_index = font->rsx->col_index[VIDEO_SHADER_STOCK_BLEND];
font->tex_unit = font->rsx->tex_unit[VIDEO_SHADER_STOCK_BLEND];
font->vertices = (rsx_vertex_t *)rsxMemalign(128, MAX_MSG_LEN_CHUNK*sizeof(rsx_vertex_t)*6);
rsxAddressToOffset(&font->vertices[0].x, &font->pos_offset);
rsxAddressToOffset(&font->vertices[0].u, &font->uv_offset);
rsxAddressToOffset(&font->vertices[0].r, &font->col_offset);
font->vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * RSX_MAX_FONT_VERTICES);
font->rsx->font_vert_idx = 0;
font->tex_width = font->atlas->width;
font->tex_height = font->atlas->height;
@ -245,24 +244,37 @@ static void rsx_font_draw_vertices(rsx_font_t *font,
font->atlas->dirty = false;
}
for (i = 0; i < coords->vertices; i++)
int end_vert_idx = font->rsx->font_vert_idx + coords->vertices;
if (end_vert_idx > RSX_MAX_FONT_VERTICES)
{
font->vertices[i].x = *vertex++;
font->vertices[i].y = *vertex++;
font->vertices[i].z = 0.0f;
font->vertices[i].u = *tex_coord++;
font->vertices[i].v = *tex_coord++;
font->vertices[i].r = *color++;
font->vertices[i].g = *color++;
font->vertices[i].b = *color++;
font->vertices[i].a = *color++;
font->rsx->font_vert_idx = 0;
end_vert_idx = font->rsx->font_vert_idx + coords->vertices;
}
rsx_vertex_t *vertices = &font->vertices[font->rsx->font_vert_idx];
for (i = font->rsx->font_vert_idx; i < end_vert_idx; i++)
{
vertices[i].x = *vertex++;
vertices[i].y = *vertex++;
vertices[i].u = *tex_coord++;
vertices[i].v = *tex_coord++;
vertices[i].r = *color++;
vertices[i].g = *color++;
vertices[i].b = *color++;
vertices[i].a = *color++;
}
rsxAddressToOffset(&vertices[font->rsx->font_vert_idx].x, &font->pos_offset);
rsxAddressToOffset(&vertices[font->rsx->font_vert_idx].u, &font->uv_offset);
rsxAddressToOffset(&vertices[font->rsx->font_vert_idx].r, &font->col_offset);
font->rsx->font_vert_idx = end_vert_idx;
rsxBindVertexArrayAttrib(font->rsx->context, font->pos_index->index, 0, font->pos_offset, sizeof(rsx_vertex_t), 3, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(font->rsx->context, font->pos_index->index, 0, font->pos_offset, sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(font->rsx->context, font->uv_index->index, 0, font->uv_offset, sizeof(rsx_vertex_t), 2, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxBindVertexArrayAttrib(font->rsx->context, font->col_index->index, 0, font->col_offset, sizeof(rsx_vertex_t), 4, GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
rsxSetVertexProgramParameter(font->rsx->context, font->vpo, font->proj_matrix, (float*)&font->rsx->mvp_no_rot);
rsxLoadVertexProgram(font->rsx->context, font->vpo, font->vp_ucode);
rsxSetVertexProgramParameter(font->rsx->context, font->vpo, font->proj_matrix, (float *)&font->rsx->mvp_no_rot);
rsxLoadFragmentProgramLocation(font->rsx->context, font->fpo, font->fp_offset, GCM_LOCATION_RSX);
rsxClearSurface(font->rsx->context, GCM_CLEAR_Z);
rsxDrawVertexArray(font->rsx->context, GCM_TYPE_TRIANGLES, 0, coords->vertices);
}
@ -397,12 +409,9 @@ static void rsx_font_setup_viewport(unsigned width, unsigned height,
if (font->rsx)
{
rsxSetBlendEnable(font->rsx->context, GCM_TRUE);
rsxSetBlendFunc(font->rsx->context, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA);
rsxSetBlendEquation(font->rsx->context, GCM_FUNC_ADD, GCM_FUNC_ADD);
rsxSetBlendEnable(font->rsx->context, GCM_TRUE);
rsxLoadVertexProgram(font->rsx->context, font->vpo, font->vp_ucode);
rsxLoadFragmentProgramLocation(font->rsx->context, font->fpo, font->fp_offset, GCM_LOCATION_RSX);
rsxLoadTexture(font->rsx->context, font->tex_unit->index, &font->texture.tex);
rsxTextureControl(font->rsx->context, font->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
@ -503,10 +512,12 @@ static void rsx_font_render_msg(
if (!font->block)
{
rsxTextureControl(font->rsx->context, font->rsx->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
/* restore viewport */
rsxTextureControl(font->rsx->context, font->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxSetBlendEnable(font->rsx->context, GCM_FALSE);
video_driver_set_viewport(width, height, false, true);
}
font->rsx->font_vert_idx = 0;
}
}
@ -533,10 +544,12 @@ static void rsx_font_flush_block(unsigned width, unsigned height,
if (font->rsx)
{
rsxTextureControl(font->rsx->context, font->rsx->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
/* restore viewport */
rsxTextureControl(font->rsx->context, font->tex_unit->index, GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
rsxSetBlendEnable(font->rsx->context, GCM_FALSE);
video_driver_set_viewport(width, height, block->fullscreen, true);
}
font->rsx->font_vert_idx = 0;
}
static void rsx_font_bind_block(void *data, void *userdata)

View File

@ -119,9 +119,13 @@ static const gfx_ctx_driver_t *gfx_ctx_gl_drivers[] = {
#if defined(HAVE_VITAGL) | defined(HAVE_VITAGLES)
&vita_ctx,
#endif
#if !defined(__PSL1GHT__) && defined(__PS3__)
#if defined(__PS3__)
#if defined(__PSL1GHT__)
&gfx_ctx_psl1ght,
#else
&gfx_ctx_ps3,
#endif
#endif
#if defined(HAVE_LIBNX) && defined(HAVE_OPENGL)
&switch_ctx,
#endif
@ -3164,6 +3168,8 @@ enum gfx_ctx_api video_context_driver_get_api(void)
return GFX_CTX_VULKAN_API;
else if (string_is_equal(video_ident, "metal"))
return GFX_CTX_METAL_API;
else if (string_is_equal(video_ident, "rsx"))
return GFX_CTX_RSX_API;
return GFX_CTX_NONE;
}

View File

@ -1411,6 +1411,7 @@ extern const gfx_ctx_driver_t gfx_ctx_vivante_fbdev;
extern const gfx_ctx_driver_t gfx_ctx_android;
extern const gfx_ctx_driver_t gfx_ctx_vk_android;
extern const gfx_ctx_driver_t gfx_ctx_ps3;
extern const gfx_ctx_driver_t gfx_ctx_psl1ght;
extern const gfx_ctx_driver_t gfx_ctx_w_vk;
extern const gfx_ctx_driver_t gfx_ctx_wgl;
extern const gfx_ctx_driver_t gfx_ctx_videocore;

View File

@ -160,7 +160,6 @@ int setupCamera(ps3_input_t *ps3)
ps3->camread.buffer = ps3->camInf.buffer;
ps3->camread.version = 0x0100;
ps3->cam_buf = (u8 *)(u64)ps3->camread.buffer;
ps3->camread.buffer);
break;
default:
error = 1;

View File

@ -901,7 +901,7 @@ static void xmb_draw_icon(
draw.height = icon_size;
draw.rotation = rotation;
draw.scale_factor = scale_factor;
#if defined(VITA) || defined(WIIU)
#if defined(VITA) || defined(WIIU) || defined(__PSL1GHT__)
draw.width *= scale_factor;
draw.height *= scale_factor;
#endif
@ -919,7 +919,7 @@ static void xmb_draw_icon(
draw.x = x + shadow_offset;
draw.y = height - y - shadow_offset;
#if defined(VITA) || defined(WIIU)
#if defined(VITA) || defined(WIIU) || defined(__PSL1GHT__)
if (scale_factor < 1)
{
draw.x = draw.x + (icon_size-draw.width)/2;
@ -935,7 +935,7 @@ static void xmb_draw_icon(
draw.x = x;
draw.y = height - y;
#if defined(VITA) || defined(WIIU)
#if defined(VITA) || defined(WIIU) || defined(__PSL1GHT__)
if (scale_factor < 1)
{
draw.x = draw.x + (icon_size-draw.width)/2;