Add preliminary PBO mode for GL. (GLES).

This commit is contained in:
Themaister 2012-09-10 11:12:57 +02:00
parent cfae6196a6
commit 9871b8d56f
3 changed files with 101 additions and 13 deletions

View File

@ -127,12 +127,17 @@ static void calculate_msg_geometry(const struct font_output *head, struct font_r
rect->height = y_max - y_min;
}
// TODO: Doesn't really use PBO ...
static void adjust_power_of_two(gl_t *gl, struct font_rect *geom)
{
// Some systems really hate NPOT textures.
geom->pot_width = next_pow2(geom->width);
geom->pot_height = next_pow2(geom->height);
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#endif
if ((geom->pot_width > gl->font_tex_w) || (geom->pot_height > gl->font_tex_h))
{
gl->font_tex_empty_buf = realloc(gl->font_tex_empty_buf, geom->pot_width * geom->pot_height);
@ -146,15 +151,25 @@ static void adjust_power_of_two(gl_t *gl, struct font_rect *geom)
gl->font_tex_w = geom->pot_width;
gl->font_tex_h = geom->pot_height;
}
#ifdef HAVE_GL_PBO
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
#endif
}
// Old style "blitting", so we can render all the fonts in one go.
// TODO: Is it possible that fonts could overlap if we blit without alpha blending?
static void blit_fonts(gl_t *gl, const struct font_output *head, const struct font_rect *geom)
{
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#endif
// Clear out earlier fonts.
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->font_tex_w);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->font_tex_w, gl->font_tex_h,
GL_LUMINANCE, GL_UNSIGNED_BYTE, gl->font_tex_empty_buf);
@ -174,6 +189,11 @@ static void blit_fonts(gl_t *gl, const struct font_output *head, const struct fo
head = head->next;
}
#ifdef HAVE_GL_PBO
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
#endif
}
static void calculate_font_coords(gl_t *gl,

View File

@ -348,6 +348,10 @@ static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height,
static void gl_create_fbo_textures(gl_t *gl)
{
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#endif
glGenTextures(gl->fbo_pass, gl->fbo_texture);
GLuint base_filt = g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST;
@ -379,6 +383,10 @@ static void gl_create_fbo_textures(gl_t *gl)
}
glBindTexture(GL_TEXTURE_2D, 0);
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
#endif
}
static bool gl_create_fbo_targets(gl_t *gl)
@ -658,11 +666,20 @@ static void gl_check_fbo_dimensions(gl_t *gl)
pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]);
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]);
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#endif
glTexImage2D(GL_TEXTURE_2D,
0, RARCH_GL_INTERNAL_FORMAT, gl->fbo_rect[i].width, gl->fbo_rect[i].height,
0, RARCH_GL_TEXTURE_TYPE,
RARCH_GL_FORMAT32, NULL);
#ifdef HAVE_GL_PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
#endif
pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0);
GLenum status = pglCheckFramebufferStatus(GL_FRAMEBUFFER);
@ -789,9 +806,16 @@ static void gl_update_input_size(gl_t *gl, unsigned width, unsigned height, unsi
gl->tex_w * gl->tex_h * gl->tex_index * gl->base_size,
gl->tex_w * gl->tex_h * gl->base_size,
gl->empty_buf);
#elif defined(HAVE_GL_PBO)
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(gl->tex_w));
glBufferSubData(GL_PIXEL_UNPACK_BUFFER,
0, gl->tex_w * gl->tex_h * gl->base_size, gl->empty_buf);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type,
gl->texture_fmt, NULL);
#else
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch));
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type,
gl->texture_fmt, gl->empty_buf);
@ -862,22 +886,34 @@ static void gl_init_textures(gl_t *gl)
}
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
}
#else
#elif defined(HAVE_GL_PBO)
static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned width, unsigned height, unsigned pitch)
{
#ifndef HAVE_OPENGLES
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / gl->base_size);
const uint8_t *frame_copy = frame;
size_t frame_copy_size = width * gl->base_size;
uint8_t *data = (uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
if (!data)
return;
for (unsigned h = 0; h < height; h++, data += frame_copy_size, frame_copy += pitch)
memcpy(data, frame_copy, frame_copy_size);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, width, height, gl->texture_type,
gl->texture_fmt, frame);
#else
// Use PBO to get same effect as GL_UNPACK_ROW_LENGTH.
#endif
gl->texture_fmt, NULL);
}
static void gl_init_textures(gl_t *gl)
{
void *buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
if (buf)
{
memset(buf, 0, gl->tex_w * gl->tex_h * gl->base_size);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glGenTextures(TEXTURES, gl->texture);
for (unsigned i = 0; i < TEXTURES; i++)
{
@ -894,10 +930,34 @@ static void gl_init_textures(gl_t *gl)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter);
#ifndef HAVE_OPENGLES
glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
#endif
glTexImage2D(GL_TEXTURE_2D,
0, RARCH_GL_INTERNAL_FORMAT, gl->tex_w, gl->tex_h, 0, gl->texture_type,
gl->texture_fmt, NULL);
}
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
}
#else
static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned width, unsigned height, unsigned pitch)
{
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / gl->base_size);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, width, height, gl->texture_type,
gl->texture_fmt, frame);
}
static void gl_init_textures(gl_t *gl)
{
glGenTextures(TEXTURES, gl->texture);
for (unsigned i = 0; i < TEXTURES; i++)
{
glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter);
glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
glTexImage2D(GL_TEXTURE_2D,
0, RARCH_GL_INTERNAL_FORMAT, gl->tex_w, gl->tex_h, 0, gl->texture_type,
gl->texture_fmt, gl->empty_buf ? gl->empty_buf : NULL);
@ -1045,6 +1105,9 @@ static void gl_free(void *data)
#ifdef HAVE_OPENGL_TEXREF
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
glDeleteBuffers(1, &gl->pbo);
#elif defined(HAVE_GL_PBO)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glDeleteBuffers(1, &gl->pbo);
#endif
#ifdef HAVE_FBO
@ -1191,11 +1254,16 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
gl->tex_h = RARCH_SCALE_BASE * video->input_scale;
#ifdef HAVE_OPENGL_TEXREF
#if defined(HAVE_OPENGL_TEXREF)
glGenBuffers(1, &gl->pbo);
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);
#elif defined(HAVE_GL_PBO)
glGenBuffers(1, &gl->pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER,
gl->tex_w * gl->tex_h * gl->base_size, NULL, GL_STREAM_DRAW);
#endif
// Empty buffer that we use to clear out the texture with on res change.

View File

@ -197,7 +197,7 @@ typedef struct gl
struct gl_coords coords;
#ifdef __CELLOS_LV2__
#if defined(__CELLOS_LV2__) || defined(HAVE_GL_PBO)
GLuint pbo;
#endif
GLenum texture_type; // XBGR1555 or ARGB