Fix incompatibilities with GL core.

This commit is contained in:
Themaister 2013-06-23 11:55:21 +02:00
parent b9fce188ea
commit e28f5d7cc1
5 changed files with 108 additions and 37 deletions

View File

@ -126,18 +126,18 @@ static void adjust_power_of_two(gl_t *gl, struct font_rect *geom)
if ((geom->pot_width > gl->font_tex_w) || (geom->pot_height > gl->font_tex_h))
{
gl->font_tex_buf = (uint16_t*)realloc(gl->font_tex_buf,
geom->pot_width * geom->pot_height * sizeof(uint16_t));
gl->font_tex_buf = (uint32_t*)realloc(gl->font_tex_buf,
geom->pot_width * geom->pot_height * sizeof(uint32_t));
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, geom->pot_width, geom->pot_height,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, geom->pot_width, geom->pot_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
gl->font_tex_w = geom->pot_width;
gl->font_tex_h = geom->pot_height;
}
}
static void copy_glyph(const struct font_output *head, const struct font_rect *geom, uint16_t *buffer, unsigned width, unsigned height)
static void copy_glyph(const struct font_output *head, const struct font_rect *geom, uint32_t *buffer, unsigned width, unsigned height)
{
// head has top-left oriented coords.
int x = head->off_x - geom->x;
@ -166,18 +166,25 @@ static void copy_glyph(const struct font_output *head, const struct font_rect *g
if (y + font_height > (int)height)
font_height = height - y;
uint16_t *dst = buffer + y * width + x;
uint32_t *dst = buffer + y * width + x;
for (int h = 0; h < font_height; h++, dst += width, src += head->pitch)
{
uint8_t *d = (uint8_t*)dst;
for (int w = 0; w < font_width; w++)
dst[w] = 0xff | (src[w] << 8); // Assume little endian for now.
{
*d++ = 0xff;
*d++ = 0xff;
*d++ = 0xff;
*d++ = src[w];
}
}
}
// 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)
{
memset(gl->font_tex_buf, 0, gl->font_tex_w * gl->font_tex_h * sizeof(uint16_t));
memset(gl->font_tex_buf, 0, gl->font_tex_w * gl->font_tex_h * sizeof(uint32_t));
while (head)
{
@ -188,7 +195,7 @@ static void blit_fonts(gl_t *gl, const struct font_output *head, const struct fo
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
glTexSubImage2D(GL_TEXTURE_2D,
0, 0, 0, gl->font_tex_w, gl->font_tex_h,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, gl->font_tex_buf);
GL_RGBA, GL_UNSIGNED_BYTE, gl->font_tex_buf);
}
static void calculate_font_coords(gl_t *gl,

View File

@ -78,6 +78,43 @@ static const GLfloat tex_coords[] = {
1, 1
};
// Workaround broken Apple headers.
typedef const GLubyte* (*gl_get_stringi_proc)(GLenum name, GLuint index);
static inline bool gl_query_extension(gl_t *gl, const char *ext)
{
bool ret = false;
if (gl->core_context)
{
#ifdef GL_NUM_EXTENSIONS
gl_get_stringi_proc proc = (gl_get_stringi_proc)gl->ctx_driver->get_proc_address("glGetStringi");
if (!proc)
return false;
GLint exts = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &exts);
for (GLint i = 0; i < exts; i++)
{
const char *str = (const char*)proc(GL_EXTENSIONS, i);
if (str && strstr(str, ext))
{
ret = true;
break;
}
}
#endif
}
else
{
const char *str = (const char*)glGetString(GL_EXTENSIONS);
ret = str && strstr(str, ext);
}
RARCH_LOG("Querying GL extension: %s => %s\n",
ext, ret ? "exists" : "doesn't exist");
return ret;
}
#ifdef HAVE_OVERLAY
static void gl_render_overlay(void *data);
static void gl_overlay_vertex_geom(void *data,
@ -127,7 +164,7 @@ static PFNGLCLIENTWAITSYNCPROC pglClientWaitSync;
static bool load_sync_proc(gl_t *gl)
{
if (!gl_query_extension("ARB_sync"))
if (!gl_query_extension(gl, "ARB_sync"))
return false;
LOAD_GL_SYM(FenceSync);
@ -145,7 +182,7 @@ static PFNGLDELETEVERTEXARRAYSPROC pglDeleteVertexArrays;
static bool load_vao_proc(gl_t *gl)
{
if (!gl_query_extension("ARB_vertex_array_object"))
if (!gl_query_extension(gl, "ARB_vertex_array_object"))
return false;
LOAD_GL_SYM(GenVertexArrays);
@ -285,7 +322,9 @@ static bool gl_shader_init(void *data)
const char *shader_path = (g_settings.video.shader_enable && *g_settings.video.shader_path) ?
g_settings.video.shader_path : NULL;
enum rarch_shader_type type = gfx_shader_parse_type(shader_path, DEFAULT_SHADER_TYPE);
enum rarch_shader_type type = gfx_shader_parse_type(shader_path,
gl->core_context ? RARCH_SHADER_GLSL : DEFAULT_SHADER_TYPE);
if (type == RARCH_SHADER_NONE)
{
@ -357,8 +396,11 @@ static void gl_set_coords(const struct gl_coords *coords)
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void gl_disable_client_arrays(void)
static void gl_disable_client_arrays(gl_t *gl)
{
if (gl->core_context)
return;
pglClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
pglClientActiveTexture(GL_TEXTURE0);
@ -543,7 +585,7 @@ static void gl_create_fbo_textures(void *data)
{
// GLES and GL are inconsistent in which arguments to pass.
#ifdef HAVE_OPENGLES2
bool has_fp_fbo = gl_query_extension("OES_texture_float_linear");
bool has_fp_fbo = gl_query_extension(gl, "OES_texture_float_linear");
if (!has_fp_fbo)
RARCH_ERR("OES_texture_float_linear extension not found.\n");
@ -552,7 +594,7 @@ static void gl_create_fbo_textures(void *data)
gl->fbo_rect[i].width, gl->fbo_rect[i].height,
0, GL_RGBA, GL_FLOAT, NULL);
#else
bool has_fp_fbo = gl_query_extension("ARB_texture_float");
bool has_fp_fbo = gl_query_extension(gl, "ARB_texture_float");
if (!has_fp_fbo)
RARCH_ERR("ARB_texture_float extension was not found.\n");
@ -709,7 +751,7 @@ bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
bool stencil = g_extern.system.hw_render_callback.stencil;
#ifdef HAVE_OPENGLES2
if (stencil && !gl_query_extension("OES_packed_depth_stencil"))
if (stencil && !gl_query_extension(gl, "OES_packed_depth_stencil"))
return false;
#endif
@ -1188,7 +1230,7 @@ static void gl_init_textures(void *data, const video_info_t *video)
#ifdef HAVE_OPENGLES2
if (gl->hw_render_use && gl->base_size == sizeof(uint32_t))
{
bool support_argb = gl_query_extension("OES_rgb8_rgba8") || gl_query_extension("ARM_argb8");
bool support_argb = gl_query_extension(gl, "OES_rgb8_rgba8") || gl_query_extension(gl, "ARM_argb8");
if (support_argb)
{
internal_fmt = GL_RGBA;
@ -1481,6 +1523,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
if (gl->hw_render_fbo_init)
{
#ifndef HAVE_OPENGLES
if (!gl->core_context)
glEnable(GL_TEXTURE_2D);
#endif
glDisable(GL_DEPTH_TEST);
@ -1545,7 +1588,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
gl->shader->use(0);
glBindTexture(GL_TEXTURE_2D, 0);
#ifndef NO_GL_FF_VERTEX
gl_disable_client_arrays();
gl_disable_client_arrays(gl);
#endif
}
#endif
@ -1613,7 +1656,7 @@ static void gl_free(void *data)
gl_shader_deinit(gl);
#ifndef NO_GL_FF_VERTEX
gl_disable_client_arrays();
gl_disable_client_arrays(gl);
#endif
glDeleteTextures(TEXTURES, gl->texture);
@ -1714,7 +1757,7 @@ static bool resolve_extensions(gl_t *gl)
driver.gfx_use_rgba = false;
#ifdef HAVE_OPENGLES2
if (gl_query_extension("BGRA8888"))
if (gl_query_extension(gl, "BGRA8888"))
RARCH_LOG("[GL]: BGRA8888 extension found for GLES.\n");
else
{
@ -1992,6 +2035,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl_set_texture_fmts(gl, video->rgb32);
#ifndef HAVE_OPENGLES
if (!gl->core_context)
glEnable(GL_TEXTURE_2D);
#endif
@ -2004,7 +2048,6 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->coords.tex_coord = gl->tex_coords;
gl->coords.color = white_color;
gl->coords.lut_tex_coord = tex_coords;
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
// Empty buffer that we use to clear out the texture with on res change.
gl->empty_buf = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h);

View File

@ -81,16 +81,6 @@
gl->ctx_driver->write_egl_image(frame, width, height, pitch, base_size, tex_index,img)
#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();
@ -244,7 +234,7 @@ typedef struct gl
const font_renderer_driver_t *font_driver;
GLuint font_tex;
int font_tex_w, font_tex_h;
uint16_t *font_tex_buf;
uint32_t *font_tex_buf;
char font_last_msg[256];
int font_last_width, font_last_height;
GLfloat font_color[16];
@ -285,10 +275,8 @@ typedef struct gl
unsigned fence_count;
#endif
#ifndef HAVE_OPENGLES
bool core_context;
GLuint vao;
#endif
} gl_t;
// Windows ... <_<

View File

@ -106,6 +106,10 @@ else
LIBS += $(GL_LIB)
endif
ifeq ($(CORE), 1)
CFLAGS += -DCORE
endif
all: $(TARGET)
$(TARGET): $(OBJECTS)

View File

@ -73,6 +73,10 @@ static PFNGLDISABLEVERTEXATTRIBARRAYPROC pglDisableVertexAttribArray;
static PFNGLGENBUFFERSPROC pglGenBuffers;
static PFNGLBUFFERDATAPROC pglBufferData;
static PFNGLBINDBUFFERPROC pglBindBuffer;
#ifdef CORE
static PFNGLGENVERTEXARRAYSPROC pglGenVertexArrays;
static PFNGLBINDVERTEXARRAYPROC pglBindVertexArray;
#endif
struct gl_proc_map
{
@ -99,6 +103,10 @@ static const struct gl_proc_map proc_map[] = {
PROC_BIND(GenBuffers),
PROC_BIND(BufferData),
PROC_BIND(BindBuffer),
#ifdef CORE
PROC_BIND(GenVertexArrays),
PROC_BIND(BindVertexArray),
#endif
};
static void init_gl_proc(void)
@ -116,6 +124,10 @@ static void init_gl_proc(void)
static GLuint prog;
static GLuint vbo;
#ifdef CORE
static GLuint vao;
#endif
static const GLfloat vertex_data[] = {
-0.5, -0.5,
0.5, -0.5,
@ -166,6 +178,9 @@ static void compile_program(void)
static void setup_vao(void)
{
#ifdef CORE
pglGenVertexArrays(1, &vao);
#endif
pglUseProgram(prog);
pglGenBuffers(1, &vbo);
@ -303,6 +318,10 @@ void retro_run(void)
input_poll_cb();
#ifdef CORE
pglBindVertexArray(vao);
#endif
pglBindFramebuffer(GL_FRAMEBUFFER, hw_render.get_current_framebuffer());
glClearColor(0.3, 0.4, 0.5, 1.0);
glViewport(0, 0, width, height);
@ -355,6 +374,9 @@ void retro_run(void)
pglUseProgram(0);
video_cb(RETRO_HW_FRAME_BUFFER_VALID, width, height, 0);
#ifdef CORE
pglBindVertexArray(0);
#endif
}
static void context_reset(void)
@ -379,11 +401,18 @@ bool retro_load_game(const struct retro_game_info *info)
#ifdef GLES
hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES2;
#else
#ifdef CORE
hw_render.context_type = RETRO_HW_CONTEXT_OPENGL_CORE;
hw_render.version_major = 3;
hw_render.version_minor = 1;
#else
hw_render.context_type = RETRO_HW_CONTEXT_OPENGL;
#endif
#endif
hw_render.context_reset = context_reset;
hw_render.depth = true;
hw_render.stencil = true;
if (!environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
return false;