diff --git a/gfx/gl.c b/gfx/gl.c index 53a297a1fc..e80b442fa9 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -352,6 +352,13 @@ static bool gl_shader_init(void *data) return true; } + if (gl->core_context && RARCH_SHADER_CG) + { + RARCH_ERR("[GL]: Cg cannot be used with core GL context. Falling back to GLSL.\n"); + backend = &gl_glsl_backend; + shader_path = NULL; + } + gl->shader = backend; bool ret = gl->shader->init(shader_path); if (!ret) @@ -1988,8 +1995,22 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl->full_y = gl->win_height; } + struct retro_hw_render_callback *hw_render = &g_extern.system.hw_render_callback; + gl->vertex_ptr = hw_render->bottom_left_origin ? vertexes : vertexes_flipped; + +#ifdef HAVE_FBO +#ifdef HAVE_OPENGLES2 + gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES2; +#else + gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGL || + g_extern.system.hw_render_callback.context_type == RETRO_HW_CONTEXT_OPENGL_CORE; +#endif +#endif + gl->white_color_ptr = white_color; + #ifdef HAVE_GLSL gl_glsl_set_get_proc_address(gl->ctx_driver->get_proc_address); + gl_glsl_set_context_type(gl->core_context, hw_render->version_major, hw_render->version_minor); #endif if (!gl_shader_init(gl)) @@ -2017,18 +2038,6 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo else gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST; -#ifdef HAVE_FBO - struct retro_hw_render_callback *hw_render = &g_extern.system.hw_render_callback; - gl->vertex_ptr = hw_render->bottom_left_origin ? vertexes : vertexes_flipped; -#ifdef HAVE_OPENGLES2 - gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES2; -#else - gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGL || - g_extern.system.hw_render_callback.context_type == RETRO_HW_CONTEXT_OPENGL_CORE; -#endif -#endif - gl->white_color_ptr = white_color; - gl_set_texture_fmts(gl, video->rgb32); #ifndef HAVE_OPENGLES diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 4b4c8a5a73..3d1e2e757e 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -129,6 +129,9 @@ static PFNGLBINDBUFFERPROC pglBindBuffer; #define PREV_TEXTURES (TEXTURES - 1) static struct gfx_shader *glsl_shader; +static bool glsl_core; +static unsigned glsl_major; +static unsigned glsl_minor; static bool glsl_enable; static GLuint gl_program[GFX_MAX_SHADERS]; @@ -224,6 +227,25 @@ static const char *stock_fragment_modern = " gl_FragColor = vec4(texture2D(Texture, tex_coord).rgb, 1.0);\n" "}"; +static const char *stock_vertex_core = + "in vec2 TexCoord;\n" + "in vec2 VertexCoord;\n" + "in vec4 Color;\n" + "uniform mat4 MVPMatrix;\n" + "out vec2 tex_coord;\n" + "void main() {\n" + " gl_Position = MVPMatrix * vec4(VertexCoord, 0.0, 1.0);\n" + " tex_coord = TexCoord;\n" + "}"; + +static const char *stock_fragment_core = + "uniform sampler2D Texture;\n" + "in vec2 tex_coord;\n" + "out vec4 FragColor;\n" + "void main() {\n" + " FragColor = vec4(texture(Texture, tex_coord).rgb, 1.0);\n" + "}"; + static const char *stock_vertex_legacy = "varying vec4 color;\n" "void main() {\n" @@ -263,6 +285,27 @@ static const char *stock_fragment_modern_blend = " gl_FragColor = color * texture2D(Texture, tex_coord);\n" "}"; +static const char *stock_vertex_core_blend = + "in vec2 TexCoord;\n" + "in vec2 VertexCoord;\n" + "in vec4 Color;\n" + "uniform mat4 MVPMatrix;\n" + "out vec2 tex_coord;\n" + "out vec4 color;\n" + "void main() {\n" + " gl_Position = MVPMatrix * vec4(VertexCoord, 0.0, 1.0);\n" + " tex_coord = TexCoord;\n" + " color = Color;\n" + "}"; + +static const char *stock_fragment_core_blend = + "uniform sampler2D Texture;\n" + "in vec2 tex_coord;\n" + "in vec4 color;\n" + "out vec4 FragColor;\n" + "void main() {\n" + " FragColor = color * texture2D(Texture, tex_coord);\n" + "}"; static GLint get_uniform(GLuint prog, const char *base) { @@ -392,7 +435,24 @@ static void print_linker_log(GLuint obj) static bool compile_shader(GLuint shader, const char *define, const char *program) { - const char *source[] = { define, program }; + char version[32] = {0}; + if (glsl_core) + { + unsigned version_no = 0; + unsigned gl_ver = glsl_major * 100 + glsl_minor * 10; + switch (gl_ver) + { + case 300: version_no = 130; break; + case 310: version_no = 140; break; + case 320: version_no = 150; break; + default: version_no = gl_ver; break; + } + + snprintf(version, sizeof(version), "#version %u\n", version_no); + RARCH_LOG("[GL]: Using GLSL version %u.\n", version_no); + } + + const char *source[] = { version, define, program }; pglShaderSource(shader, ARRAY_SIZE(source), source, NULL); pglCompileShader(shader); @@ -771,8 +831,8 @@ static bool gl_glsl_init(const char *path) { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); glsl_shader->passes = 1; - glsl_shader->pass[0].source.xml.vertex = strdup(stock_vertex_modern); - glsl_shader->pass[0].source.xml.fragment = strdup(stock_fragment_modern); + glsl_shader->pass[0].source.xml.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); + glsl_shader->pass[0].source.xml.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); glsl_shader->modern = true; } @@ -789,6 +849,12 @@ static bool gl_glsl_init(const char *path) RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); goto error; } +#else + if (glsl_core && !glsl_shader->modern) + { + RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n"); + goto error; + } #endif if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0))) @@ -838,8 +904,8 @@ static bool gl_glsl_init(const char *path) if (glsl_shader->modern) { - gl_program[GL_SHADER_STOCK_BLEND] = compile_program(stock_vertex_modern_blend, - stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); + gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend, + glsl_core ? stock_fragment_modern_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); find_uniforms(gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]); } @@ -1196,6 +1262,13 @@ void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*)) glsl_get_proc_address = proc; } +void gl_glsl_set_context_type(bool core_profile, unsigned major, unsigned minor) +{ + glsl_core = core_profile; + glsl_major = major; + glsl_minor = minor; +} + const gl_shader_backend_t gl_glsl_backend = { gl_glsl_init, gl_glsl_deinit, diff --git a/gfx/shader_glsl.h b/gfx/shader_glsl.h index d7be9f19a4..f9c71411dc 100644 --- a/gfx/shader_glsl.h +++ b/gfx/shader_glsl.h @@ -21,6 +21,7 @@ #include "shader_common.h" void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*)); +void gl_glsl_set_context_type(bool core_profile, unsigned major, unsigned minor); extern const gl_shader_backend_t gl_glsl_backend; #endif diff --git a/libretro-test-gl/libretro-test.c b/libretro-test-gl/libretro-test.c index e19972a87e..fa80502762 100644 --- a/libretro-test-gl/libretro-test.c +++ b/libretro-test-gl/libretro-test.c @@ -139,6 +139,28 @@ static const GLfloat vertex_data[] = { 1.0, 0.0, 1.0, 1.0, }; +#ifdef CORE +static const char *vertex_shader[] = { + "#version 420\n" + "uniform mat4 uMVP;", + "in vec2 aVertex;", + "in vec4 aColor;", + "out vec4 color;", + "void main() {", + " gl_Position = uMVP * vec4(aVertex, 0.0, 1.0);", + " color = aColor;", + "}", +}; + +static const char *fragment_shader[] = { + "#version 420\n" + "in vec4 color;", + "out vec4 FragColor;\n" + "void main() {", + " FragColor = color;", + "}", +}; +#else static const char *vertex_shader[] = { "uniform mat4 uMVP;", "attribute vec2 aVertex;", @@ -159,6 +181,7 @@ static const char *fragment_shader[] = { " gl_FragColor = color;", "}", }; +#endif static void compile_program(void) { @@ -344,7 +367,7 @@ void retro_run(void) static unsigned frame_count; frame_count++; - float angle = frame_count / 10.0; + float angle = frame_count / 100.0; float cos_angle = cos(angle); float sin_angle = sin(angle); @@ -404,8 +427,8 @@ bool retro_load_game(const struct retro_game_info *info) #else #ifdef CORE hw_render.context_type = RETRO_HW_CONTEXT_OPENGL_CORE; - hw_render.version_major = 3; - hw_render.version_minor = 1; + hw_render.version_major = 4; + hw_render.version_minor = 2; #else hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; #endif