mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 16:39:43 +00:00
Be more conservative about texture memory usage.
This commit is contained in:
parent
911558462a
commit
6b4924c844
91
gfx/gl.c
91
gfx/gl.c
@ -627,8 +627,16 @@ void gl_init_fbo(void *data, unsigned width, unsigned height)
|
||||
}
|
||||
|
||||
#ifndef HAVE_RGL
|
||||
static void gl_deinit_hw_render(gl_t *gl)
|
||||
{
|
||||
if (gl->hw_render_fbo_init)
|
||||
glDeleteFramebuffers(gl->textures, gl->hw_render_fbo);
|
||||
if (gl->hw_render_depth_init)
|
||||
glDeleteRenderbuffers(gl->textures, gl->hw_render_depth);
|
||||
gl->hw_render_fbo_init = false;
|
||||
}
|
||||
|
||||
bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
static bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
{
|
||||
RARCH_LOG("[GL]: Initializing HW render (%u x %u).\n", width, height);
|
||||
GLint max_fbo_size = 0;
|
||||
@ -641,7 +649,7 @@ bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glGenFramebuffers(TEXTURES, gl->hw_render_fbo);
|
||||
glGenFramebuffers(gl->textures, gl->hw_render_fbo);
|
||||
|
||||
bool depth = g_extern.system.hw_render_callback.depth;
|
||||
bool stencil = g_extern.system.hw_render_callback.stencil;
|
||||
@ -653,11 +661,11 @@ bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
|
||||
if (depth)
|
||||
{
|
||||
glGenRenderbuffers(TEXTURES, gl->hw_render_depth);
|
||||
glGenRenderbuffers(gl->textures, gl->hw_render_depth);
|
||||
gl->hw_render_depth_init = true;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < TEXTURES; i++)
|
||||
for (unsigned i = 0; i < gl->textures; i++)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl->hw_render_fbo[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->texture[i], 0);
|
||||
@ -1019,8 +1027,8 @@ static void gl_update_input_size(void *data, unsigned width, unsigned height, un
|
||||
set_texture_coords(gl->tex_coords, xamt, yamt);
|
||||
}
|
||||
// We might have used different texture coordinates last frame. Edge case if resolution changes very rapidly.
|
||||
else if (width != gl->last_width[(gl->tex_index - 1) & TEXTURES_MASK] ||
|
||||
height != gl->last_height[(gl->tex_index - 1) & TEXTURES_MASK])
|
||||
else if (width != gl->last_width[(gl->tex_index + gl->textures - 1) % gl->textures] ||
|
||||
height != gl->last_height[(gl->tex_index + gl->textures - 1) % gl->textures])
|
||||
{
|
||||
GLfloat xamt = (GLfloat)width / gl->tex_w;
|
||||
GLfloat yamt = (GLfloat)height / gl->tex_h;
|
||||
@ -1077,13 +1085,13 @@ static inline void gl_convert_frame_argb8888_abgr8888(void *data, void *output,
|
||||
static void gl_init_textures_data(void *data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
for (unsigned i = 0; i < TEXTURES; i++)
|
||||
for (unsigned i = 0; i < gl->textures; i++)
|
||||
{
|
||||
gl->last_width[i] = gl->tex_w;
|
||||
gl->last_height[i] = gl->tex_h;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < TEXTURES; i++)
|
||||
for (unsigned i = 0; i < gl->textures; i++)
|
||||
{
|
||||
gl->prev_info[i].tex = gl->texture[0];
|
||||
gl->prev_info[i].input_size[0] = gl->tex_w;
|
||||
@ -1110,7 +1118,7 @@ static void gl_init_textures(void *data, const video_info_t *video)
|
||||
|
||||
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, gl->pbo);
|
||||
glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE,
|
||||
gl->tex_w * gl->tex_h * gl->base_size * TEXTURES, NULL, GL_STREAM_DRAW);
|
||||
gl->tex_w * gl->tex_h * gl->base_size * gl->textures, NULL, GL_STREAM_DRAW);
|
||||
#endif
|
||||
|
||||
GLenum internal_fmt = gl->internal_fmt;
|
||||
@ -1141,9 +1149,9 @@ static void gl_init_textures(void *data, const video_info_t *video)
|
||||
}
|
||||
#endif
|
||||
|
||||
glGenTextures(TEXTURES, gl->texture);
|
||||
glGenTextures(gl->textures, gl->texture);
|
||||
|
||||
for (unsigned i = 0; i < TEXTURES; i++)
|
||||
for (unsigned i = 0; i < gl->textures; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
|
||||
|
||||
@ -1264,7 +1272,7 @@ static inline void gl_copy_frame(void *data, const void *frame, unsigned width,
|
||||
static inline void gl_set_prev_texture(void *data, const struct gl_tex_info *tex_info)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
memmove(gl->prev_info + 1, gl->prev_info, sizeof(*tex_info) * (TEXTURES - 1));
|
||||
memmove(gl->prev_info + 1, gl->prev_info, sizeof(*tex_info) * (gl->textures - 1));
|
||||
memcpy(&gl->prev_info[0], tex_info, sizeof(*tex_info));
|
||||
}
|
||||
|
||||
@ -1386,7 +1394,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
|
||||
if (frame) // Can be NULL for frame dupe / NULL render.
|
||||
{
|
||||
gl->tex_index = (gl->tex_index + 1) & TEXTURES_MASK;
|
||||
gl->tex_index = (gl->tex_index + 1) % gl->textures;
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
@ -1555,7 +1563,7 @@ static void gl_free(void *data)
|
||||
gl_disable_client_arrays(gl);
|
||||
#endif
|
||||
|
||||
glDeleteTextures(TEXTURES, gl->texture);
|
||||
glDeleteTextures(gl->textures, gl->texture);
|
||||
|
||||
#if defined(HAVE_RGUI) || defined(HAVE_RMENU)
|
||||
if (gl->rgui_texture)
|
||||
@ -1584,13 +1592,8 @@ static void gl_free(void *data)
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
gl_deinit_fbo(gl);
|
||||
|
||||
#ifndef HAVE_RGL
|
||||
if (gl->hw_render_fbo_init)
|
||||
glDeleteFramebuffers(TEXTURES, gl->hw_render_fbo);
|
||||
if (gl->hw_render_depth_init)
|
||||
glDeleteRenderbuffers(TEXTURES, gl->hw_render_depth);
|
||||
gl->hw_render_fbo_init = false;
|
||||
gl_deinit_hw_render(gl);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -1707,7 +1710,7 @@ static inline void gl_reinit_textures(void *data, const video_info_t *video)
|
||||
#endif
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(TEXTURES, gl->texture);
|
||||
glDeleteTextures(gl->textures, gl->texture);
|
||||
|
||||
gl_init_textures(gl, video);
|
||||
gl_init_textures_data(gl);
|
||||
@ -1836,6 +1839,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gl->video_info = *video;
|
||||
|
||||
RARCH_LOG("Found GL context: %s\n", gl->ctx_driver->ident);
|
||||
|
||||
context_get_video_size_func(&gl->full_x, &gl->full_y);
|
||||
@ -1887,6 +1892,9 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
struct retro_hw_render_callback *hw_render = &g_extern.system.hw_render_callback;
|
||||
gl->vertex_ptr = hw_render->bottom_left_origin ? vertexes : vertexes_flipped;
|
||||
|
||||
// Better pipelining with GPU due to synchronous glSubTexImage. Multiple async PBOs would be an alternative,
|
||||
// but still need multiple textures with PREV.
|
||||
gl->textures = 4;
|
||||
#ifdef HAVE_FBO
|
||||
#ifdef HAVE_OPENGLES2
|
||||
gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES2;
|
||||
@ -1894,6 +1902,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGL ||
|
||||
g_extern.system.hw_render_callback.context_type == RETRO_HW_CONTEXT_OPENGL_CORE;
|
||||
#endif
|
||||
if (gl->hw_render_use)
|
||||
gl->textures = 1; // All on GPU, no need to excessively create textures.
|
||||
#endif
|
||||
gl->white_color_ptr = white_color;
|
||||
|
||||
@ -1910,6 +1920,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gl->shader)
|
||||
{
|
||||
unsigned minimum = gl->shader->get_prev_textures();
|
||||
gl->textures = max(minimum + 1, gl->textures);
|
||||
}
|
||||
|
||||
RARCH_LOG("GL: Using %u textures.\n", gl->textures);
|
||||
RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num(gl));
|
||||
|
||||
gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
|
||||
@ -2027,12 +2044,13 @@ static void gl_update_tex_filter_frame(gl_t *gl)
|
||||
if (!gl_shader_filter_type(gl, 1, &smooth))
|
||||
smooth = g_settings.video.smooth;
|
||||
|
||||
gl->video_info.smooth = smooth;
|
||||
GLuint new_filt = smooth ? GL_LINEAR : GL_NEAREST;
|
||||
if (new_filt == gl->tex_filter)
|
||||
return;
|
||||
|
||||
gl->tex_filter = new_filt;
|
||||
for (unsigned i = 0; i < TEXTURES; i++)
|
||||
for (unsigned i = 0; i < gl->textures; i++)
|
||||
{
|
||||
if (gl->texture[i])
|
||||
{
|
||||
@ -2096,6 +2114,33 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
|
||||
gl_update_tex_filter_frame(gl);
|
||||
|
||||
if (gl->shader)
|
||||
{
|
||||
unsigned textures = gl->shader->get_prev_textures() + 1;
|
||||
if (textures > gl->textures) // Have to reinit a bit.
|
||||
{
|
||||
#if defined(HAVE_FBO) && !defined(HAVE_RGL)
|
||||
gl_deinit_hw_render(gl);
|
||||
#endif
|
||||
|
||||
glDeleteTextures(gl->textures, gl->texture);
|
||||
#if defined(HAVE_PSGL)
|
||||
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
|
||||
glDeleteBuffers(1, &gl->pbo);
|
||||
#endif
|
||||
gl->textures = textures;
|
||||
RARCH_LOG("GL: Using %u textures.\n", gl->textures);
|
||||
gl->tex_index = 0;
|
||||
gl_init_textures(gl, &gl->video_info);
|
||||
gl_init_textures_data(gl);
|
||||
|
||||
#if defined(HAVE_FBO) && !defined(HAVE_RGL)
|
||||
if (gl->hw_render_use)
|
||||
gl_init_hw_render(gl, gl->tex_w, gl->tex_h);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
// Set up render to texture again.
|
||||
gl_init_fbo(gl, gl->tex_w, gl->tex_h);
|
||||
@ -2362,7 +2407,7 @@ static void gl_get_overlay_interface(void *data, const video_overlay_interface_t
|
||||
static uintptr_t gl_get_current_framebuffer(void *data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
return gl->hw_render_fbo[(gl->tex_index + 1) & TEXTURES_MASK];
|
||||
return gl->hw_render_fbo[(gl->tex_index + 1) % gl->textures];
|
||||
}
|
||||
|
||||
static retro_proc_address_t gl_get_proc_address(void *data, const char *sym)
|
||||
|
@ -137,13 +137,7 @@ struct gl_coords
|
||||
typedef struct gl_shader_backend gl_shader_backend_t;
|
||||
|
||||
#define MAX_SHADERS 16
|
||||
|
||||
#if (defined(HAVE_GLSL) || defined(HAVE_CG))
|
||||
#define TEXTURES 8
|
||||
#else
|
||||
#define TEXTURES 1
|
||||
#endif
|
||||
#define TEXTURES_MASK (TEXTURES - 1)
|
||||
#define MAX_TEXTURES 8
|
||||
|
||||
typedef struct gl
|
||||
{
|
||||
@ -151,9 +145,10 @@ typedef struct gl
|
||||
const gl_shader_backend_t *shader;
|
||||
|
||||
bool vsync;
|
||||
GLuint texture[TEXTURES];
|
||||
GLuint texture[MAX_TEXTURES];
|
||||
unsigned tex_index; // For use with PREV.
|
||||
struct gl_tex_info prev_info[TEXTURES];
|
||||
unsigned textures;
|
||||
struct gl_tex_info prev_info[MAX_TEXTURES];
|
||||
GLuint tex_filter;
|
||||
|
||||
void *empty_buf;
|
||||
@ -172,8 +167,8 @@ typedef struct gl
|
||||
int fbo_pass;
|
||||
bool fbo_inited;
|
||||
|
||||
GLuint hw_render_fbo[TEXTURES];
|
||||
GLuint hw_render_depth[TEXTURES];
|
||||
GLuint hw_render_fbo[MAX_TEXTURES];
|
||||
GLuint hw_render_depth[MAX_TEXTURES];
|
||||
bool hw_render_fbo_init;
|
||||
bool hw_render_depth_init;
|
||||
#endif
|
||||
@ -192,8 +187,8 @@ typedef struct gl
|
||||
struct rarch_viewport vp;
|
||||
unsigned vp_out_width;
|
||||
unsigned vp_out_height;
|
||||
unsigned last_width[TEXTURES];
|
||||
unsigned last_height[TEXTURES];
|
||||
unsigned last_width[MAX_TEXTURES];
|
||||
unsigned last_height[MAX_TEXTURES];
|
||||
unsigned tex_w, tex_h;
|
||||
GLfloat tex_coords[8];
|
||||
math_matrix mvp, mvp_no_rot;
|
||||
@ -223,6 +218,7 @@ typedef struct gl
|
||||
GLfloat font_color_dark[16];
|
||||
|
||||
bool egl_images;
|
||||
video_info_t video_info;
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
// Overlay rendering
|
||||
|
@ -102,9 +102,9 @@ struct cg_fbo_params
|
||||
CGparameter coord;
|
||||
};
|
||||
|
||||
#define MAX_TEXTURES 8
|
||||
#define MAX_LUT_TEXTURES 8
|
||||
#define MAX_VARIABLES 64
|
||||
#define PREV_TEXTURES (TEXTURES - 1)
|
||||
#define PREV_TEXTURES (MAX_TEXTURES - 1)
|
||||
|
||||
struct cg_program
|
||||
{
|
||||
@ -142,7 +142,7 @@ static unsigned active_index;
|
||||
static struct gfx_shader *cg_shader;
|
||||
|
||||
static state_tracker_t *state_tracker;
|
||||
static GLuint lut_textures[MAX_TEXTURES];
|
||||
static GLuint lut_textures[MAX_LUT_TEXTURES];
|
||||
|
||||
static CGparameter cg_attribs[PREV_TEXTURES + 1 + 4 + GFX_MAX_SHADERS];
|
||||
static unsigned cg_attrib_index;
|
||||
@ -911,6 +911,20 @@ static void gl_cg_shader_scale(unsigned index, struct gfx_fbo_scale *scale)
|
||||
scale->valid = false;
|
||||
}
|
||||
|
||||
static unsigned gl_cg_get_prev_textures(void)
|
||||
{
|
||||
if (!cg_active)
|
||||
return 0;
|
||||
|
||||
unsigned max_prev = 0;
|
||||
for (unsigned i = 1; i <= cg_shader->passes; i++)
|
||||
for (unsigned j = 0; j < PREV_TEXTURES; j++)
|
||||
if (prg[i].prev[j].tex)
|
||||
max_prev = max(j + 1, max_prev);
|
||||
|
||||
return max_prev;
|
||||
}
|
||||
|
||||
void gl_cg_set_compiler_args(const char **argv)
|
||||
{
|
||||
cg_arguments = argv;
|
||||
@ -931,6 +945,7 @@ const gl_shader_backend_t gl_cg_backend = {
|
||||
gl_cg_shader_scale,
|
||||
gl_cg_set_coords,
|
||||
gl_cg_set_mvp,
|
||||
gl_cg_get_prev_textures,
|
||||
|
||||
RARCH_SHADER_CG,
|
||||
};
|
||||
|
@ -50,6 +50,7 @@ struct gl_shader_backend
|
||||
void (*shader_scale)(unsigned index, struct gfx_fbo_scale *scale);
|
||||
bool (*set_coords)(const struct gl_coords *coords);
|
||||
bool (*set_mvp)(const math_matrix *mat);
|
||||
unsigned (*get_prev_textures)(void);
|
||||
|
||||
enum rarch_shader_type type;
|
||||
};
|
||||
|
@ -64,7 +64,7 @@
|
||||
#define BORDER_FUNC GL_CLAMP_TO_BORDER
|
||||
#endif
|
||||
|
||||
#define PREV_TEXTURES (TEXTURES - 1)
|
||||
#define PREV_TEXTURES (MAX_TEXTURES - 1)
|
||||
|
||||
static struct gfx_shader *glsl_shader;
|
||||
static bool glsl_core;
|
||||
@ -1188,6 +1188,20 @@ static void gl_glsl_shader_scale(unsigned index, struct gfx_fbo_scale *scale)
|
||||
scale->valid = false;
|
||||
}
|
||||
|
||||
static unsigned gl_glsl_get_prev_textures(void)
|
||||
{
|
||||
if (!glsl_enable)
|
||||
return 0;
|
||||
|
||||
unsigned max_prev = 0;
|
||||
for (unsigned i = 1; i <= glsl_shader->passes; i++)
|
||||
for (unsigned j = 0; j < PREV_TEXTURES; j++)
|
||||
if (gl_uniforms[i].prev[j].texture >= 0)
|
||||
max_prev = max(j + 1, max_prev);
|
||||
|
||||
return max_prev;
|
||||
}
|
||||
|
||||
void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*))
|
||||
{
|
||||
glsl_get_proc_address = proc;
|
||||
@ -1210,6 +1224,7 @@ const gl_shader_backend_t gl_glsl_backend = {
|
||||
gl_glsl_shader_scale,
|
||||
gl_glsl_set_coords,
|
||||
gl_glsl_set_mvp,
|
||||
gl_glsl_get_prev_textures,
|
||||
|
||||
RARCH_SHADER_GLSL,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user