1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *
5  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
6  *  of the GNU General Public License as published by the Free Software Found-
7  *  ation, either version 3 of the License, or (at your option) any later version.
8  *
9  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  *  PURPOSE.  See the GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License along with RetroArch.
14  *  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include <compat/strl.h>
21 #include <compat/posix_string.h>
22 #include <file/file_path.h>
23 #include <retro_assert.h>
24 #include <streams/file_stream.h>
25 #include <string/stdstring.h>
26 
27 #ifdef HAVE_CONFIG_H
28 #include "../../config.h"
29 #endif
30 
31 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
32 #include <gfx/gl_capabilities.h>
33 #include "../common/gl_common.h"
34 #endif
35 
36 #include "shader_glsl.h"
37 #ifdef HAVE_REWIND
38 #include "../../state_manager.h"
39 #endif
40 #include "../../core.h"
41 #include "../../verbosity.h"
42 
43 #define PREV_TEXTURES (GFX_MAX_TEXTURES - 1)
44 
45 /* Cache the VBO. */
46 struct cache_vbo
47 {
48    GLuint vbo_primary;
49    GLuint vbo_secondary;
50    size_t size_primary;
51    size_t size_secondary;
52    GLfloat *buffer_primary;
53    GLfloat *buffer_secondary;
54 };
55 
56 struct shader_program_glsl_data
57 {
58    GLuint vprg;
59    GLuint fprg;
60 
61    GLuint id;
62 };
63 
64 struct glsl_attrib
65 {
66    GLint loc;
67    GLsizei size;
68    GLsizei offset;
69 };
70 
71 struct shader_uniforms_frame
72 {
73    int texture;
74    int input_size;
75    int texture_size;
76    int tex_coord;
77 };
78 
79 struct shader_uniforms
80 {
81 #if defined(VITA)
82    int time;
83 #endif
84    int mvp;
85    int tex_coord;
86    int vertex_coord;
87    int color;
88    int lut_tex_coord;
89 
90    int input_size;
91    int output_size;
92    int texture_size;
93 
94    int frame_count;
95    int frame_direction;
96 
97    int lut_texture[GFX_MAX_TEXTURES];
98    unsigned frame_count_mod;
99 
100    struct shader_uniforms_frame orig;
101    struct shader_uniforms_frame feedback;
102    struct shader_uniforms_frame pass[GFX_MAX_SHADERS];
103    struct shader_uniforms_frame prev[PREV_TEXTURES];
104 };
105 
106 static const char *glsl_prefixes[] = {
107    "",
108    "ruby",
109 };
110 
111 #if defined(VITA)
112 #include "../drivers/gl_shaders/modern_opaque.cg.vert.h"
113 #include "../drivers/gl_shaders/modern_opaque.cg.frag.h"
114 #include "../drivers/gl_shaders/modern_alpha_blend.cg.vert.h"
115 #include "../drivers/gl_shaders/modern_alpha_blend.cg.frag.h"
116 
117 #ifdef HAVE_SHADERPIPELINE
118 #include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.cg.vert.h"
119 #include "../drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.frag.h"
120 #include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon.cg.vert.h"
121 #include "../drivers/gl_shaders/pipeline_xmb_ribbon.cg.frag.h"
122 #endif
123 
124 #else
125 #include "../drivers/gl_shaders/modern_opaque.glsl.vert.h"
126 #include "../drivers/gl_shaders/modern_opaque.glsl.frag.h"
127 #include "../drivers/gl_shaders/core_opaque.glsl.vert.h"
128 #include "../drivers/gl_shaders/core_opaque.glsl.frag.h"
129 #include "../drivers/gl_shaders/legacy_opaque.glsl.vert.h"
130 #include "../drivers/gl_shaders/legacy_opaque.glsl.frag.h"
131 #include "../drivers/gl_shaders/modern_alpha_blend.glsl.vert.h"
132 #include "../drivers/gl_shaders/modern_alpha_blend.glsl.frag.h"
133 #include "../drivers/gl_shaders/core_alpha_blend.glsl.vert.h"
134 #include "../drivers/gl_shaders/core_alpha_blend.glsl.frag.h"
135 
136 #ifdef HAVE_SHADERPIPELINE
137 #include "../drivers/gl_shaders/core_pipeline_snow.glsl.frag.h"
138 #include "../drivers/gl_shaders/core_pipeline_snow_simple.glsl.frag.h"
139 #include "../drivers/gl_shaders/core_pipeline_xmb_ribbon.glsl.frag.h"
140 #include "../drivers/gl_shaders/core_pipeline_xmb_ribbon_simple.glsl.frag.h"
141 #include "../drivers/gl_shaders/core_pipeline_bokeh.glsl.frag.h"
142 #include "../drivers/gl_shaders/core_pipeline_snowflake.glsl.frag.h"
143 #include "../drivers/gl_shaders/legacy_pipeline_xmb_ribbon_simple.glsl.vert.h"
144 #include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon_simple.glsl.vert.h"
145 #include "../drivers/gl_shaders/pipeline_xmb_ribbon_simple.glsl.frag.h"
146 #include "../drivers/gl_shaders/pipeline_snow.glsl.frag.h"
147 #include "../drivers/gl_shaders/pipeline_snow.glsl.vert.h"
148 #include "../drivers/gl_shaders/pipeline_snow_core.glsl.vert.h"
149 #include "../drivers/gl_shaders/pipeline_snow_simple.glsl.frag.h"
150 #include "../drivers/gl_shaders/legacy_pipeline_snow.glsl.vert.h"
151 #include "../drivers/gl_shaders/legacy_pipeline_xmb_ribbon.glsl.vert.h"
152 #include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h"
153 #include "../drivers/gl_shaders/pipeline_xmb_ribbon.glsl.frag.h"
154 #include "../drivers/gl_shaders/pipeline_bokeh.glsl.frag.h"
155 #include "../drivers/gl_shaders/pipeline_snowflake.glsl.frag.h"
156 #endif
157 #endif
158 
159 typedef struct glsl_shader_data
160 {
161    char alias_define[1024];
162    GLint attribs_elems[32 * PREV_TEXTURES + 2 + 4 + GFX_MAX_SHADERS];
163    unsigned attribs_index;
164    unsigned active_idx;
165    unsigned current_idx;
166    GLuint lut_textures[GFX_MAX_TEXTURES];
167    float  current_mat_data[GFX_MAX_SHADERS];
168    float* current_mat_data_pointer[GFX_MAX_SHADERS];
169    struct shader_uniforms uniforms[GFX_MAX_SHADERS];
170    struct cache_vbo vbo[GFX_MAX_SHADERS];
171    struct shader_program_glsl_data prg[GFX_MAX_SHADERS];
172    struct video_shader *shader;
173 } glsl_shader_data_t;
174 
175 /* TODO/FIXME - static globals */
176 static bool glsl_core;
177 static unsigned glsl_major;
178 static unsigned glsl_minor;
179 
gl_glsl_get_uniform(glsl_shader_data_t * glsl,GLuint prog,const char * base)180 static GLint gl_glsl_get_uniform(glsl_shader_data_t *glsl,
181       GLuint prog, const char *base)
182 {
183    unsigned i;
184    GLint loc;
185    char buf[80];
186 
187    buf[0] = '\0';
188 
189    strlcpy(buf, glsl->shader->prefix, sizeof(buf));
190    strlcat(buf, base, sizeof(buf));
191    loc = glGetUniformLocation(prog, buf);
192    if (loc >= 0)
193       return loc;
194 
195    for (i = 0; i < ARRAY_SIZE(glsl_prefixes); i++)
196    {
197       buf[0] = '\0';
198       strlcpy(buf, glsl_prefixes[i], sizeof(buf));
199       strlcat(buf, base, sizeof(buf));
200       loc = glGetUniformLocation(prog, buf);
201       if (loc >= 0)
202          return loc;
203    }
204 
205    return -1;
206 }
207 
gl_glsl_get_attrib(glsl_shader_data_t * glsl,GLuint prog,const char * base)208 static GLint gl_glsl_get_attrib(glsl_shader_data_t *glsl,
209       GLuint prog, const char *base)
210 {
211    unsigned i;
212    GLint loc;
213    char buf[80];
214 
215    buf[0] = '\0';
216 
217    strlcpy(buf, glsl->shader->prefix, sizeof(buf));
218    strlcat(buf, base, sizeof(buf));
219    loc = glGetUniformLocation(prog, buf);
220    if (loc >= 0)
221       return loc;
222 
223    for (i = 0; i < ARRAY_SIZE(glsl_prefixes); i++)
224    {
225       strlcpy(buf, glsl_prefixes[i], sizeof(buf));
226       strlcat(buf, base, sizeof(buf));
227       loc = glGetAttribLocation(prog, buf);
228       if (loc >= 0)
229          return loc;
230    }
231 
232    return -1;
233 }
234 
gl_glsl_print_shader_log(GLuint obj)235 static void gl_glsl_print_shader_log(GLuint obj)
236 {
237    char *info_log = NULL;
238    GLint max_len, info_len = 0;
239 
240    glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &max_len);
241 
242    if (max_len == 0)
243       return;
244 
245    info_log = (char*)malloc(max_len);
246    if (!info_log)
247       return;
248 
249    glGetShaderInfoLog(obj, max_len, &info_len, info_log);
250 
251    if (info_len > 0)
252       RARCH_LOG("Shader log: %s\n", info_log);
253 
254    free(info_log);
255 }
256 
gl_glsl_print_linker_log(GLuint obj)257 static void gl_glsl_print_linker_log(GLuint obj)
258 {
259    char *info_log = NULL;
260    GLint max_len, info_len = 0;
261 
262    glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &max_len);
263 
264    if (max_len == 0)
265       return;
266 
267    info_log = (char*)malloc(max_len);
268    if (!info_log)
269       return;
270 
271    glGetProgramInfoLog(obj, max_len, &info_len, info_log);
272 
273    if (info_len > 0)
274       RARCH_LOG("Linker log: %s\n", info_log);
275 
276    free(info_log);
277 }
278 
gl_glsl_compile_shader(glsl_shader_data_t * glsl,GLuint shader,const char * define,const char * program)279 static bool gl_glsl_compile_shader(glsl_shader_data_t *glsl,
280       GLuint shader,
281       const char *define, const char *program)
282 {
283    GLint status;
284    const char *source[4];
285    char version[32];
286    const char *existing_version = strstr(program, "#version");
287 
288    version[0]                   = '\0';
289 
290    if (existing_version)
291    {
292       const char* version_extra = "";
293       unsigned version_no = (unsigned)strtoul(existing_version + 8, (char**)&program, 10);
294 #ifdef HAVE_OPENGLES
295       if (version_no < 130)
296          version_no = 100;
297       else
298       {
299          version_extra = " es";
300          version_no = 300;
301       }
302 #endif
303       snprintf(version, sizeof(version), "#version %u%s\n", version_no, version_extra);
304       RARCH_LOG("[GLSL]: Using GLSL version %u%s.\n", version_no, version_extra);
305    }
306    else if (glsl_core)
307    {
308       unsigned version_no = 0;
309       unsigned gl_ver = glsl_major * 100 + glsl_minor * 10;
310 
311       switch (gl_ver)
312       {
313          case 300:
314             version_no = 130;
315             break;
316          case 310:
317             version_no = 140;
318             break;
319          case 320:
320             version_no = 150;
321             break;
322          default:
323             version_no = gl_ver;
324             break;
325       }
326 
327       snprintf(version, sizeof(version), "#version %u\n", version_no);
328       RARCH_LOG("[GLSL]: Using GLSL version %u.\n", version_no);
329    }
330 
331    source[0] = version;
332    source[1] = define;
333    source[2] = glsl->alias_define;
334    source[3] = program;
335 
336    glShaderSource(shader, ARRAY_SIZE(source), source, NULL);
337    glCompileShader(shader);
338 
339    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
340    gl_glsl_print_shader_log(shader);
341 
342    return status == GL_TRUE;
343 }
344 
gl_glsl_link_program(GLuint prog)345 static bool gl_glsl_link_program(GLuint prog)
346 {
347    GLint status;
348 
349    glLinkProgram(prog);
350 
351    glGetProgramiv(prog, GL_LINK_STATUS, &status);
352    gl_glsl_print_linker_log(prog);
353 
354    if (status != GL_TRUE)
355       return false;
356 
357    glUseProgram(prog);
358    return true;
359 }
360 
gl_glsl_compile_program(void * data,unsigned idx,void * program_data,struct shader_program_info * program_info)361 static bool gl_glsl_compile_program(
362       void *data,
363       unsigned idx,
364       void *program_data,
365       struct shader_program_info *program_info)
366 {
367    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
368    struct shader_program_glsl_data *program = (struct shader_program_glsl_data*)program_data;
369    GLuint prog = glCreateProgram();
370 
371    if (!program)
372       program = &glsl->prg[idx];
373 
374    if (!prog)
375       goto error;
376 
377    if (program_info->vertex)
378    {
379       RARCH_LOG("[GLSL]: Found GLSL vertex shader.\n");
380       program->vprg = glCreateShader(GL_VERTEX_SHADER);
381 
382       if (!gl_glsl_compile_shader(
383                glsl,
384                program->vprg,
385                "#define VERTEX\n#define PARAMETER_UNIFORM\n", program_info->vertex))
386       {
387          RARCH_ERR("Failed to compile vertex shader #%u\n", idx);
388          goto error;
389       }
390 
391       glAttachShader(prog, program->vprg);
392    }
393 
394    if (program_info->fragment)
395    {
396       RARCH_LOG("[GLSL]: Found GLSL fragment shader.\n");
397       program->fprg = glCreateShader(GL_FRAGMENT_SHADER);
398       if (!gl_glsl_compile_shader(glsl, program->fprg,
399                "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", program_info->fragment))
400       {
401          RARCH_ERR("Failed to compile fragment shader #%u\n", idx);
402          goto error;
403       }
404 
405       glAttachShader(prog, program->fprg);
406    }
407 
408    if (program_info->vertex || program_info->fragment)
409    {
410       RARCH_LOG("[GLSL]: Linking GLSL program.\n");
411       if (!gl_glsl_link_program(prog))
412          goto error;
413 
414       /* Clean up dead memory. We're not going to relink the program.
415        * Detaching first seems to kill some mobile drivers
416        * (according to the intertubes anyways). */
417       if (program->vprg)
418          glDeleteShader(program->vprg);
419       if (program->fprg)
420          glDeleteShader(program->fprg);
421       program->vprg = 0;
422       program->fprg = 0;
423 
424       glUseProgram(prog);
425 #if defined(VITA)
426       glUniform1i(gl_glsl_get_uniform(glsl, prog, "vTexture"), 0);
427 #else
428       glUniform1i(gl_glsl_get_uniform(glsl, prog, "Texture"), 0);
429 #endif
430       glUseProgram(0);
431    }
432 
433    program->id = prog;
434 
435    return true;
436 
437 error:
438    RARCH_ERR("Failed to link program #%u.\n", idx);
439    program->id = 0;
440    return false;
441 }
442 
gl_glsl_strip_parameter_pragmas(char * source,const char * str)443 static void gl_glsl_strip_parameter_pragmas(char *source, const char *str)
444 {
445    /* #pragma parameter lines tend to have " characters in them,
446     * which is not legal GLSL. */
447    char *s = strstr(source, str);
448 
449    while (s)
450    {
451       /* #pragmas have to be on a single line,
452        * so we can just replace the entire line with spaces. */
453       while (*s != '\0' && *s != '\n')
454          *s++ = ' ';
455       s = strstr(s, str);
456    }
457 }
458 
gl_glsl_load_source_path(struct video_shader_pass * pass,const char * path)459 static bool gl_glsl_load_source_path(struct video_shader_pass *pass,
460       const char *path)
461 {
462    int64_t len    = 0;
463    int64_t nitems = pass ? filestream_read_file(path,
464          (void**)&pass->source.string.vertex, &len) : 0;
465 
466    if (nitems <= 0 || len <= 0)
467       return false;
468 
469    gl_glsl_strip_parameter_pragmas(pass->source.string.vertex, "#pragma parameter");
470    pass->source.string.fragment = strdup(pass->source.string.vertex);
471    return pass->source.string.fragment && pass->source.string.vertex;
472 }
473 
gl_glsl_compile_programs(glsl_shader_data_t * glsl,struct shader_program_glsl_data * program)474 static bool gl_glsl_compile_programs(
475       glsl_shader_data_t *glsl, struct shader_program_glsl_data *program)
476 {
477    unsigned i;
478 
479    for (i = 0; i < glsl->shader->passes; i++)
480    {
481       struct shader_program_info shader_prog_info;
482       const char *vertex           = NULL;
483       const char *fragment         = NULL;
484       struct video_shader_pass *pass = (struct video_shader_pass*)
485          &glsl->shader->pass[i];
486 
487       if (!pass)
488          continue;
489 
490       /* If we load from GLSLP (preset),
491        * load the file here.
492        */
493       if (     !string_is_empty(pass->source.path)
494             && !gl_glsl_load_source_path(pass, pass->source.path))
495       {
496          RARCH_ERR("Failed to load GLSL shader: %s.\n",
497                pass->source.path);
498          return false;
499       }
500 
501       vertex                    = pass->source.string.vertex;
502       fragment                  = pass->source.string.fragment;
503 
504       shader_prog_info.vertex   = vertex;
505       shader_prog_info.fragment = fragment;
506       shader_prog_info.is_file  = false;
507 
508       if (!gl_glsl_compile_program(glsl, i,
509             &program[i],
510             &shader_prog_info))
511       {
512          RARCH_ERR("Failed to create GL program #%u.\n", i);
513          return false;
514       }
515    }
516 
517    return true;
518 }
519 
gl_glsl_reset_attrib(glsl_shader_data_t * glsl)520 static void gl_glsl_reset_attrib(glsl_shader_data_t *glsl)
521 {
522    unsigned i;
523 
524    /* Add sanity check that we did not overflow. */
525    retro_assert(glsl->attribs_index <= ARRAY_SIZE(glsl->attribs_elems));
526 
527    for (i = 0; i < glsl->attribs_index; i++)
528       glDisableVertexAttribArray(glsl->attribs_elems[i]);
529    glsl->attribs_index = 0;
530 }
531 
gl_glsl_set_vbo(GLfloat ** buffer,size_t * buffer_elems,const GLfloat * data,size_t elems)532 static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems,
533       const GLfloat *data, size_t elems)
534 {
535    if (elems > *buffer_elems)
536    {
537       GLfloat *new_buffer = (GLfloat*)
538          realloc(*buffer, elems * sizeof(GLfloat));
539       retro_assert(new_buffer);
540       *buffer = new_buffer;
541    }
542 
543    memcpy(*buffer, data, elems * sizeof(GLfloat));
544    glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat),
545          data, GL_STATIC_DRAW);
546    *buffer_elems = elems;
547 }
548 
gl_glsl_set_attribs(glsl_shader_data_t * glsl,GLuint vbo,GLfloat ** buffer,size_t * buffer_elems,const GLfloat * data,size_t elems,const struct glsl_attrib * attrs,size_t num_attrs)549 static INLINE void gl_glsl_set_attribs(glsl_shader_data_t *glsl,
550       GLuint vbo,
551       GLfloat **buffer, size_t *buffer_elems,
552       const GLfloat *data, size_t elems,
553       const struct glsl_attrib *attrs, size_t num_attrs)
554 {
555    size_t i;
556 
557    glBindBuffer(GL_ARRAY_BUFFER, vbo);
558 
559    if (elems != *buffer_elems ||
560          memcmp(data, *buffer, elems * sizeof(GLfloat)))
561       gl_glsl_set_vbo(buffer, buffer_elems, data, elems);
562 
563    for (i = 0; i < num_attrs; i++)
564    {
565       if (glsl->attribs_index < ARRAY_SIZE(glsl->attribs_elems))
566       {
567          GLint loc = attrs[i].loc;
568 
569          glEnableVertexAttribArray(loc);
570          glVertexAttribPointer(loc, attrs[i].size, GL_FLOAT, GL_FALSE, 0,
571                (const GLvoid*)(uintptr_t)attrs[i].offset);
572          glsl->attribs_elems[glsl->attribs_index++] = loc;
573       }
574       else
575          RARCH_WARN("Attrib array buffer was overflown!\n");
576    }
577 
578    glBindBuffer(GL_ARRAY_BUFFER, 0);
579 }
580 
gl_glsl_clear_uniforms_frame(struct shader_uniforms_frame * frame)581 static void gl_glsl_clear_uniforms_frame(struct shader_uniforms_frame *frame)
582 {
583    frame->texture      = -1;
584    frame->texture_size = -1;
585    frame->input_size   = -1;
586    frame->tex_coord    = -1;
587 }
588 
gl_glsl_find_uniforms_frame(glsl_shader_data_t * glsl,GLuint prog,struct shader_uniforms_frame * frame,const char * base)589 static void gl_glsl_find_uniforms_frame(glsl_shader_data_t *glsl,
590       GLuint prog,
591       struct shader_uniforms_frame *frame, const char *base)
592 {
593    char texture[64];
594    char texture_size[64];
595    char input_size[64];
596    char tex_coord[64];
597 
598    texture[0] = texture_size[0] = input_size[0] = tex_coord[0] = '\0';
599 
600    strlcpy(texture,      base,          sizeof(texture));
601    strlcat(texture,      "Texture",     sizeof(texture));
602    strlcpy(texture_size, base,          sizeof(texture_size));
603    strlcat(texture_size, "TextureSize", sizeof(texture_size));
604    strlcpy(input_size,   base,          sizeof(input_size));
605    strlcat(input_size,   "InputSize",   sizeof(input_size));
606    strlcpy(tex_coord,    base,          sizeof(tex_coord));
607    strlcat(tex_coord,    "TexCoord",    sizeof(tex_coord));
608 
609    if (frame->texture < 0)
610       frame->texture = gl_glsl_get_uniform(glsl, prog, texture);
611    if (frame->texture_size < 0)
612       frame->texture_size = gl_glsl_get_uniform(glsl, prog, texture_size);
613    if (frame->input_size < 0)
614       frame->input_size = gl_glsl_get_uniform(glsl, prog, input_size);
615    if (frame->tex_coord < 0)
616       frame->tex_coord = gl_glsl_get_attrib(glsl, prog, tex_coord);
617 }
618 
gl_glsl_find_uniforms(glsl_shader_data_t * glsl,unsigned pass,GLuint prog,struct shader_uniforms * uni)619 static void gl_glsl_find_uniforms(glsl_shader_data_t *glsl,
620       unsigned pass, GLuint prog,
621       struct shader_uniforms *uni)
622 {
623    unsigned i;
624    char frame_base[64];
625 
626    frame_base[0] = '\0';
627 
628    glUseProgram(prog);
629 
630 #if defined(VITA)
631    uni->time            = gl_glsl_get_uniform(glsl, prog, "Time");
632 #endif
633    uni->mvp             = gl_glsl_get_uniform(glsl, prog, "MVPMatrix");
634    uni->tex_coord       = gl_glsl_get_attrib(glsl, prog, "TexCoord");
635    uni->vertex_coord    = gl_glsl_get_attrib(glsl, prog, "VertexCoord");
636    uni->color           = gl_glsl_get_attrib(glsl, prog, "Color");
637    uni->lut_tex_coord   = gl_glsl_get_attrib(glsl, prog, "LUTTexCoord");
638 
639    uni->input_size      = gl_glsl_get_uniform(glsl, prog, "InputSize");
640    uni->output_size     = gl_glsl_get_uniform(glsl, prog, "OutputSize");
641    uni->texture_size    = gl_glsl_get_uniform(glsl, prog, "TextureSize");
642 
643    uni->frame_count     = gl_glsl_get_uniform(glsl, prog, "FrameCount");
644    uni->frame_direction = gl_glsl_get_uniform(glsl, prog, "FrameDirection");
645 
646    for (i = 0; i < glsl->shader->luts; i++)
647       uni->lut_texture[i] = glGetUniformLocation(prog, glsl->shader->lut[i].id);
648 
649    gl_glsl_clear_uniforms_frame(&uni->orig);
650    gl_glsl_find_uniforms_frame(glsl, prog, &uni->orig, "Orig");
651    gl_glsl_clear_uniforms_frame(&uni->feedback);
652    gl_glsl_find_uniforms_frame(glsl, prog, &uni->feedback, "Feedback");
653 
654    if (pass > 1)
655    {
656       snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass);
657       gl_glsl_find_uniforms_frame(glsl, prog, &uni->orig, frame_base);
658    }
659 
660    for (i = 0; i + 1 < pass; i++)
661    {
662       snprintf(frame_base, sizeof(frame_base), "Pass%u", i + 1);
663       gl_glsl_clear_uniforms_frame(&uni->pass[i]);
664       gl_glsl_find_uniforms_frame(glsl, prog, &uni->pass[i], frame_base);
665       snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass - (i + 1));
666       gl_glsl_find_uniforms_frame(glsl, prog, &uni->pass[i], frame_base);
667 
668       if (*glsl->shader->pass[i].alias)
669          gl_glsl_find_uniforms_frame(glsl, prog, &uni->pass[i], glsl->shader->pass[i].alias);
670    }
671 
672    gl_glsl_clear_uniforms_frame(&uni->prev[0]);
673    gl_glsl_find_uniforms_frame(glsl, prog, &uni->prev[0], "Prev");
674    for (i = 1; i < PREV_TEXTURES; i++)
675    {
676       snprintf(frame_base, sizeof(frame_base), "Prev%u", i);
677       gl_glsl_clear_uniforms_frame(&uni->prev[i]);
678       gl_glsl_find_uniforms_frame(glsl, prog, &uni->prev[i], frame_base);
679    }
680 
681    glUseProgram(0);
682 }
683 
gl_glsl_deinit_shader(glsl_shader_data_t * glsl)684 static void gl_glsl_deinit_shader(glsl_shader_data_t *glsl)
685 {
686    unsigned i;
687 
688    if (!glsl || !glsl->shader)
689       return;
690 
691    for (i = 0; i < glsl->shader->passes; i++)
692    {
693       free(glsl->shader->pass[i].source.string.vertex);
694       free(glsl->shader->pass[i].source.string.fragment);
695    }
696 
697    free(glsl->shader);
698    glsl->shader = NULL;
699 }
700 
gl_glsl_destroy_resources(glsl_shader_data_t * glsl)701 static void gl_glsl_destroy_resources(glsl_shader_data_t *glsl)
702 {
703    unsigned i;
704 
705    if (!glsl)
706       return;
707 
708    glsl->current_idx = 0;
709 
710    glUseProgram(0);
711 
712    for (i = 0; i < GFX_MAX_SHADERS; i++)
713    {
714       if (glsl->prg[i].id == 0 || (i && glsl->prg[i].id == glsl->prg[0].id))
715          continue;
716       if (!glIsProgram(glsl->prg[i].id))
717          continue;
718 
719       glDeleteProgram(glsl->prg[i].id);
720       glsl->prg[i].id = 0;
721    }
722 
723    if (glsl->shader && glsl->shader->luts)
724       glDeleteTextures(glsl->shader->luts, glsl->lut_textures);
725 
726    memset(glsl->prg, 0, sizeof(glsl->prg));
727    memset(glsl->uniforms, 0, sizeof(glsl->uniforms));
728    glsl->active_idx = 0;
729 
730    gl_glsl_deinit_shader(glsl);
731 
732    gl_glsl_reset_attrib(glsl);
733 
734    for (i = 0; i < GFX_MAX_SHADERS; i++)
735    {
736       if (glsl->vbo[i].vbo_primary)
737          glDeleteBuffers(1, &glsl->vbo[i].vbo_primary);
738       if (glsl->vbo[i].vbo_secondary)
739          glDeleteBuffers(1, &glsl->vbo[i].vbo_secondary);
740 
741       free(glsl->vbo[i].buffer_primary);
742       free(glsl->vbo[i].buffer_secondary);
743    }
744    memset(&glsl->vbo, 0, sizeof(glsl->vbo));
745 }
746 
gl_glsl_deinit(void * data)747 static void gl_glsl_deinit(void *data)
748 {
749    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
750 
751    if (!glsl)
752       return;
753 
754    gl_glsl_destroy_resources(glsl);
755 
756    free(glsl);
757 }
758 
gl_glsl_init_menu_shaders(void * data)759 static void gl_glsl_init_menu_shaders(void *data)
760 {
761 #ifdef HAVE_SHADERPIPELINE
762    struct shader_program_info shader_prog_info;
763    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
764 
765    if (!glsl)
766       return;
767 
768 #ifdef HAVE_OPENGLES
769 #if defined(VITA)
770    shader_prog_info.vertex = stock_vertex_xmb_ribbon_modern;
771    shader_prog_info.fragment = stock_fragment_xmb;
772 #else
773    if (gl_query_extension("GL_OES_standard_derivatives"))
774    {
775       shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy;
776       shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb;
777    }
778    else
779    {
780       shader_prog_info.vertex = stock_vertex_xmb_ribbon_simple_legacy;
781       shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple;
782    }
783 #endif
784 #else
785    shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy;
786    shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb;
787 #endif
788    shader_prog_info.is_file = false;
789 
790    RARCH_LOG("[GLSL]: Compiling ribbon shader..\n");
791    gl_glsl_compile_program(
792          glsl,
793          VIDEO_SHADER_MENU,
794          &glsl->prg[VIDEO_SHADER_MENU],
795          &shader_prog_info);
796    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU].id,
797          &glsl->uniforms[VIDEO_SHADER_MENU]);
798 
799 #if defined(VITA)
800    shader_prog_info.vertex = stock_vertex_xmb_simple_modern;
801    shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple;
802 #else
803    shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_simple_modern : stock_vertex_xmb_ribbon_simple_legacy;
804    shader_prog_info.fragment = glsl_core ? stock_fragment_xmb_ribbon_simple_core : stock_fragment_xmb_ribbon_simple;
805 #endif
806 
807    RARCH_LOG("[GLSL]: Compiling simple ribbon shader..\n");
808    gl_glsl_compile_program(
809          glsl,
810          VIDEO_SHADER_MENU_2,
811          &glsl->prg[VIDEO_SHADER_MENU_2],
812          &shader_prog_info);
813    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_2].id,
814          &glsl->uniforms[VIDEO_SHADER_MENU_2]);
815 
816 #if !defined(VITA)
817 #if defined(HAVE_OPENGLES)
818    shader_prog_info.vertex   = stock_vertex_xmb_snow;
819    shader_prog_info.fragment = stock_fragment_xmb_simple_snow;
820 #else
821    shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_core : stock_vertex_xmb_snow_legacy;
822    shader_prog_info.fragment = glsl_core ? stock_fragment_xmb_simple_snow_core : stock_fragment_xmb_simple_snow;
823 #endif
824 
825    RARCH_LOG("[GLSL]: Compiling snow shader..\n");
826    gl_glsl_compile_program(
827          glsl,
828          VIDEO_SHADER_MENU_3,
829          &glsl->prg[VIDEO_SHADER_MENU_3],
830          &shader_prog_info);
831    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_3].id,
832          &glsl->uniforms[VIDEO_SHADER_MENU_3]);
833 
834 #if defined(HAVE_OPENGLES)
835    shader_prog_info.vertex   = stock_vertex_xmb_snow;
836    shader_prog_info.fragment = stock_fragment_xmb_snow;
837 #else
838    shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_core : stock_vertex_xmb_snow_legacy;
839    shader_prog_info.fragment = glsl_core ? stock_fragment_xmb_snow_core : stock_fragment_xmb_snow;
840 #endif
841 
842    RARCH_LOG("[GLSL]: Compiling modern snow shader..\n");
843    gl_glsl_compile_program(
844          glsl,
845          VIDEO_SHADER_MENU_4,
846          &glsl->prg[VIDEO_SHADER_MENU_4],
847          &shader_prog_info);
848    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_4].id,
849          &glsl->uniforms[VIDEO_SHADER_MENU_4]);
850 
851 #if defined(HAVE_OPENGLES)
852    shader_prog_info.vertex   = stock_vertex_xmb_snow;
853    shader_prog_info.fragment = stock_fragment_xmb_bokeh;
854 #else
855    shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_core  : stock_vertex_xmb_snow_legacy;
856    shader_prog_info.fragment = glsl_core ? stock_fragment_xmb_bokeh_core : stock_fragment_xmb_bokeh;
857 #endif
858 
859    RARCH_LOG("[GLSL]: Compiling bokeh shader..\n");
860    gl_glsl_compile_program(
861          glsl,
862          VIDEO_SHADER_MENU_5,
863          &glsl->prg[VIDEO_SHADER_MENU_5],
864          &shader_prog_info);
865    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_5].id,
866          &glsl->uniforms[VIDEO_SHADER_MENU_5]);
867 
868 #if defined(HAVE_OPENGLES)
869    shader_prog_info.vertex   = stock_vertex_xmb_snow;
870    shader_prog_info.fragment = stock_fragment_xmb_snowflake;
871 #else
872    shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_core : stock_vertex_xmb_snow_legacy;
873    shader_prog_info.fragment = glsl_core ? stock_fragment_xmb_snowflake_core : stock_fragment_xmb_snowflake;
874 #endif
875 
876    RARCH_LOG("[GLSL]: Compiling snowflake shader..\n");
877    gl_glsl_compile_program(
878          glsl,
879          VIDEO_SHADER_MENU_6,
880          &glsl->prg[VIDEO_SHADER_MENU_6],
881          &shader_prog_info);
882    gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_6].id,
883          &glsl->uniforms[VIDEO_SHADER_MENU_6]);
884 #endif
885 #endif
886 }
887 
gl_glsl_init(void * data,const char * path)888 static void *gl_glsl_init(void *data, const char *path)
889 {
890    unsigned i;
891    struct shader_program_info shader_prog_info;
892    bool shader_support        = false;
893 #ifdef GLSL_DEBUG
894    char *error_string         = NULL;
895 #endif
896    const char *stock_vertex   = NULL;
897    const char *stock_fragment = NULL;
898    glsl_shader_data_t   *glsl = (glsl_shader_data_t*)
899       calloc(1, sizeof(glsl_shader_data_t));
900 
901    if (!glsl)
902       return NULL;
903 
904    (void)shader_support;
905 
906 #ifndef HAVE_OPENGLES
907    RARCH_LOG("[GLSL]: Checking GLSL shader support ...\n");
908    shader_support = glCreateProgram && glUseProgram && glCreateShader
909       && glDeleteShader && glShaderSource && glCompileShader && glAttachShader
910       && glDetachShader && glLinkProgram && glGetUniformLocation
911       && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
912       && glUniformMatrix4fv
913       && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
914       && glGetProgramInfoLog
915       && glDeleteProgram && glGetAttachedShaders
916       && glGetAttribLocation && glEnableVertexAttribArray
917       && glDisableVertexAttribArray
918       && glVertexAttribPointer
919       && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;
920 
921    if (!shader_support)
922    {
923       RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
924       goto error;
925    }
926 #endif
927 
928    glsl->shader = (struct video_shader*)calloc(1, sizeof(*glsl->shader));
929    if (!glsl->shader)
930       goto error;
931 
932    {
933       bool is_preset;
934       enum rarch_shader_type type =
935          video_shader_get_type_from_ext(path_get_extension(path), &is_preset);
936 
937       if (!string_is_empty(path) && type != RARCH_SHADER_GLSL)
938       {
939          RARCH_ERR("[GL]: Invalid shader type, falling back to stock.\n");
940          path = NULL;
941       }
942 
943       if (!string_is_empty(path))
944       {
945          bool ret = false;
946 
947          if (is_preset)
948          {
949             ret = video_shader_load_preset_into_shader(path, glsl->shader);
950             glsl->shader->modern = true;
951          }
952          else
953          {
954             strlcpy(glsl->shader->pass[0].source.path, path,
955                   sizeof(glsl->shader->pass[0].source.path));
956             glsl->shader->passes = 1;
957             glsl->shader->modern = true;
958             ret = true;
959          }
960 
961          if (!ret)
962          {
963             RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
964             goto error;
965          }
966       }
967       else
968       {
969          RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
970          glsl->shader->passes = 1;
971 #if defined(VITA)
972          glsl->shader->pass[0].source.string.vertex   = strdup(stock_vertex_modern);
973          glsl->shader->pass[0].source.string.fragment = strdup(stock_fragment_modern);
974 #else
975          glsl->shader->pass[0].source.string.vertex   =
976             strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
977          glsl->shader->pass[0].source.string.fragment =
978             strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
979 #endif
980          glsl->shader->modern = true;
981       }
982    }
983 
984 #if defined(VITA)
985     stock_vertex = stock_vertex_modern;
986     stock_fragment = stock_fragment_modern;
987 #else
988    stock_vertex = (glsl->shader->modern) ?
989       stock_vertex_modern : stock_vertex_legacy;
990    stock_fragment = (glsl->shader->modern) ?
991       stock_fragment_modern : stock_fragment_legacy;
992 
993    if (glsl_core)
994    {
995       stock_vertex = stock_vertex_core;
996       stock_fragment = stock_fragment_core;
997    }
998 #endif
999 
1000 #ifdef HAVE_OPENGLES
1001    if (!glsl->shader->modern)
1002    {
1003       RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
1004       goto error;
1005    }
1006 #else
1007    if (glsl_core && !glsl->shader->modern)
1008    {
1009       RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n");
1010       goto error;
1011    }
1012 #endif
1013 
1014    /* Find all aliases we use in our GLSLP and add #defines for them so
1015     * that a shader can choose a fallback if we are not using a preset. */
1016    *glsl->alias_define = '\0';
1017    for (i = 0; i < glsl->shader->passes; i++)
1018    {
1019       if (*glsl->shader->pass[i].alias)
1020       {
1021          char define[128];
1022 
1023          define[0] = '\0';
1024 
1025          snprintf(define, sizeof(define), "#define %s_ALIAS\n",
1026                glsl->shader->pass[i].alias);
1027          strlcat(glsl->alias_define, define, sizeof(glsl->alias_define));
1028       }
1029    }
1030 
1031    shader_prog_info.vertex   = stock_vertex;
1032    shader_prog_info.fragment = stock_fragment;
1033    shader_prog_info.is_file  = false;
1034 
1035    if (!gl_glsl_compile_program(glsl, 0, &glsl->prg[0], &shader_prog_info))
1036    {
1037       RARCH_ERR("GLSL stock programs failed to compile.\n");
1038       goto error;
1039    }
1040 
1041    if (!gl_glsl_compile_programs(glsl, &glsl->prg[1]))
1042       goto error;
1043 
1044    if (!gl_load_luts(glsl->shader, glsl->lut_textures))
1045    {
1046       RARCH_ERR("[GL]: Failed to load LUTs.\n");
1047       goto error;
1048    }
1049 
1050    for (i = 0; i <= glsl->shader->passes; i++)
1051       gl_glsl_find_uniforms(glsl, i, glsl->prg[i].id, &glsl->uniforms[i]);
1052 
1053 #ifdef GLSL_DEBUG
1054    if (!gl_check_error(&error_string))
1055    {
1056       RARCH_ERR("%s\n", error_string);
1057       free(error_string);
1058       RARCH_WARN("Detected GL error in GLSL.\n");
1059    }
1060 #endif
1061 
1062    glsl->prg[glsl->shader->passes  + 1]     = glsl->prg[0];
1063    glsl->uniforms[glsl->shader->passes + 1] = glsl->uniforms[0];
1064 
1065    if (glsl->shader->modern)
1066    {
1067 #if defined(VITA)
1068       shader_prog_info.vertex   = stock_vertex_modern_blend;
1069       shader_prog_info.fragment = stock_fragment_modern_blend;
1070 #else
1071       shader_prog_info.vertex   =
1072             glsl_core ?
1073             stock_vertex_core_blend : stock_vertex_modern_blend;
1074       shader_prog_info.fragment =
1075             glsl_core ?
1076             stock_fragment_core_blend : stock_fragment_modern_blend;
1077 #endif
1078       shader_prog_info.is_file  = false;
1079 
1080       gl_glsl_compile_program(
1081             glsl,
1082             VIDEO_SHADER_STOCK_BLEND,
1083             &glsl->prg[VIDEO_SHADER_STOCK_BLEND],
1084             &shader_prog_info
1085             );
1086 
1087       gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_STOCK_BLEND].id,
1088             &glsl->uniforms[VIDEO_SHADER_STOCK_BLEND]);
1089    }
1090    else
1091    {
1092       glsl->prg[VIDEO_SHADER_STOCK_BLEND] = glsl->prg[0];
1093       glsl->uniforms[VIDEO_SHADER_STOCK_BLEND] = glsl->uniforms[0];
1094    }
1095 
1096    gl_glsl_reset_attrib(glsl);
1097 
1098    for (i = 0; i < GFX_MAX_SHADERS; i++)
1099    {
1100       glGenBuffers(1, &glsl->vbo[i].vbo_primary);
1101       glGenBuffers(1, &glsl->vbo[i].vbo_secondary);
1102    }
1103 
1104    return glsl;
1105 
1106 error:
1107    gl_glsl_destroy_resources(glsl);
1108 
1109    if (glsl)
1110       free(glsl);
1111 
1112    return NULL;
1113 }
1114 
gl_glsl_set_uniform_parameter(void * data,struct uniform_info * param,void * uniform_data)1115 static void gl_glsl_set_uniform_parameter(
1116       void *data,
1117       struct uniform_info *param,
1118       void *uniform_data)
1119 {
1120    GLint            location = 0;
1121    glsl_shader_data_t  *glsl = (glsl_shader_data_t*)data;
1122 
1123    if (!glsl || !param)
1124       return;
1125 
1126    if (param->lookup.enable)
1127       location = glGetUniformLocation(glsl->prg[param->lookup.idx].id, param->lookup.ident);
1128    else
1129       location = param->location;
1130 
1131    switch (param->type)
1132    {
1133       case UNIFORM_1F:
1134          glUniform1f(location, param->result.f.v0);
1135          break;
1136       case UNIFORM_2F:
1137          glUniform2f(location, param->result.f.v0,
1138                param->result.f.v1);
1139          break;
1140       case UNIFORM_3F:
1141          glUniform3f(location, param->result.f.v0,
1142                param->result.f.v1, param->result.f.v2);
1143          break;
1144       case UNIFORM_4F:
1145          glUniform4f(location, param->result.f.v0,
1146                param->result.f.v1, param->result.f.v2,
1147                param->result.f.v3);
1148          break;
1149       case UNIFORM_1FV:
1150          glUniform1fv(location, 1, param->result.floatv);
1151          break;
1152       case UNIFORM_2FV:
1153          glUniform2fv(location, 1, param->result.floatv);
1154          break;
1155       case UNIFORM_3FV:
1156          glUniform3fv(location, 1, param->result.floatv);
1157          break;
1158       case UNIFORM_4FV:
1159          glUniform4fv(location, 1, param->result.floatv);
1160          break;
1161       case UNIFORM_1I:
1162          glUniform1i(location, (GLint)param->result.integer.v0);
1163          break;
1164    }
1165 }
1166 
gl_glsl_set_params(void * dat,void * shader_data)1167 static void gl_glsl_set_params(void *dat, void *shader_data)
1168 {
1169    unsigned i;
1170    GLfloat buffer[512];
1171    struct glsl_attrib attribs[32];
1172    float input_size[2], output_size[2], texture_size[2];
1173    video_shader_ctx_params_t          *params = (video_shader_ctx_params_t*)dat;
1174    unsigned width                             = params->width;
1175    unsigned height                            = params->height;
1176    unsigned tex_width                         = params->tex_width;
1177    unsigned tex_height                        = params->tex_height;
1178    unsigned out_width                         = params->out_width;
1179    unsigned out_height                        = params->out_height;
1180    unsigned frame_count                       = params->frame_counter;
1181    const void *_info                          = params->info;
1182    const void *_prev_info                     = params->prev_info;
1183    const void *_feedback_info                 = params->feedback_info;
1184    const void *_fbo_info                      = params->fbo_info;
1185    unsigned fbo_info_cnt                      = params->fbo_info_cnt;
1186    unsigned                           texunit = 1;
1187    const struct          shader_uniforms *uni = NULL;
1188    size_t                                size = 0;
1189    size_t                        attribs_size = 0;
1190    const struct video_tex_info          *info = (const struct video_tex_info*)_info;
1191    const struct video_tex_info     *prev_info = (const struct video_tex_info*)_prev_info;
1192    const struct video_tex_info *feedback_info = (const struct video_tex_info*)_feedback_info;
1193    const struct video_tex_info      *fbo_info = (const struct video_tex_info*)_fbo_info;
1194    struct glsl_attrib                   *attr = (struct glsl_attrib*)attribs;
1195    glsl_shader_data_t                   *glsl = (glsl_shader_data_t*)shader_data;
1196 
1197    if (!glsl)
1198       return;
1199 
1200    uni = (const struct shader_uniforms*)&glsl->uniforms[glsl->active_idx];
1201 
1202    if (glsl->prg[glsl->active_idx].id == 0)
1203       return;
1204 
1205    input_size [0]  = (float)width;
1206    input_size [1]  = (float)height;
1207    output_size[0]  = (float)out_width;
1208    output_size[1]  = (float)out_height;
1209    texture_size[0] = (float)tex_width;
1210    texture_size[1] = (float)tex_height;
1211 
1212    if (uni->input_size >= 0)
1213       glUniform2fv(uni->input_size, 1, input_size);
1214 
1215    if (uni->output_size >= 0)
1216       glUniform2fv(uni->output_size, 1, output_size);
1217 
1218    if (uni->texture_size >= 0)
1219       glUniform2fv(uni->texture_size, 1, texture_size);
1220 
1221    if (uni->frame_count >= 0 && glsl->active_idx)
1222    {
1223       unsigned modulo = glsl->shader->pass[glsl->active_idx - 1].frame_count_mod;
1224 
1225       if (modulo)
1226          frame_count %= modulo;
1227 
1228       glUniform1i(uni->frame_count, frame_count);
1229    }
1230 
1231    if (uni->frame_direction >= 0)
1232    {
1233 #ifdef HAVE_REWIND
1234       if (state_manager_frame_is_reversed())
1235          glUniform1i(uni->frame_direction, -1);
1236       else
1237 #endif
1238          glUniform1i(uni->frame_direction, 1);
1239    }
1240 
1241    /* Set lookup textures. */
1242    for (i = 0; i < glsl->shader->luts; i++)
1243    {
1244       if (uni->lut_texture[i] < 0)
1245          continue;
1246 
1247       /* Have to rebind as HW render could override this. */
1248       glActiveTexture(GL_TEXTURE0 + texunit);
1249       glBindTexture(GL_TEXTURE_2D, glsl->lut_textures[i]);
1250       glUniform1i(uni->lut_texture[i], texunit);
1251       texunit++;
1252    }
1253 
1254    if (glsl->active_idx)
1255    {
1256       /* Set original texture. */
1257       if (uni->orig.texture >= 0)
1258       {
1259          /* Bind original texture. */
1260          glActiveTexture(GL_TEXTURE0 + texunit);
1261          glUniform1i(uni->orig.texture, texunit);
1262          glBindTexture(GL_TEXTURE_2D, info->tex);
1263          texunit++;
1264       }
1265 
1266       if (uni->orig.texture_size >= 0)
1267          glUniform2fv(uni->orig.texture_size, 1, info->tex_size);
1268 
1269       if (uni->orig.input_size >= 0)
1270          glUniform2fv(uni->orig.input_size, 1, info->input_size);
1271 
1272       /* Pass texture coordinates. */
1273       if (uni->orig.tex_coord >= 0)
1274       {
1275          attr->loc    = uni->orig.tex_coord;
1276          attr->size   = 2;
1277          attr->offset = (GLsizei)(size * sizeof(GLfloat));
1278          attribs_size++;
1279          attr++;
1280 
1281          buffer[size ]       = info->coord[0];
1282          buffer[size + 1]    = info->coord[1];
1283          buffer[size + 2]    = info->coord[2];
1284          buffer[size + 3]    = info->coord[3];
1285          buffer[size + 4]    = info->coord[4];
1286          buffer[size + 5]    = info->coord[5];
1287          buffer[size + 6]    = info->coord[6];
1288          buffer[size + 7]    = info->coord[7];
1289          size += 8;
1290       }
1291 
1292       /* Set feedback texture. */
1293       if (uni->feedback.texture >= 0)
1294       {
1295          /* Bind original texture. */
1296          glActiveTexture(GL_TEXTURE0 + texunit);
1297          glUniform1i(uni->feedback.texture, texunit);
1298          glBindTexture(GL_TEXTURE_2D, feedback_info->tex);
1299          texunit++;
1300       }
1301 
1302       if (uni->feedback.texture_size >= 0)
1303          glUniform2fv(uni->feedback.texture_size, 1, feedback_info->tex_size);
1304 
1305       if (uni->feedback.input_size >= 0)
1306          glUniform2fv(uni->feedback.input_size, 1, feedback_info->input_size);
1307 
1308       /* Pass texture coordinates. */
1309       if (uni->feedback.tex_coord >= 0)
1310       {
1311          attr->loc    = uni->feedback.tex_coord;
1312          attr->size   = 2;
1313          attr->offset = (GLsizei)(size * sizeof(GLfloat));
1314          attribs_size++;
1315          attr++;
1316 
1317          buffer[size  ]      = feedback_info->coord[0];
1318          buffer[size + 1]    = feedback_info->coord[1];
1319          buffer[size + 2]    = feedback_info->coord[2];
1320          buffer[size + 3]    = feedback_info->coord[3];
1321          buffer[size + 4]    = feedback_info->coord[4];
1322          buffer[size + 5]    = feedback_info->coord[5];
1323          buffer[size + 6]    = feedback_info->coord[6];
1324          buffer[size + 7]    = feedback_info->coord[7];
1325          size += 8;
1326       }
1327 
1328       /* Bind FBO textures. */
1329       for (i = 0; i < fbo_info_cnt; i++)
1330       {
1331          if (uni->pass[i].texture)
1332          {
1333             glActiveTexture(GL_TEXTURE0 + texunit);
1334             glBindTexture(GL_TEXTURE_2D, fbo_info[i].tex);
1335             glUniform1i(uni->pass[i].texture, texunit);
1336             texunit++;
1337          }
1338 
1339           if (uni->pass[i].texture_size >= 0)
1340             glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size);
1341 
1342          if (uni->pass[i].input_size >= 0)
1343             glUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size);
1344 
1345          if (uni->pass[i].tex_coord >= 0)
1346          {
1347             attr->loc    = uni->pass[i].tex_coord;
1348             attr->size   = 2;
1349             attr->offset = (GLsizei)(size * sizeof(GLfloat));
1350             attribs_size++;
1351             attr++;
1352 
1353             buffer[size  ]      = fbo_info[i].coord[0];
1354             buffer[size + 1]    = fbo_info[i].coord[1];
1355             buffer[size + 2]    = fbo_info[i].coord[2];
1356             buffer[size + 3]    = fbo_info[i].coord[3];
1357             buffer[size + 4]    = fbo_info[i].coord[4];
1358             buffer[size + 5]    = fbo_info[i].coord[5];
1359             buffer[size + 6]    = fbo_info[i].coord[6];
1360             buffer[size + 7]    = fbo_info[i].coord[7];
1361             size += 8;
1362          }
1363       }
1364    }
1365 
1366    /* Set previous textures. Only bind if they're actually used. */
1367    for (i = 0; i < PREV_TEXTURES; i++)
1368    {
1369       if (uni->prev[i].texture >= 0)
1370       {
1371          glActiveTexture(GL_TEXTURE0 + texunit);
1372          glBindTexture(GL_TEXTURE_2D, prev_info[i].tex);
1373          glUniform1i(uni->prev[i].texture, texunit);
1374          texunit++;
1375       }
1376 
1377       if (uni->prev[i].texture_size >= 0)
1378          glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size);
1379 
1380       if (uni->prev[i].input_size >= 0)
1381          glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size);
1382 
1383       /* Pass texture coordinates. */
1384       if (uni->prev[i].tex_coord >= 0)
1385       {
1386          attr->loc    = uni->prev[i].tex_coord;
1387          attr->size   = 2;
1388          attr->offset = (GLsizei)(size * sizeof(GLfloat));
1389          attribs_size++;
1390          attr++;
1391 
1392          buffer[size  ]      = prev_info[i].coord[0];
1393          buffer[size + 1]    = prev_info[i].coord[1];
1394          buffer[size + 2]    = prev_info[i].coord[2];
1395          buffer[size + 3]    = prev_info[i].coord[3];
1396          buffer[size + 4]    = prev_info[i].coord[4];
1397          buffer[size + 5]    = prev_info[i].coord[5];
1398          buffer[size + 6]    = prev_info[i].coord[6];
1399          buffer[size + 7]    = prev_info[i].coord[7];
1400          size += 8;
1401       }
1402    }
1403 
1404    if (size)
1405       gl_glsl_set_attribs(glsl, glsl->vbo[glsl->active_idx].vbo_secondary,
1406             &glsl->vbo[glsl->active_idx].buffer_secondary,
1407             &glsl->vbo[glsl->active_idx].size_secondary,
1408             buffer, size, attribs, attribs_size);
1409 
1410    glActiveTexture(GL_TEXTURE0);
1411 
1412    /* #pragma parameters. */
1413    for (i = 0; i < glsl->shader->num_parameters; i++)
1414    {
1415 
1416       int location = glGetUniformLocation(
1417             glsl->prg[glsl->active_idx].id,
1418             glsl->shader->parameters[i].id);
1419       glUniform1f(location, glsl->shader->parameters[i].current);
1420    }
1421 }
1422 
gl_glsl_set_mvp(void * shader_data,const void * mat_data)1423 static bool gl_glsl_set_mvp(void *shader_data, const void *mat_data)
1424 {
1425    int loc;
1426    glsl_shader_data_t *glsl   = (glsl_shader_data_t*)shader_data;
1427 
1428    if (!glsl || !glsl->shader->modern)
1429       return false;
1430 
1431    loc = glsl->uniforms[glsl->active_idx].mvp;
1432    if (loc >= 0)
1433    {
1434       const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data;
1435 
1436       if (  (glsl->current_idx != glsl->active_idx) ||
1437             (mat->data  != glsl->current_mat_data_pointer[glsl->active_idx]) ||
1438             (*mat->data != glsl->current_mat_data[glsl->active_idx]))
1439       {
1440          glUniformMatrix4fv(loc, 1, GL_FALSE, mat->data);
1441          glsl->current_idx                                = glsl->active_idx;
1442          glsl->current_mat_data_pointer[glsl->active_idx] = (float*)mat->data;
1443          glsl->current_mat_data[glsl->active_idx]         = *mat->data;
1444       }
1445    }
1446 
1447    return true;
1448 }
1449 
1450 #define gl_glsl_set_coord_array(attribs, coord1, coord2, coords, size, multiplier) \
1451    unsigned y; \
1452    attribs[attribs_size].loc            = (GLint)coord1; \
1453    attribs[attribs_size].size           = (GLsizei)multiplier; \
1454    attribs[attribs_size].offset         = (GLsizei)(size * sizeof(GLfloat)); \
1455    for (y = 0; y < (multiplier * coords->vertices); y++) \
1456       buffer[y + size]  = coord2[y]; \
1457    size                += multiplier * coords->vertices; \
1458 
gl_glsl_set_coords(void * shader_data,const struct video_coords * coords)1459 static bool gl_glsl_set_coords(void *shader_data,
1460       const struct video_coords *coords)
1461 {
1462    GLfloat short_buffer[4 * (2 + 2 + 4 + 2)];
1463    struct glsl_attrib attribs[4];
1464    size_t               attribs_size = 0;
1465    size_t                       size = 0;
1466    GLfloat *buffer                   = short_buffer;
1467    glsl_shader_data_t          *glsl = (glsl_shader_data_t*)shader_data;
1468    const struct shader_uniforms *uni = glsl
1469       ? &glsl->uniforms[glsl->active_idx] : NULL;
1470 
1471    if (!glsl || !glsl->shader->modern || !coords)
1472    {
1473       if (coords)
1474          return false;
1475       return true;
1476    }
1477 
1478    if (coords->vertices > 4)
1479    {
1480       /* Avoid hitting malloc on every single regular quad draw. */
1481 
1482       size_t elems  = 0;
1483       elems        += (uni->color >= 0)         * 4;
1484       elems        += (uni->tex_coord >= 0)     * 2;
1485       elems        += (uni->vertex_coord >= 0)  * 2;
1486       elems        += (uni->lut_tex_coord >= 0) * 2;
1487 
1488       elems        *= coords->vertices * sizeof(GLfloat);
1489 
1490       buffer        = (GLfloat*)malloc(elems);
1491 
1492       if (!buffer)
1493          return false;
1494    }
1495 
1496 #if defined(VITA)
1497    if (uni->time >= 0) {
1498       float t = (sceKernelGetSystemTimeWide()) / (scePowerGetArmClockFrequency() * 1000.0);
1499       glUniform1f(uni->time, t);
1500    }
1501 #endif
1502 
1503    if (uni->tex_coord >= 0)
1504    {
1505       gl_glsl_set_coord_array(attribs, uni->tex_coord,
1506             coords->tex_coord, coords, size, 2);
1507       attribs_size++;
1508    }
1509 
1510    if (uni->vertex_coord >= 0)
1511    {
1512       gl_glsl_set_coord_array(attribs, uni->vertex_coord,
1513             coords->vertex, coords, size, 2);
1514       attribs_size++;
1515    }
1516 
1517    if (uni->color >= 0)
1518    {
1519       gl_glsl_set_coord_array(attribs, uni->color,
1520             coords->color, coords, size, 4);
1521       attribs_size++;
1522    }
1523 
1524    if (uni->lut_tex_coord >= 0)
1525    {
1526       gl_glsl_set_coord_array(attribs, uni->lut_tex_coord,
1527             coords->lut_tex_coord, coords, size, 2);
1528       attribs_size++;
1529    }
1530 
1531    if (size)
1532       gl_glsl_set_attribs(glsl,
1533             glsl->vbo[glsl->active_idx].vbo_primary,
1534             &glsl->vbo[glsl->active_idx].buffer_primary,
1535             &glsl->vbo[glsl->active_idx].size_primary,
1536             buffer, size,
1537             attribs, attribs_size);
1538 
1539    if (buffer != short_buffer)
1540       free(buffer);
1541 
1542    return true;
1543 }
1544 
gl_glsl_use(void * data,void * shader_data,unsigned idx,bool set_active)1545 static void gl_glsl_use(void *data, void *shader_data, unsigned idx, bool set_active)
1546 {
1547    GLuint id;
1548 
1549    if (set_active)
1550    {
1551       glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data;
1552       if (!glsl)
1553          return;
1554 
1555       gl_glsl_reset_attrib(glsl);
1556       glsl->active_idx        = idx;
1557       id                      = glsl->prg[idx].id;
1558    }
1559    else
1560       id = (GLuint)idx;
1561 
1562    glUseProgram(id);
1563 }
1564 
gl_glsl_num(void * data)1565 static unsigned gl_glsl_num(void *data)
1566 {
1567    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1568    if (glsl && glsl->shader)
1569       return glsl->shader->passes;
1570    return 0;
1571 }
1572 
gl_glsl_filter_type(void * data,unsigned idx,bool * smooth)1573 static bool gl_glsl_filter_type(void *data, unsigned idx, bool *smooth)
1574 {
1575    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1576    if (glsl && idx
1577          && (glsl->shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC)
1578       )
1579    {
1580       *smooth = (glsl->shader->pass[idx - 1].filter == RARCH_FILTER_LINEAR);
1581       return true;
1582    }
1583    return false;
1584 }
1585 
gl_glsl_wrap_type(void * data,unsigned idx)1586 static enum gfx_wrap_type gl_glsl_wrap_type(void *data, unsigned idx)
1587 {
1588    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1589    if (glsl && idx)
1590       return glsl->shader->pass[idx - 1].wrap;
1591    return RARCH_WRAP_BORDER;
1592 }
1593 
gl_glsl_shader_scale(void * data,unsigned idx,struct gfx_fbo_scale * scale)1594 static void gl_glsl_shader_scale(void *data, unsigned idx, struct gfx_fbo_scale *scale)
1595 {
1596    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1597    if (glsl && idx)
1598       *scale = glsl->shader->pass[idx - 1].fbo;
1599    else
1600       scale->valid = false;
1601 }
1602 
gl_glsl_get_prev_textures(void * data)1603 static unsigned gl_glsl_get_prev_textures(void *data)
1604 {
1605    unsigned i, j;
1606    unsigned max_prev = 0;
1607    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1608 
1609    if (!glsl)
1610       return 0;
1611 
1612    for (i = 1; i <= glsl->shader->passes; i++)
1613       for (j = 0; j < PREV_TEXTURES; j++)
1614          if (glsl->uniforms[i].prev[j].texture >= 0)
1615             max_prev = MAX(j + 1, max_prev);
1616 
1617    return max_prev;
1618 }
1619 
gl_glsl_mipmap_input(void * data,unsigned idx)1620 static bool gl_glsl_mipmap_input(void *data, unsigned idx)
1621 {
1622    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1623    if (glsl && idx)
1624       return glsl->shader->pass[idx - 1].mipmap;
1625    return false;
1626 }
1627 
gl_glsl_get_feedback_pass(void * data,unsigned * index)1628 static bool gl_glsl_get_feedback_pass(void *data, unsigned *index)
1629 {
1630    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1631    if (!glsl || glsl->shader->feedback_pass < 0)
1632       return false;
1633 
1634    *index = glsl->shader->feedback_pass;
1635    return true;
1636 }
1637 
gl_glsl_get_current_shader(void * data)1638 static struct video_shader *gl_glsl_get_current_shader(void *data)
1639 {
1640    glsl_shader_data_t *glsl = (glsl_shader_data_t*)data;
1641    if (!glsl)
1642       return NULL;
1643    return glsl->shader;
1644 }
1645 
gl_glsl_get_flags(uint32_t * flags)1646 static void gl_glsl_get_flags(uint32_t *flags)
1647 {
1648    BIT32_SET(*flags, GFX_CTX_FLAGS_SHADERS_GLSL);
1649 }
1650 
gl_glsl_set_context_type(bool core_profile,unsigned major,unsigned minor)1651 void gl_glsl_set_context_type(bool core_profile,
1652       unsigned major, unsigned minor)
1653 {
1654    glsl_core  = core_profile;
1655    glsl_major = major;
1656    glsl_minor = minor;
1657 }
1658 
1659 
1660 const shader_backend_t gl_glsl_backend = {
1661    gl_glsl_init,
1662    gl_glsl_init_menu_shaders,
1663    gl_glsl_deinit,
1664    gl_glsl_set_params,
1665    gl_glsl_set_uniform_parameter,
1666    gl_glsl_compile_program,
1667    gl_glsl_use,
1668    gl_glsl_num,
1669    gl_glsl_filter_type,
1670    gl_glsl_wrap_type,
1671    gl_glsl_shader_scale,
1672    gl_glsl_set_coords,
1673    gl_glsl_set_mvp,
1674    gl_glsl_get_prev_textures,
1675    gl_glsl_get_feedback_pass,
1676    gl_glsl_mipmap_input,
1677    gl_glsl_get_current_shader,
1678    gl_glsl_get_flags,
1679 
1680    RARCH_SHADER_GLSL,
1681    "glsl"
1682 };
1683