mirror of
https://github.com/libretro/RetroArch.git
synced 2024-12-02 13:28:35 +00:00
Use VBOs in GLSL.
Future proof a bit as future GL versions require use of VBOs. Also avoids spamming client-side data to GL all the time. VAOs are not used, but that is only relevant if we actually create a GL3+ context.
This commit is contained in:
parent
a66fdf8b5f
commit
b4b83cdf41
2
gfx/gl.c
2
gfx/gl.c
@ -758,8 +758,6 @@ void gl_set_projection(void *data, struct gl_ortho *ortho, bool allow_rotate)
|
||||
}
|
||||
else
|
||||
gl->mvp = gl->mvp_no_rot;
|
||||
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
|
||||
}
|
||||
|
||||
void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_full, bool allow_rotate)
|
||||
|
@ -84,6 +84,10 @@
|
||||
#define pglEnableVertexAttribArray glEnableVertexAttribArray
|
||||
#define pglDisableVertexAttribArray glDisableVertexAttribArray
|
||||
#define pglVertexAttribPointer glVertexAttribPointer
|
||||
#define pglGenBuffers glGenBuffers
|
||||
#define pglBufferData glBufferData
|
||||
#define pglDeleteBuffers glDeleteBuffers
|
||||
#define pglBindBuffer glBindBuffer
|
||||
#else
|
||||
static PFNGLCREATEPROGRAMPROC pglCreateProgram;
|
||||
static PFNGLUSEPROGRAMPROC pglUseProgram;
|
||||
@ -110,6 +114,10 @@ static PFNGLGETATTRIBLOCATIONPROC pglGetAttribLocation;
|
||||
static PFNGLENABLEVERTEXATTRIBARRAYPROC pglEnableVertexAttribArray;
|
||||
static PFNGLDISABLEVERTEXATTRIBARRAYPROC pglDisableVertexAttribArray;
|
||||
static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer;
|
||||
static PFNGLGENBUFFERSPROC pglGenBuffers;
|
||||
static PFNGLBUFFERDATAPROC pglBufferData;
|
||||
static PFNGLDELETEBUFFERSPROC pglDeleteBuffers;
|
||||
static PFNGLBINDBUFFERPROC pglBindBuffer;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGLES2
|
||||
@ -133,6 +141,26 @@ static state_tracker_t *gl_state_tracker;
|
||||
static GLint gl_attribs[PREV_TEXTURES + 1 + 4 + GFX_MAX_SHADERS];
|
||||
static unsigned gl_attrib_index;
|
||||
|
||||
// Cache the VBO.
|
||||
struct cache_vbo
|
||||
{
|
||||
GLuint vbo_primary;
|
||||
GLfloat buffer_primary[128];
|
||||
size_t size_primary;
|
||||
|
||||
GLuint vbo_secondary;
|
||||
GLfloat buffer_secondary[128];
|
||||
size_t size_secondary;
|
||||
};
|
||||
static struct cache_vbo glsl_vbo[GFX_MAX_SHADERS];
|
||||
|
||||
struct glsl_attrib
|
||||
{
|
||||
GLint loc;
|
||||
GLsizei size;
|
||||
GLsizei offset;
|
||||
};
|
||||
|
||||
static gfx_ctx_proc_t (*glsl_get_proc_address)(const char*);
|
||||
|
||||
struct shader_uniforms_frame
|
||||
@ -489,6 +517,37 @@ static void gl_glsl_reset_attrib(void)
|
||||
gl_attrib_index = 0;
|
||||
}
|
||||
|
||||
static void gl_glsl_set_vbo(GLfloat *buffer, size_t *buffer_elems, const GLfloat *data, size_t elems)
|
||||
{
|
||||
if (elems != *buffer_elems || memcmp(data, buffer, elems * sizeof(GLfloat)))
|
||||
{
|
||||
//RARCH_LOG("[GL]: VBO updated with %u elems.\n", (unsigned)elems);
|
||||
memcpy(buffer, data, elems * sizeof(GLfloat));
|
||||
pglBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat), data, GL_STATIC_DRAW);
|
||||
*buffer_elems = elems;
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_glsl_set_attribs(GLuint vbo, GLfloat *buffer, size_t *buffer_elems,
|
||||
const GLfloat *data, size_t elems, const struct glsl_attrib *attrs, size_t num_attrs)
|
||||
{
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
||||
gl_glsl_set_vbo(buffer, buffer_elems, data, elems);
|
||||
|
||||
for (size_t i = 0; i < num_attrs; i++)
|
||||
{
|
||||
GLint loc = attrs[i].loc;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
|
||||
pglVertexAttribPointer(loc, attrs[i].size, GL_FLOAT, GL_FALSE, 0,
|
||||
(const GLvoid*)(uintptr_t)attrs[i].offset);
|
||||
}
|
||||
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame, const char *base)
|
||||
{
|
||||
char texture[64];
|
||||
@ -614,6 +673,10 @@ static bool gl_glsl_init(const char *path)
|
||||
LOAD_GL_SYM(EnableVertexAttribArray);
|
||||
LOAD_GL_SYM(DisableVertexAttribArray);
|
||||
LOAD_GL_SYM(VertexAttribPointer);
|
||||
LOAD_GL_SYM(GenBuffers);
|
||||
LOAD_GL_SYM(BufferData);
|
||||
LOAD_GL_SYM(DeleteBuffers);
|
||||
LOAD_GL_SYM(BindBuffer);
|
||||
|
||||
RARCH_LOG("Checking GLSL shader support ...\n");
|
||||
bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader
|
||||
@ -623,7 +686,8 @@ static bool gl_glsl_init(const char *path)
|
||||
&& pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog
|
||||
&& pglDeleteProgram && pglGetAttachedShaders
|
||||
&& pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray
|
||||
&& pglVertexAttribPointer;
|
||||
&& pglVertexAttribPointer
|
||||
&& pglGenBuffers && pglBufferData && pglDeleteBuffers && pglBindBuffer;
|
||||
|
||||
if (!shader_support)
|
||||
{
|
||||
@ -756,6 +820,12 @@ static bool gl_glsl_init(const char *path)
|
||||
|
||||
gl_glsl_reset_attrib();
|
||||
|
||||
for (unsigned i = 0; i < GFX_MAX_SHADERS; i++)
|
||||
{
|
||||
pglGenBuffers(1, &glsl_vbo[i].vbo_primary);
|
||||
pglGenBuffers(1, &glsl_vbo[i].vbo_secondary);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -787,6 +857,13 @@ static void gl_glsl_deinit(void)
|
||||
gl_state_tracker = NULL;
|
||||
|
||||
gl_glsl_reset_attrib();
|
||||
|
||||
for (unsigned i = 0; i < GFX_MAX_SHADERS; i++)
|
||||
{
|
||||
pglDeleteBuffers(1, &glsl_vbo[i].vbo_primary);
|
||||
pglDeleteBuffers(1, &glsl_vbo[i].vbo_secondary);
|
||||
}
|
||||
memset(&glsl_vbo, 0, sizeof(glsl_vbo));
|
||||
}
|
||||
|
||||
static void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
@ -807,6 +884,12 @@ static void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
if (!glsl_enable || (gl_program[active_index] == 0))
|
||||
return;
|
||||
|
||||
GLfloat buffer[128];
|
||||
size_t size = 0;
|
||||
struct glsl_attrib attribs[32];
|
||||
size_t attribs_size = 0;
|
||||
struct glsl_attrib *attr = attribs;
|
||||
|
||||
const struct shader_uniforms *uni = &gl_uniforms[active_index];
|
||||
|
||||
float input_size[2] = {(float)width, (float)height};
|
||||
@ -868,10 +951,14 @@ static void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
// Pass texture coordinates.
|
||||
if (uni->orig.tex_coord >= 0)
|
||||
{
|
||||
int loc = uni->orig.tex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, info->coord);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->orig.tex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, info->coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
|
||||
// Bind new texture in the chain.
|
||||
@ -897,10 +984,14 @@ static void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
|
||||
if (uni->pass[i].tex_coord >= 0)
|
||||
{
|
||||
int loc = uni->pass[i].tex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, fbo_info[i].coord);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->pass[i].tex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, fbo_info[i].coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -943,13 +1034,25 @@ static void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
// Pass texture coordinates.
|
||||
if (uni->prev[i].tex_coord >= 0)
|
||||
{
|
||||
int loc = uni->prev[i].tex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, prev_info[i].coord);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->prev[i].tex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, prev_info[i].coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
gl_glsl_set_attribs(glsl_vbo[active_index].vbo_secondary,
|
||||
glsl_vbo[active_index].buffer_secondary,
|
||||
&glsl_vbo[active_index].size_secondary,
|
||||
buffer, size, attribs, attribs_size);
|
||||
}
|
||||
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
|
||||
if (gl_state_tracker)
|
||||
@ -985,37 +1088,69 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
if (!glsl_enable || !glsl_shader->modern)
|
||||
return false;
|
||||
|
||||
GLfloat buffer[128];
|
||||
size_t size = 0;
|
||||
|
||||
struct glsl_attrib attribs[4];
|
||||
size_t attribs_size = 0;
|
||||
struct glsl_attrib *attr = attribs;
|
||||
|
||||
const struct shader_uniforms *uni = &gl_uniforms[active_index];
|
||||
if (uni->tex_coord >= 0)
|
||||
{
|
||||
int loc = uni->tex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, coords->tex_coord);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->tex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->tex_coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
|
||||
if (uni->vertex_coord >= 0)
|
||||
{
|
||||
int loc = uni->vertex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, coords->vertex);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->vertex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->vertex, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
|
||||
if (uni->color >= 0)
|
||||
{
|
||||
int loc = uni->color;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 0, coords->color);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->color;
|
||||
attr->size = 4;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->color, 16 * sizeof(GLfloat));
|
||||
size += 16;
|
||||
}
|
||||
|
||||
if (uni->lut_tex_coord >= 0)
|
||||
{
|
||||
int loc = uni->lut_tex_coord;
|
||||
pglEnableVertexAttribArray(loc);
|
||||
pglVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, coords->lut_tex_coord);
|
||||
gl_attribs[gl_attrib_index++] = loc;
|
||||
attr->loc = uni->lut_tex_coord;
|
||||
attr->size = 2;
|
||||
attr->offset = size * sizeof(GLfloat);
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->lut_tex_coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
gl_glsl_set_attribs(glsl_vbo[active_index].vbo_primary,
|
||||
glsl_vbo[active_index].buffer_primary,
|
||||
&glsl_vbo[active_index].size_primary,
|
||||
buffer, size,
|
||||
attribs, attribs_size);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user