diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 55845a8b23..a332b722cd 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -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) diff --git a/configuration.c b/configuration.c index aba56b93e2..6c89b29e0a 100644 --- a/configuration.c +++ b/configuration.c @@ -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; diff --git a/gfx/common/rsx_common.h b/gfx/common/rsx_common.h index e84cb8487d..44f3ce9e89 100644 --- a/gfx/common/rsx_common.h +++ b/gfx/common/rsx_common.h @@ -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 diff --git a/gfx/drivers/rsx_gfx.c b/gfx/drivers/rsx_gfx.c index 6f860efac5..e69a77dd59 100644 --- a/gfx/drivers/rsx_gfx.c +++ b/gfx/drivers/rsx_gfx.c @@ -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 - rsx_update_screen(gcm); - rsx_clear_surface(gcm); + 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); diff --git a/gfx/drivers/rsx_shaders/modern_alpha_blend.fcg b/gfx/drivers/rsx_shaders/modern_alpha_blend.fcg new file mode 100644 index 0000000000..623b1e652f --- /dev/null +++ b/gfx/drivers/rsx_shaders/modern_alpha_blend.fcg @@ -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; +} diff --git a/gfx/drivers/rsx_shaders/modern_alpha_blend.vcg b/gfx/drivers/rsx_shaders/modern_alpha_blend.vcg new file mode 100644 index 0000000000..59bb96f3f1 --- /dev/null +++ b/gfx/drivers/rsx_shaders/modern_alpha_blend.vcg @@ -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; +} diff --git a/gfx/drivers/rsx_shaders/modern_opaque.fcg b/gfx/drivers/rsx_shaders/modern_opaque.fcg new file mode 100644 index 0000000000..b4d55a90ad --- /dev/null +++ b/gfx/drivers/rsx_shaders/modern_opaque.fcg @@ -0,0 +1,9 @@ +void main +( + uniform sampler2D texture, + float2 texcoord : TEXCOORD0, + out float4 oColor : COLOR +) +{ + oColor = float4(tex2D(texture, texcoord).rgb, 1.0); +} diff --git a/gfx/drivers/rsx_shaders/modern_opaque.vcg b/gfx/drivers/rsx_shaders/modern_opaque.vcg new file mode 100644 index 0000000000..59bb96f3f1 --- /dev/null +++ b/gfx/drivers/rsx_shaders/modern_opaque.vcg @@ -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; +} diff --git a/gfx/drivers_display/gfx_display_rsx.c b/gfx/drivers_display/gfx_display_rsx.c index 4499b22b07..fd88b0b624 100644 --- a/gfx/drivers_display/gfx_display_rsx.c +++ b/gfx/drivers_display/gfx_display_rsx.c @@ -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); } diff --git a/gfx/drivers_font/rsx_font.c b/gfx/drivers_font/rsx_font.c index b299773c03..09340bb080 100644 --- a/gfx/drivers_font/rsx_font.c +++ b/gfx/drivers_font/rsx_font.c @@ -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) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 32549577a5..917e5864d3 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -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; } diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 25695a9974..63c6c742a3 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -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; diff --git a/input/drivers/psl1ght_input.c b/input/drivers/psl1ght_input.c index 4d4b228d76..fa7640cf40 100644 --- a/input/drivers/psl1ght_input.c +++ b/input/drivers/psl1ght_input.c @@ -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; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 3c735766c3..3c6d19b55b 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -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;