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