Cleanup PBO handling. Makes it optional via ./configure.

This commit is contained in:
Themaister 2012-09-10 23:17:48 +02:00
parent 82d726f6dd
commit 756f8fb3db
7 changed files with 79 additions and 62 deletions

View File

@ -127,17 +127,12 @@ 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);
@ -152,24 +147,16 @@ static void adjust_power_of_two(gl_t *gl, struct font_rect *geom)
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);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
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);
@ -190,10 +177,7 @@ 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

@ -130,16 +130,31 @@ static bool load_fbo_proc(void) { return true; }
#endif
#ifdef _WIN32
PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture = NULL;
PFNGLACTIVETEXTUREPROC pglActiveTexture = NULL;
static inline bool load_gl_proc(void)
PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture;
PFNGLACTIVETEXTUREPROC pglActiveTexture;
static PFNGLBINDBUFFERPROC pglBindBuffer;
static PFNGLBUFFERSUBDATA pglBufferSubData;
static PFNGLBUFFERDATA pglBufferData;
static PFNGLMAPBUFFER pglMapBuffer;
static PFNGLUNMAPBUFFER pglUnmapBuffer;
static inline bool load_gl_proc_win32(void)
{
LOAD_SYM(glClientActiveTexture);
LOAD_SYM(glActiveTexture);
return pglClientActiveTexture && pglActiveTexture;
LOAD_SYM(glBindBuffer);
LOAD_SYM(glBufferSubData);
LOAD_SYM(glBufferData);
LOAD_SYM(glMapBuffer);
LOAD_SYM(glUnmapBuffer);
return pglClientActiveTexture && pglActiveTexture && pglBindBuffer &&
pglBufferSubData && pglBufferData && pglMapBuffer && pglUnmapBuffer;
}
#else
static inline bool load_gl_proc(void) { return true; }
#define pglBindBuffer glBindBuffer
#define pglBufferSubData glBufferSubData
#define pglBufferData glBufferData
#define pglMapBuffer glMapBuffer
#define pglUnmapBuffer glUnmapBuffer
#endif
////////////////// Shaders
@ -348,10 +363,6 @@ 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;
@ -383,10 +394,6 @@ 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)
@ -667,19 +674,11 @@ 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);
@ -804,17 +803,21 @@ 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));
#elif defined(HAVE_PBO)
pglBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER,
0, gl->tex_w * gl->tex_h * gl->base_size, gl->empty_buf);
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(gl->tex_w * gl->base_size));
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type,
gl->texture_fmt, NULL);
pglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#else
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch));
glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * gl->base_size));
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type,
gl->texture_fmt, gl->empty_buf);
@ -879,32 +882,35 @@ static void gl_init_textures(gl_t *gl)
}
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
}
#elif defined(HAVE_GL_PBO)
#elif defined(HAVE_PBO)
static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned width, unsigned height, unsigned pitch)
{
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);
pglBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
uint8_t *data = (uint8_t*)pglMapBuffer(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);
pglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * gl->base_size));
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, width, height, gl->texture_type,
gl->texture_fmt, NULL);
pglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
static void gl_init_textures(gl_t *gl)
{
void *buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
void *buf = pglMapBuffer(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);
pglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glGenTextures(TEXTURES, gl->texture);
@ -932,10 +938,12 @@ static void gl_init_textures(gl_t *gl)
#else
static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned width, unsigned height, unsigned pitch)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * gl->base_size));
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);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
static void gl_init_textures(gl_t *gl)
@ -950,7 +958,7 @@ 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);
glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
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);
@ -1096,7 +1104,7 @@ 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)
#elif defined(HAVE_PBO)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glDeleteBuffers(1, &gl->pbo);
#endif
@ -1170,9 +1178,9 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
#endif
#ifdef _WIN32
// Win32 GL lib doesn't have some functions needed.
// Win32 GL lib doesn't have some elementary functions needed.
// Need to load dynamically :(
if (!load_gl_proc())
if (!load_gl_proc_win32())
{
gfx_ctx_destroy();
free(gl);
@ -1180,6 +1188,17 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
}
#endif
#ifdef HAVE_PBO
RARCH_LOG("[GL]: Using PBOs.\n");
if (!gl_query_extension("GL_ARB_pixel_buffer_object"))
{
RARCH_ERR("[GL]: PBOs are enabled, but extension does not exist ...\n");
gfx_ctx_destroy();
free(gl);
return NULL;
}
#endif
gl->vsync = video->vsync;
gl->fullscreen = video->fullscreen;
@ -1250,7 +1269,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
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)
#elif defined(HAVE_PBO)
glGenBuffers(1, &gl->pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER,
@ -1279,7 +1298,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gfx_ctx_input_driver(input, input_data);
gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
if (!gl_check_error())
{
gfx_ctx_destroy();
@ -1499,3 +1519,4 @@ const video_driver_t video_gl = {
NULL,
#endif
};

View File

@ -24,6 +24,8 @@
#include "../config.h"
#endif
#include <string.h>
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
@ -35,7 +37,6 @@
#include <EGL/egl.h>
#include <GL3/gl3.h>
#include <GL3/gl3ext.h>
#define GL_QUADS 0x0007
#elif defined(HAVE_OPENGLES2)
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@ -48,6 +49,16 @@
#include <GL/glext.h>
#endif
static inline bool gl_query_extension(const char *ext)
{
const char *str = (const char*)glGetString(GL_EXTENSIONS);
bool ret = str && strstr(str, ext);
RARCH_LOG("Querying GL extension: %s => %s\n",
ext, ret ? "exists" : "doesn't exist");
return ret;
}
static inline bool gl_check_error(void)
{
int error = glGetError();
@ -57,18 +68,18 @@ static inline bool gl_check_error(void)
RARCH_ERR("GL: Invalid enum.\n");
break;
case GL_INVALID_VALUE:
RARCH_ERR("GL: Invalid value. (You're not alone.)\n");
RARCH_ERR("GL: Invalid value.\n");
break;
case GL_INVALID_OPERATION:
RARCH_ERR("GL: Invalid operation.\n");
break;
case GL_OUT_OF_MEMORY:
RARCH_ERR("GL: Out of memory. Harhar.\n");
RARCH_ERR("GL: Out of memory.\n");
break;
case GL_NO_ERROR:
return true;
default:
RARCH_ERR("Non specified error :v\n");
RARCH_ERR("Non specified GL error.\n");
}
return false;
@ -197,9 +208,7 @@ typedef struct gl
struct gl_coords coords;
#if defined(__CELLOS_LV2__) || defined(HAVE_GL_PBO)
GLuint pbo;
#endif
GLenum texture_type; // XBGR1555 or ARGB
GLenum texture_fmt;
unsigned base_size; // 2 or 4

View File

@ -484,7 +484,7 @@ static void load_texture_data(GLuint *obj, const struct texture_image *img, bool
0, GL_ARGB_SCE, GL_UNSIGNED_INT_8_8_8_8, img->pixels);
#else
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->width);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D,
0, GL_RGBA, img->width, img->height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, img->pixels);

View File

@ -380,7 +380,7 @@ static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, img.width);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D,
0, GL_RGBA, img.width, img.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, img.pixels);

View File

@ -77,8 +77,10 @@ fi
if [ "$OS" = Darwin ]; then
check_lib FBO "-framework OpenGL" glFramebufferTexture2D
check_lib PBO "-framework OpenGL" glMapBuffer
else
check_lib FBO -lGL glFramebufferTexture2D
check_lib PBO -lGL glMapBuffer
fi
check_pkgconf RSOUND rsound 1.1
@ -143,6 +145,6 @@ check_pkgconf PYTHON python3
add_define_make OS "$OS"
# Creates config.mk and config.h.
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC FIXED_POINT BSV_MOVIE RPI"
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO PBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC FIXED_POINT BSV_MOVIE RPI"
create_config_make config.mk $VARS
create_config_header config.h $VARS

View File

@ -9,6 +9,7 @@ HAVE_OPENGL=yes # Disable OpenGL support
HAVE_CG=auto # Enable Cg shader support
HAVE_XML=auto # Enable bSNES-style XML shader support
HAVE_FBO=auto # Enable render-to-texture (FBO) support
HAVE_PBO=no # Enable pixel buffer object (PBO) support
HAVE_ALSA=auto # Enable ALSA support
HAVE_OSS=auto # Enable OSS support
HAVE_RSOUND=auto # Enable RSound support