mirror of
https://github.com/libretro/RetroArch
synced 2025-02-01 00:32:46 +00:00
c0ccb8cda3
* (PSL1GHT) Use RSX_SHADER_STOCK_BLEND and RSX_SHADER_MENU defines * (PSL1GHT) Cleanup compiler warnings * (PSL1GHT) Make sure we compile with librt
231 lines
8.1 KiB
C
231 lines
8.1 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <retro_miscellaneous.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "../../config.h"
|
|
#endif
|
|
|
|
#include "../gfx_display.h"
|
|
|
|
#include "../common/rsx_common.h"
|
|
|
|
static const float rsx_vertexes[8] = {
|
|
0, 0,
|
|
1, 0,
|
|
0, 1,
|
|
1, 1
|
|
};
|
|
|
|
static const float rsx_tex_coords[8] = {
|
|
0, 1,
|
|
1, 1,
|
|
0, 0,
|
|
1, 0
|
|
};
|
|
|
|
static const float *gfx_display_rsx_get_default_vertices(void)
|
|
{
|
|
return &rsx_vertexes[0];
|
|
}
|
|
|
|
static const float *gfx_display_rsx_get_default_tex_coords(void)
|
|
{
|
|
return &rsx_tex_coords[0];
|
|
}
|
|
|
|
static void *gfx_display_rsx_get_default_mvp(void *data)
|
|
{
|
|
rsx_t *rsx = (rsx_t*)data;
|
|
|
|
if (!rsx)
|
|
return NULL;
|
|
|
|
return &rsx->mvp_no_rot;
|
|
}
|
|
|
|
static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
|
|
void *data, unsigned video_width, unsigned video_height)
|
|
{
|
|
unsigned i;
|
|
rsx_viewport_t vp;
|
|
int end_vert_idx;
|
|
rsx_vertex_t *vertices = NULL;
|
|
rsx_texture_t *texture = NULL;
|
|
const float *vertex = NULL;
|
|
const float *tex_coord = NULL;
|
|
const float *color = NULL;
|
|
rsx_t *rsx = (rsx_t*)data;
|
|
|
|
if (!rsx || !draw)
|
|
return;
|
|
|
|
texture = (rsx_texture_t *)draw->texture;
|
|
vertex = draw->coords->vertex;
|
|
tex_coord = draw->coords->tex_coord;
|
|
color = draw->coords->color;
|
|
|
|
if (!vertex)
|
|
vertex = &rsx_vertexes[0];
|
|
if (!tex_coord)
|
|
tex_coord = &rsx_tex_coords[0];
|
|
if (!draw->coords->lut_tex_coord)
|
|
draw->coords->lut_tex_coord = &rsx_tex_coords[0];
|
|
if (!draw->texture)
|
|
return;
|
|
|
|
vp.x = fabs(draw->x);
|
|
vp.y = fabs(rsx->height - draw->y - draw->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;
|
|
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(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[RSX_SHADER_STOCK_BLEND]->index, &texture->tex);
|
|
rsxTextureControl(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index,
|
|
GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
|
|
rsxTextureFilter(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, 0,
|
|
texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
|
|
rsxTextureWrapMode(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, texture->wrap_s,
|
|
texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
|
|
|
|
#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->texture_vert_idx = 0;
|
|
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
|
|
}
|
|
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[RSX_SHADER_STOCK_BLEND]);
|
|
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].u,
|
|
&rsx->uv_offset[RSX_SHADER_STOCK_BLEND]);
|
|
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].r,
|
|
&rsx->col_offset[RSX_SHADER_STOCK_BLEND]);
|
|
rsx->texture_vert_idx = end_vert_idx;
|
|
|
|
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
|
rsx->pos_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
|
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
|
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
|
rsx->uv_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
|
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
|
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
|
rsx->col_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 4,
|
|
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
|
|
|
rsxLoadVertexProgram(rsx->context, rsx->vpo[RSX_SHADER_STOCK_BLEND],
|
|
rsx->vp_ucode[RSX_SHADER_STOCK_BLEND]);
|
|
rsxSetVertexProgramParameter(rsx->context,
|
|
rsx->vpo[RSX_SHADER_STOCK_BLEND], rsx->proj_matrix[RSX_SHADER_STOCK_BLEND],
|
|
(float *)&rsx->mvp_no_rot);
|
|
rsxLoadFragmentProgramLocation(rsx->context,
|
|
rsx->fpo[RSX_SHADER_STOCK_BLEND], rsx->fp_offset[RSX_SHADER_STOCK_BLEND],
|
|
GCM_LOCATION_RSX);
|
|
|
|
rsxClearSurface(rsx->context, GCM_CLEAR_Z);
|
|
rsxDrawVertexArray(rsx->context, GCM_TYPE_TRIANGLE_STRIP, 0, draw->coords->vertices);
|
|
}
|
|
|
|
static void gfx_display_rsx_scissor_begin(void *data,
|
|
unsigned video_width,
|
|
unsigned video_height,
|
|
int x, int y,
|
|
unsigned width, unsigned height)
|
|
{
|
|
rsx_t *rsx = (rsx_t *)data;
|
|
rsxSetScissor(rsx->context, x, video_height - y - height, width, height);
|
|
}
|
|
|
|
static void gfx_display_rsx_scissor_end(
|
|
void *data,
|
|
unsigned video_width,
|
|
unsigned video_height)
|
|
{
|
|
rsx_t *rsx = (rsx_t *)data;
|
|
rsxSetScissor(rsx->context, 0, 0, video_width, video_height);
|
|
}
|
|
|
|
static void gfx_display_rsx_blend_begin(void *data)
|
|
{
|
|
rsx_t *rsx = (rsx_t *)data;
|
|
rsxSetBlendEnable(rsx->context, GCM_TRUE);
|
|
rsxSetBlendFunc(rsx->context, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA);
|
|
rsxSetBlendEquation(rsx->context, GCM_FUNC_ADD, GCM_FUNC_ADD);
|
|
#if 0
|
|
rsxSetBlendEnableMrt(rsx->context, GCM_TRUE, GCM_TRUE, GCM_TRUE);
|
|
rsxSetDepthFunc(rsx->context, GCM_LESS);
|
|
rsxSetDepthTestEnable(rsx->context, GCM_FALSE);
|
|
rsxSetAlphaFunc(rsx->context, GCM_ALWAYS, 0);
|
|
rsxSetAlphaTestEnable(rsx->context, GCM_TRUE);
|
|
#endif
|
|
}
|
|
|
|
static void gfx_display_rsx_blend_end(void *data)
|
|
{
|
|
rsx_t *rsx = (rsx_t *)data;
|
|
rsxSetBlendEnable(rsx->context, GCM_FALSE);
|
|
#if 0
|
|
rsxSetBlendEnableMrt(rsx->context, GCM_FALSE, GCM_FALSE, GCM_FALSE);
|
|
#endif
|
|
}
|
|
|
|
gfx_display_ctx_driver_t gfx_display_ctx_rsx = {
|
|
gfx_display_rsx_draw,
|
|
NULL, /* draw_pipeline */
|
|
gfx_display_rsx_blend_begin,
|
|
gfx_display_rsx_blend_end,
|
|
gfx_display_rsx_get_default_mvp,
|
|
gfx_display_rsx_get_default_vertices,
|
|
gfx_display_rsx_get_default_tex_coords,
|
|
FONT_DRIVER_RENDER_RSX,
|
|
GFX_VIDEO_DRIVER_RSX,
|
|
"rsx",
|
|
true,
|
|
gfx_display_rsx_scissor_begin,
|
|
gfx_display_rsx_scissor_end
|
|
};
|