diff --git a/gfx/fonts/gl_raster_font.c b/gfx/fonts/gl_raster_font.c index c4650b60ed..d6e32dff9b 100644 --- a/gfx/fonts/gl_raster_font.c +++ b/gfx/fonts/gl_raster_font.c @@ -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, diff --git a/gfx/gl.c b/gfx/gl.c index cb2c1ee7e9..ee4904bde7 100644 --- a/gfx/gl.c +++ b/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); diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 1f004d81c3..be07c45e26 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.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 ... <_< diff --git a/libretro-test-gl/Makefile b/libretro-test-gl/Makefile index 2506afd81d..084e6ddd29 100644 --- a/libretro-test-gl/Makefile +++ b/libretro-test-gl/Makefile @@ -106,6 +106,10 @@ else LIBS += $(GL_LIB) endif +ifeq ($(CORE), 1) + CFLAGS += -DCORE +endif + all: $(TARGET) $(TARGET): $(OBJECTS) diff --git a/libretro-test-gl/libretro-test.c b/libretro-test-gl/libretro-test.c index 62d2f80574..92bb507505 100644 --- a/libretro-test-gl/libretro-test.c +++ b/libretro-test-gl/libretro-test.c @@ -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;