mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 06:18:34 +00:00
Fix incompatibilities with GL core.
This commit is contained in:
parent
b9fce188ea
commit
e28f5d7cc1
@ -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,
|
||||
|
71
gfx/gl.c
71
gfx/gl.c
@ -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,7 +1523,8 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
if (gl->hw_render_fbo_init)
|
||||
{
|
||||
#ifndef HAVE_OPENGLES
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (!gl->core_context)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_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,7 +2035,8 @@ 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
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (!gl->core_context)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@ -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);
|
||||
|
@ -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 ... <_<
|
||||
|
@ -106,6 +106,10 @@ else
|
||||
LIBS += $(GL_LIB)
|
||||
endif
|
||||
|
||||
ifeq ($(CORE), 1)
|
||||
CFLAGS += -DCORE
|
||||
endif
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user