update vibration handling
[pcsx_rearmed.git] / deps / libretro-common / glsm / glsm.c
1 /* Copyright (C) 2010-2018 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this libretro SDK code part (glsm).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <glsym/glsym.h>
26 #include <glsm/glsm.h>
27
28 #ifndef GL_DEPTH_CLAMP
29 #define GL_DEPTH_CLAMP                    0x864F
30 #define GL_RASTERIZER_DISCARD             0x8C89
31 #define GL_SAMPLE_MASK                    0x8E51
32 #endif
33
34 #if 0
35 extern retro_log_printf_t log_cb;
36 #define GLSM_DEBUG
37 #endif
38
39 struct gl_cached_state
40 {
41    struct
42    {
43       GLuint *ids;
44    } bind_textures;
45
46    struct
47    {
48       bool used[MAX_ATTRIB];
49       GLint size[MAX_ATTRIB];
50       GLenum type[MAX_ATTRIB];
51       GLboolean normalized[MAX_ATTRIB];
52       GLsizei stride[MAX_ATTRIB];
53       const GLvoid *pointer[MAX_ATTRIB];
54       GLuint buffer[MAX_ATTRIB];
55    } attrib_pointer;
56
57 #ifndef HAVE_OPENGLES
58    GLenum colorlogicop;
59 #endif
60
61    struct
62    {
63       bool enabled[MAX_ATTRIB];
64    } vertex_attrib_pointer;
65
66    struct
67    {
68       GLenum pname;
69       GLint param;
70    } pixelstore_i;
71
72    struct
73    {
74       GLuint r;
75       GLuint g;
76       GLuint b;
77       GLuint a;
78    } clear_color;
79
80    struct
81    {
82       bool used;
83       GLint x;
84       GLint y;
85       GLsizei w;
86       GLsizei h;
87    } scissor;
88
89    struct
90    {
91       GLint x;
92       GLint y;
93       GLsizei w;
94       GLsizei h;
95    } viewport;
96
97    struct
98    {
99       bool used;
100       GLenum sfactor;
101       GLenum dfactor;
102    } blendfunc;
103
104    struct
105    {
106       bool used;
107       GLenum srcRGB;
108       GLenum dstRGB;
109       GLenum srcAlpha;
110       GLenum dstAlpha;
111    } blendfunc_separate;
112
113    struct
114    {
115       bool used;
116       GLboolean red;
117       GLboolean green;
118       GLboolean blue;
119       GLboolean alpha;
120    } colormask;
121
122    struct
123    {
124       bool used;
125       GLdouble depth;
126    } cleardepth;
127
128    struct
129    {
130       bool used;
131       GLenum func;
132    } depthfunc;
133
134    struct
135    {
136       bool used;
137       GLclampd zNear;
138       GLclampd zFar;
139    } depthrange;
140
141    struct
142    {
143       bool used;
144       GLfloat factor;
145       GLfloat units;
146    } polygonoffset;
147
148    struct
149    {
150       bool used;
151       GLenum func;
152       GLint ref;
153       GLuint mask;
154    } stencilfunc;
155
156    struct
157    {
158       bool used;
159       GLenum sfail;
160       GLenum dpfail;
161       GLenum dppass;
162    } stencilop;
163
164    struct
165    {
166       bool used;
167       GLenum mode;
168    } frontface;
169
170    struct
171    {
172       bool used;
173       GLenum mode;
174    } cullface;
175
176    struct
177    {
178       bool used;
179       GLuint mask;
180    } stencilmask;
181
182    struct
183    {
184       bool used;
185       GLboolean mask;
186    } depthmask;
187
188    struct
189    {
190       GLenum mode;
191    } readbuffer;
192
193    GLuint vao;
194    GLuint framebuf;
195    GLuint array_buffer;
196    GLuint program;
197    GLenum active_texture;
198    int cap_state[SGL_CAP_MAX];
199    int cap_translate[SGL_CAP_MAX];
200 };
201
202 static GLuint default_framebuffer;
203 static GLint glsm_max_textures;
204 struct retro_hw_render_callback hw_render;
205 static struct gl_cached_state gl_state;
206
207 /* GL wrapper-side */
208
209 /*
210  *
211  * Core in:
212  * OpenGL    : 1.0
213  */
214 GLenum rglGetError(void)
215 {
216    return glGetError();
217 }
218
219 /*
220  *
221  * Core in:
222  * OpenGL    : 3.2
223  * OpenGLES  : N/A
224  */
225
226 void rglProvokingVertex(        GLenum provokeMode)
227 {
228 #if defined(HAVE_OPENGL)
229    glProvokingVertex(provokeMode);
230 #endif
231 }
232
233 /*
234  *
235  * Core in:
236  * OpenGL    : 3.2
237  * OpenGLES  : 3.0
238  */
239 void rglGetInteger64v(  GLenum pname, int64_t *data)
240 {
241 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
242    glGetInteger64v(pname, (GLint64*)data);
243 #endif
244 }
245
246 /*
247  *
248  * Core in:
249  * OpenGL    : 3.2
250  * OpenGLES  : 3.0
251  */
252 void rglSamplerParameteri(      GLuint sampler,
253         GLenum pname,
254         GLint param)
255 {
256 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
257    glSamplerParameteri(sampler, pname, param);
258 #endif
259 }
260
261 void rglGenSamplers(    GLsizei n,
262         GLuint *samplers)
263 {
264 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
265    glGenSamplers(n, samplers);
266 #endif
267 }
268
269 void rglBindSampler(    GLuint unit,
270         GLuint sampler)
271 {
272 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
273    glBindSampler(unit, sampler);
274 #endif
275 }
276
277 /*
278  *
279  * Core in:
280  * OpenGL    : 1.0
281  */
282 void rglClear(GLbitfield mask)
283 {
284 #ifdef GLSM_DEBUG
285    log_cb(RETRO_LOG_INFO, "glClear.\n");
286 #endif
287    glClear(mask);
288 }
289
290 /*
291  *
292  * Core in:
293  * OpenGL    : 2.0
294  */
295 void rglValidateProgram(GLuint program)
296 {
297 #ifdef GLSM_DEBUG
298    log_cb(RETRO_LOG_INFO, "glValidateProgram.\n");
299 #endif
300    glValidateProgram(program);
301 }
302
303 /*
304  *
305  * Core in:
306  * OpenGL    : 1.0
307  * OpenGLES  : N/A
308  */
309 void rglPolygonMode(GLenum face, GLenum mode)
310 {
311 #ifdef GLSM_DEBUG
312    log_cb(RETRO_LOG_INFO, "glPolygonMode.\n");
313 #endif
314 #ifndef HAVE_OPENGLES
315    glPolygonMode(face, mode);
316 #endif
317 }
318
319 void rglTexSubImage2D(
320       GLenum target,
321         GLint level,
322         GLint xoffset,
323         GLint yoffset,
324         GLsizei width,
325         GLsizei height,
326         GLenum format,
327         GLenum type,
328         const GLvoid * pixels)
329 {
330 #ifdef GLSM_DEBUG
331    log_cb(RETRO_LOG_INFO, "glTexSubImage2D.\n");
332 #endif
333    glTexSubImage2D(target, level, xoffset, yoffset,
334          width, height, format, type, pixels);
335 }
336
337 void rglGetBufferSubData(       GLenum target,
338         GLintptr offset,
339         GLsizeiptr size,
340         GLvoid * data)
341 {
342 #ifdef GLSM_DEBUG
343    log_cb(RETRO_LOG_INFO, "glGetBufferSubData.\n");
344 #endif
345 #if defined(HAVE_OPENGL)
346    glGetBufferSubData(target, offset, size, data);
347 #endif
348 }
349
350 /*
351  *
352  * Core in:
353  * OpenGL    : 1.0
354  */
355 void rglLineWidth(GLfloat width)
356 {
357 #ifdef GLSM_DEBUG
358    log_cb(RETRO_LOG_INFO, "glLineWidth.\n");
359 #endif
360    glLineWidth(width);
361 }
362
363 /*
364  * Category: FBO
365  *
366  * Core in:
367  * OpenGL    : 3.0
368  * OpenGLES  : 3.0
369  */
370 void rglBlitFramebuffer(
371       GLint srcX0, GLint srcY0,
372       GLint srcX1, GLint srcY1,
373       GLint dstX0, GLint dstY0,
374       GLint dstX1, GLint dstY1,
375       GLbitfield mask, GLenum filter)
376 {
377 #ifdef GLSM_DEBUG
378    log_cb(RETRO_LOG_INFO, "glBlitFramebuffer.\n");
379 #endif
380 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
381    glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
382          dstX0, dstY0, dstX1, dstY1,
383          mask, filter);
384 #endif
385 }
386
387 /*
388  *
389  * Core in:
390  * OpenGLES  : 3.0
391  */
392 void rglReadBuffer(GLenum mode)
393 {
394 #ifdef GLSM_DEBUG
395    log_cb(RETRO_LOG_INFO, "glReadBuffer.\n");
396 #endif
397 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
398    glReadBuffer(mode);
399    gl_state.readbuffer.mode = mode;
400 #endif
401 }
402
403 /*
404  *
405  * Core in:
406  * OpenGLES  : 2.0
407  */
408 void rglClearDepth(GLdouble depth)
409 {
410 #ifdef GLSM_DEBUG
411    log_cb(RETRO_LOG_INFO, "glClearDepth.\n");
412 #endif
413    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
414 #ifdef HAVE_OPENGLES
415    glClearDepthf(depth);
416 #else
417    glClearDepth(depth);
418 #endif
419    gl_state.cleardepth.used  = true;
420    gl_state.cleardepth.depth = depth;
421 }
422
423 /*
424  *
425  * Core in:
426  * OpenGLES  : 2.0
427  */
428 void rglPixelStorei(GLenum pname, GLint param)
429 {
430 #ifdef GLSM_DEBUG
431    log_cb(RETRO_LOG_INFO, "glPixelStorei.\n");
432 #endif
433    glPixelStorei(pname, param);
434    gl_state.pixelstore_i.pname = pname;
435    gl_state.pixelstore_i.param = param;
436 }
437
438 /*
439  *
440  * Core in:
441  * OpenGLES  : 2.0
442  */
443 void rglDepthRange(GLclampd zNear, GLclampd zFar)
444 {
445 #ifdef GLSM_DEBUG
446    log_cb(RETRO_LOG_INFO, "glDepthRange.\n");
447 #endif
448 #ifdef HAVE_OPENGLES
449    glDepthRangef(zNear, zFar);
450 #else
451    glDepthRange(zNear, zFar);
452 #endif
453    gl_state.depthrange.used  = true;
454    gl_state.depthrange.zNear = zNear;
455    gl_state.depthrange.zFar  = zFar;
456 }
457
458 /*
459  *
460  * Core in:
461  * OpenGLES  : 2.0
462  */
463 void rglFrontFace(GLenum mode)
464 {
465 #ifdef GLSM_DEBUG
466    log_cb(RETRO_LOG_INFO, "glFrontFace.\n");
467 #endif
468    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
469    glFrontFace(mode);
470    gl_state.frontface.used = true;
471    gl_state.frontface.mode = mode;
472 }
473
474 /*
475  *
476  * Core in:
477  * OpenGLES  : 2.0
478  */
479 void rglDepthFunc(GLenum func)
480 {
481 #ifdef GLSM_DEBUG
482    log_cb(RETRO_LOG_INFO, "glDepthFunc.\n");
483 #endif
484    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
485    gl_state.depthfunc.used = true;
486    gl_state.depthfunc.func = func;
487    glDepthFunc(func);
488 }
489
490 /*
491  *
492  * Core in:
493  * OpenGLES  : 2.0
494  */
495 void rglColorMask(GLboolean red, GLboolean green,
496       GLboolean blue, GLboolean alpha)
497 {
498 #ifdef GLSM_DEBUG
499    log_cb(RETRO_LOG_INFO, "glColorMask.\n");
500 #endif
501    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
502    glColorMask(red, green, blue, alpha);
503    gl_state.colormask.red   = red;
504    gl_state.colormask.green = green;
505    gl_state.colormask.blue  = blue;
506    gl_state.colormask.alpha = alpha;
507    gl_state.colormask.used  = true;
508 }
509
510 /*
511  *
512  * Core in:
513  * OpenGLES  : 2.0
514  */
515 void rglCullFace(GLenum mode)
516 {
517 #ifdef GLSM_DEBUG
518    log_cb(RETRO_LOG_INFO, "glCullFace.\n");
519 #endif
520    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
521    glCullFace(mode);
522    gl_state.cullface.used = true;
523    gl_state.cullface.mode = mode;
524 }
525
526 /*
527  *
528  * Core in:
529  * OpenGLES  : 2.0
530  */
531 void rglStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
532 {
533 #ifdef GLSM_DEBUG
534    log_cb(RETRO_LOG_INFO, "glStencilOp.\n");
535 #endif
536    glStencilOp(sfail, dpfail, dppass);
537    gl_state.stencilop.used   = true;
538    gl_state.stencilop.sfail  = sfail;
539    gl_state.stencilop.dpfail = dpfail;
540    gl_state.stencilop.dppass = dppass;
541 }
542
543 /*
544  *
545  * Core in:
546  * OpenGLES  : 2.0
547  */
548 void rglStencilFunc(GLenum func, GLint ref, GLuint mask)
549 {
550 #ifdef GLSM_DEBUG
551    log_cb(RETRO_LOG_INFO, "glStencilFunc.\n");
552 #endif
553    glStencilFunc(func, ref, mask);
554    gl_state.stencilfunc.used = true;
555    gl_state.stencilfunc.func = func;
556    gl_state.stencilfunc.ref  = ref;
557    gl_state.stencilfunc.mask = mask;
558 }
559
560 /*
561  *
562  * Core in:
563  * OpenGL    : 1.0
564  */
565 GLboolean rglIsEnabled(GLenum cap)
566 {
567 #ifdef GLSM_DEBUG
568    log_cb(RETRO_LOG_INFO, "glIsEnabled.\n");
569 #endif
570    return gl_state.cap_state[cap] ? GL_TRUE : GL_FALSE;
571 }
572
573 /*
574  *
575  * Core in:
576  * OpenGL    : 1.0
577  */
578 void rglClearColor(GLclampf red, GLclampf green,
579       GLclampf blue, GLclampf alpha)
580 {
581 #ifdef GLSM_DEBUG
582    log_cb(RETRO_LOG_INFO, "glClearColor.\n");
583 #endif
584    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
585    glClearColor(red, green, blue, alpha);
586    gl_state.clear_color.r = red;
587    gl_state.clear_color.g = green;
588    gl_state.clear_color.b = blue;
589    gl_state.clear_color.a = alpha;
590 }
591
592 /*
593  *
594  * Core in:
595  * OpenGLES    : 2.0 (maybe earlier?)
596  */
597 void rglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
598 {
599 #ifdef GLSM_DEBUG
600    log_cb(RETRO_LOG_INFO, "glScissor.\n");
601 #endif
602    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
603    glScissor(x, y, width, height);
604    gl_state.scissor.used = true;
605    gl_state.scissor.x    = x;
606    gl_state.scissor.y    = y;
607    gl_state.scissor.w    = width;
608    gl_state.scissor.h    = height;
609 }
610
611 /*
612  *
613  * Core in:
614  * OpenGL    : 1.0
615  */
616 void rglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
617 {
618 #ifdef GLSM_DEBUG
619    log_cb(RETRO_LOG_INFO, "glViewport.\n");
620 #endif
621    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
622    glViewport(x, y, width, height);
623    gl_state.viewport.x = x;
624    gl_state.viewport.y = y;
625    gl_state.viewport.w = width;
626    gl_state.viewport.h = height;
627 }
628
629 void rglBlendFunc(GLenum sfactor, GLenum dfactor)
630 {
631 #ifdef GLSM_DEBUG
632    log_cb(RETRO_LOG_INFO, "glBlendFunc.\n");
633 #endif
634    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
635    gl_state.blendfunc.used    = true;
636    gl_state.blendfunc.sfactor = sfactor;
637    gl_state.blendfunc.dfactor = dfactor;
638    glBlendFunc(sfactor, dfactor);
639 }
640
641 /*
642  * Category: Blending
643  *
644  * Core in:
645  * OpenGL    : 1.4
646  */
647 void rglBlendFuncSeparate(GLenum sfactor, GLenum dfactor)
648 {
649 #ifdef GLSM_DEBUG
650    log_cb(RETRO_LOG_INFO, "glBlendFuncSeparate.\n");
651 #endif
652    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
653    gl_state.blendfunc_separate.used     = true;
654    gl_state.blendfunc_separate.srcRGB   = sfactor;
655    gl_state.blendfunc_separate.dstRGB   = dfactor;
656    gl_state.blendfunc_separate.srcAlpha = sfactor;
657    gl_state.blendfunc_separate.dstAlpha = dfactor;
658    glBlendFunc(sfactor, dfactor);
659 }
660
661 /*
662  * Category: Textures
663  *
664  * Core in:
665  * OpenGL    : 1.3
666  */
667 void rglActiveTexture(GLenum texture)
668 {
669 #ifdef GLSM_DEBUG
670    log_cb(RETRO_LOG_INFO, "glActiveTexture.\n");
671 #endif
672    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
673    glActiveTexture(texture);
674    gl_state.active_texture = texture - GL_TEXTURE0;
675 }
676
677 /*
678  *
679  * Core in:
680  * OpenGL    : 1.1
681  */
682 void rglBindTexture(GLenum target, GLuint texture)
683 {
684 #ifdef GLSM_DEBUG
685    log_cb(RETRO_LOG_INFO, "glBindTexture.\n");
686 #endif
687    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
688    glBindTexture(target, texture);
689    gl_state.bind_textures.ids[gl_state.active_texture] = texture;
690 }
691
692 /*
693  *
694  * Core in:
695  * OpenGL    : 1.0
696  */
697 void rglDisable(GLenum cap)
698 {
699 #ifdef GLSM_DEBUG
700    log_cb(RETRO_LOG_INFO, "glDisable.\n");
701 #endif
702    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
703    glDisable(gl_state.cap_translate[cap]);
704    gl_state.cap_state[cap] = 0;
705 }
706
707 /*
708  *
709  * Core in:
710  * OpenGL    : 1.0
711  */
712 void rglEnable(GLenum cap)
713 {
714 #ifdef GLSM_DEBUG
715    log_cb(RETRO_LOG_INFO, "glEnable.\n");
716 #endif
717    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
718    glEnable(gl_state.cap_translate[cap]);
719    gl_state.cap_state[cap] = 1;
720 }
721
722 /*
723  * Category: Shaders
724  *
725  * Core in:
726  * OpenGL    : 2.0
727  */
728 void rglUseProgram(GLuint program)
729 {
730 #ifdef GLSM_DEBUG
731    log_cb(RETRO_LOG_INFO, "glUseProgram.\n");
732 #endif
733    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
734    gl_state.program = program;
735    glUseProgram(program);
736 }
737
738 /*
739  *
740  * Core in:
741  * OpenGL    : 1.0
742  */
743 void rglDepthMask(GLboolean flag)
744 {
745 #ifdef GLSM_DEBUG
746    log_cb(RETRO_LOG_INFO, "glDepthMask.\n");
747 #endif
748    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
749    glDepthMask(flag);
750    gl_state.depthmask.used = true;
751    gl_state.depthmask.mask = flag;
752 }
753
754 /*
755  *
756  * Core in:
757  * OpenGL    : 1.0
758  */
759 void rglStencilMask(GLenum mask)
760 {
761 #ifdef GLSM_DEBUG
762    log_cb(RETRO_LOG_INFO, "glStencilMask.\n");
763 #endif
764    glStencilMask(mask);
765    gl_state.stencilmask.used = true;
766    gl_state.stencilmask.mask = mask;
767 }
768
769 /*
770  *
771  * Core in:
772  * OpenGL    : 1.5
773  */
774 void rglBufferData(GLenum target, GLsizeiptr size,
775       const GLvoid *data, GLenum usage)
776 {
777 #ifdef GLSM_DEBUG
778    log_cb(RETRO_LOG_INFO, "glBufferData.\n");
779 #endif
780    glBufferData(target, size, data, usage);
781 }
782
783 /*
784  *
785  * Core in:
786  * OpenGL    : 1.5
787  */
788 void rglBufferSubData(GLenum target, GLintptr offset,
789       GLsizeiptr size, const GLvoid *data)
790 {
791 #ifdef GLSM_DEBUG
792    log_cb(RETRO_LOG_INFO, "glBufferSubData.\n");
793 #endif
794    glBufferSubData(target, offset, size, data);
795 }
796
797 /*
798  *
799  * Core in:
800  * OpenGL    : 1.5
801  */
802 void rglBindBuffer(GLenum target, GLuint buffer)
803 {
804 #ifdef GLSM_DEBUG
805    log_cb(RETRO_LOG_INFO, "glBindBuffer.\n");
806 #endif
807    if (target == GL_ARRAY_BUFFER)
808       gl_state.array_buffer = buffer;
809    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
810    glBindBuffer(target, buffer);
811 }
812
813 /*
814  * Category: Shaders
815  *
816  * Core in:
817  * OpenGL    : 2.0
818  */
819 void rglLinkProgram(GLuint program)
820 {
821 #ifdef GLSM_DEBUG
822    log_cb(RETRO_LOG_INFO, "glLinkProgram.\n");
823 #endif
824    glLinkProgram(program);
825 }
826
827 /*
828  * Category: FBO
829  *
830  * Core in:
831  * OpenGL    : 3.0
832  * OpenGLES  : 2.0
833  */
834 void rglFramebufferTexture2D(GLenum target, GLenum attachment,
835       GLenum textarget, GLuint texture, GLint level)
836 {
837 #ifdef GLSM_DEBUG
838    log_cb(RETRO_LOG_INFO, "glFramebufferTexture2D.\n");
839 #endif
840    glFramebufferTexture2D(target, attachment, textarget, texture, level);
841 }
842
843 /*
844  * Category: FBO
845  *
846  * Core in:
847  * OpenGL    : 3.0
848  * OpenGLES  : 3.2
849  */
850 void rglFramebufferTexture(GLenum target, GLenum attachment,
851         GLuint texture, GLint level)
852 {
853 #ifdef GLSM_DEBUG
854    log_cb(RETRO_LOG_INFO, "glFramebufferTexture.\n");
855 #endif
856 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2)
857    glFramebufferTexture(target, attachment, texture, level);
858 #endif
859 }
860
861 /*
862  *
863  * Core in:
864  * OpenGL    : 1.1
865  */
866 void rglDrawArrays(GLenum mode, GLint first, GLsizei count)
867 {
868 #ifdef GLSM_DEBUG
869    log_cb(RETRO_LOG_INFO, "glDrawArrays.\n");
870 #endif
871    glDrawArrays(mode, first, count);
872 }
873
874 /*
875  *
876  * Core in:
877  * OpenGL    : 1.1
878  */
879 void rglDrawElements(GLenum mode, GLsizei count, GLenum type,
880                            const GLvoid * indices)
881 {
882 #ifdef GLSM_DEBUG
883    log_cb(RETRO_LOG_INFO, "glDrawElements.\n");
884 #endif
885    glDrawElements(mode, count, type, indices);
886 }
887
888 void rglCompressedTexImage2D(GLenum target, GLint level,
889       GLenum internalformat, GLsizei width, GLsizei height,
890       GLint border, GLsizei imageSize, const GLvoid *data)
891 {
892 #ifdef GLSM_DEBUG
893    log_cb(RETRO_LOG_INFO, "glCompressedTexImage2D.\n");
894 #endif
895    glCompressedTexImage2D(target, level, internalformat,
896          width, height, border, imageSize, data);
897 }
898
899 void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
900 {
901 #ifdef GLSM_DEBUG
902    log_cb(RETRO_LOG_INFO, "glDeleteFramebuffers.\n");
903 #endif
904    glDeleteFramebuffers(n, framebuffers);
905 }
906
907 void rglDeleteTextures(GLsizei n, const GLuint *textures)
908 {
909 #ifdef GLSM_DEBUG
910    log_cb(RETRO_LOG_INFO, "glDeleteTextures.\n");
911 #endif
912    glDeleteTextures(n, textures);
913 }
914
915 /*
916  *
917  * Core in:
918  * OpenGLES    : 2.0
919  */
920 void rglRenderbufferStorage(GLenum target, GLenum internalFormat,
921       GLsizei width, GLsizei height)
922 {
923 #ifdef GLSM_DEBUG
924    log_cb(RETRO_LOG_INFO, "glRenderbufferStorage.\n");
925 #endif
926    glRenderbufferStorage(target, internalFormat, width, height);
927 }
928
929 /*
930  *
931  * Core in:
932  *
933  * OpenGL      : 3.0
934  * OpenGLES    : 2.0
935  */
936 void rglBindRenderbuffer(GLenum target, GLuint renderbuffer)
937 {
938 #ifdef GLSM_DEBUG
939    log_cb(RETRO_LOG_INFO, "glBindRenderbuffer.\n");
940 #endif
941    glBindRenderbuffer(target, renderbuffer);
942 }
943
944 /*
945  *
946  * Core in:
947  *
948  * OpenGLES    : 2.0
949  */
950 void rglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers)
951 {
952 #ifdef GLSM_DEBUG
953    log_cb(RETRO_LOG_INFO, "glDeleteRenderbuffers.\n");
954 #endif
955    glDeleteRenderbuffers(n, renderbuffers);
956 }
957
958 /*
959  *
960  * Core in:
961  *
962  * OpenGL      : 3.0
963  * OpenGLES    : 2.0
964  */
965 void rglGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
966 {
967 #ifdef GLSM_DEBUG
968    log_cb(RETRO_LOG_INFO, "glGenRenderbuffers.\n");
969 #endif
970    glGenRenderbuffers(n, renderbuffers);
971 }
972
973 /*
974  *
975  * Core in:
976  *
977  * OpenGL      : 3.0
978  * OpenGLES    : 2.0
979  */
980 void rglGenerateMipmap(GLenum target)
981 {
982 #ifdef GLSM_DEBUG
983    log_cb(RETRO_LOG_INFO, "glGenerateMipmap.\n");
984 #endif
985    glGenerateMipmap(target);
986 }
987
988 /*
989  * Category: FBO
990  *
991  * Core in:
992  * OpenGL    : 3.0
993  */
994 GLenum rglCheckFramebufferStatus(GLenum target)
995 {
996 #ifdef GLSM_DEBUG
997    log_cb(RETRO_LOG_INFO, "glCheckFramebufferStatus.\n");
998 #endif
999    return glCheckFramebufferStatus(target);
1000 }
1001
1002 /*
1003  * Category: FBO
1004  *
1005  * Core in:
1006  * OpenGL    : 3.0
1007  * OpenGLES  : 2.0
1008  */
1009 void rglFramebufferRenderbuffer(GLenum target, GLenum attachment,
1010       GLenum renderbuffertarget, GLuint renderbuffer)
1011 {
1012 #ifdef GLSM_DEBUG
1013    log_cb(RETRO_LOG_INFO, "glFramebufferRenderbuffer.\n");
1014 #endif
1015    glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
1016 }
1017
1018 /*
1019  * Category: Shaders
1020  *
1021  * Core in:
1022  * OpenGL    : 3.0
1023  */
1024 void rglBindFragDataLocation(GLuint program, GLuint colorNumber,
1025                                    const char * name)
1026 {
1027 #ifdef GLSM_DEBUG
1028    log_cb(RETRO_LOG_INFO, "glBindFragDataLocation.\n");
1029 #endif
1030 #if !defined(HAVE_OPENGLES2)
1031    glBindFragDataLocation(program, colorNumber, name);
1032 #endif
1033 }
1034
1035 /*
1036  * Category: Shaders
1037  *
1038  * Core in:
1039  * OpenGL    : 2.0
1040  */
1041 void rglGetProgramiv(GLuint shader, GLenum pname, GLint *params)
1042 {
1043 #ifdef GLSM_DEBUG
1044    log_cb(RETRO_LOG_INFO, "glGetProgramiv.\n");
1045 #endif
1046    glGetProgramiv(shader, pname, params);
1047 }
1048
1049 /*
1050  * Category: Shaders
1051  *
1052  * Core in:
1053  * OpenGL    : 4.1
1054  * OpenGLES  : 3.0
1055  */
1056 void rglProgramParameteri(      GLuint program,
1057         GLenum pname,
1058         GLint value)
1059 {
1060 #ifdef GLSM_DEBUG
1061    log_cb(RETRO_LOG_INFO, "glProgramParameteri.\n");
1062 #endif
1063 #if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && (defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1))
1064    glProgramParameteri(program, pname, value);
1065 #else
1066    printf("WARNING! Not implemented.\n");
1067 #endif
1068 }
1069
1070 /*
1071  *
1072  * Core in:
1073  * OpenGL    : 2.0
1074  */
1075 void rglGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
1076       GLsizei *length, GLint *size, GLenum *type, GLchar *name)
1077 {
1078 #ifdef GLSM_DEBUG
1079    log_cb(RETRO_LOG_INFO, "glGetActiveUniform.\n");
1080 #endif
1081    glGetActiveUniform(program, index, bufsize, length, size, type, name);
1082 }
1083
1084 void rglGenQueries(     GLsizei n,
1085         GLuint * ids)
1086 {
1087 #ifdef GLSM_DEBUG
1088    log_cb(RETRO_LOG_INFO, "glGenQueries.\n");
1089 #endif
1090 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1091    glGenQueries(n, ids);
1092 #endif
1093 }
1094
1095 void rglGetQueryObjectuiv(      GLuint id,
1096         GLenum pname,
1097         GLuint * params)
1098 {
1099 #ifdef GLSM_DEBUG
1100    log_cb(RETRO_LOG_INFO, "glGetQueryObjectuiv.\n");
1101 #endif
1102 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1103    glGetQueryObjectuiv(id, pname, params);
1104 #endif
1105 }
1106
1107 void rglDeleteQueries(  GLsizei n,
1108         const GLuint * ids)
1109 {
1110 #ifdef GLSM_DEBUG
1111    log_cb(RETRO_LOG_INFO, "glDeleteQueries.\n");
1112 #endif
1113 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1114    glDeleteQueries(n, ids);
1115 #endif
1116 }
1117
1118 void rglBeginQuery(     GLenum target,
1119         GLuint id)
1120 {
1121 #ifdef GLSM_DEBUG
1122    log_cb(RETRO_LOG_INFO, "glBeginQuery.\n");
1123 #endif
1124 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1125    glBeginQuery(target, id);
1126 #endif
1127 }
1128
1129 void rglEndQuery(       GLenum target)
1130 {
1131 #ifdef GLSM_DEBUG
1132    log_cb(RETRO_LOG_INFO, "glEndQuery.\n");
1133 #endif
1134 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1135    glEndQuery(target);
1136 #endif
1137 }
1138
1139 /*
1140  * Category: UBO
1141  *
1142  * Core in:
1143  *
1144  * OpenGL    : 2.0
1145  * OpenGLES  : 3.0
1146  */
1147 void rglGetActiveUniformBlockiv(GLuint program,
1148         GLuint uniformBlockIndex,
1149         GLenum pname,
1150         GLint *params)
1151 {
1152 #ifdef GLSM_DEBUG
1153    log_cb(RETRO_LOG_INFO, "glGetActiveUniformBlockiv.\n");
1154 #endif
1155 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1156    glGetActiveUniformBlockiv(program, uniformBlockIndex,
1157          pname, params);
1158 #else
1159    printf("WARNING! Not implemented.\n");
1160 #endif
1161 }
1162
1163 /*
1164  *
1165  * Core in:
1166  *
1167  * OpenGLES  : 3.0
1168  */
1169 void rglGetActiveUniformsiv(    GLuint program,
1170         GLsizei uniformCount,
1171         const GLuint *uniformIndices,
1172         GLenum pname,
1173         GLint *params)
1174 {
1175 #ifdef GLSM_DEBUG
1176    log_cb(RETRO_LOG_INFO, "glGetActiveUniformsiv.\n");
1177 #endif
1178 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1179    glGetActiveUniformsiv(program, uniformCount,
1180          uniformIndices, pname, params);
1181 #else
1182    printf("WARNING! Not implemented.\n");
1183 #endif
1184 }
1185
1186 /*
1187  *
1188  * Core in:
1189  *
1190  * OpenGLES  : 3.0
1191  */
1192 void rglGetUniformIndices(GLuint program,
1193         GLsizei uniformCount,
1194         const GLchar **uniformNames,
1195         GLuint *uniformIndices)
1196 {
1197 #ifdef GLSM_DEBUG
1198    log_cb(RETRO_LOG_INFO, "glGetUniformIndices.\n");
1199 #endif
1200 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1201    glGetUniformIndices(program, uniformCount,
1202          uniformNames, uniformIndices);
1203 #else
1204    printf("WARNING! Not implemented.\n");
1205 #endif
1206 }
1207
1208 /*
1209  * Category: UBO
1210  *
1211  * Core in:
1212  *
1213  * OpenGLES  : 3.0
1214  */
1215 void rglBindBufferBase(         GLenum target,
1216         GLuint index,
1217         GLuint buffer)
1218 {
1219 #ifdef GLSM_DEBUG
1220    log_cb(RETRO_LOG_INFO, "glBindBufferBase.\n");
1221 #endif
1222 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1223    glBindBufferBase(target, index, buffer);
1224 #else
1225    printf("WARNING! Not implemented.\n");
1226 #endif
1227 }
1228
1229 /*
1230  *
1231  * Category: UBO
1232  *
1233  * Core in:
1234  *
1235  * OpenGLES  : 3.0
1236  */
1237 GLuint rglGetUniformBlockIndex(         GLuint program,
1238         const GLchar *uniformBlockName)
1239 {
1240 #ifdef GLSM_DEBUG
1241    log_cb(RETRO_LOG_INFO, "glGetUniformBlockIndex.\n");
1242 #endif
1243 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1244    return glGetUniformBlockIndex(program, uniformBlockName);
1245 #else
1246    printf("WARNING! Not implemented.\n");
1247    return 0;
1248 #endif
1249 }
1250
1251 /*
1252  * Category: UBO
1253  *
1254  * Core in:
1255  *
1256  * OpenGLES  : 3.0
1257  */
1258 void rglUniformBlockBinding(    GLuint program,
1259         GLuint uniformBlockIndex,
1260         GLuint uniformBlockBinding)
1261 {
1262 #ifdef GLSM_DEBUG
1263    log_cb(RETRO_LOG_INFO, "glUniformBlockBinding.\n");
1264 #endif
1265 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1266    glUniformBlockBinding(program, uniformBlockIndex,
1267          uniformBlockBinding);
1268 #else
1269    printf("WARNING! Not implemented.\n");
1270 #endif
1271 }
1272
1273 /*
1274  *
1275  * Core in:
1276  * OpenGL    : 2.0
1277  * OpenGLES  : 3.0
1278  */
1279 void rglUniform1ui(GLint location, GLuint v)
1280 {
1281 #ifdef GLSM_DEBUG
1282    log_cb(RETRO_LOG_INFO, "glUniform1ui.\n");
1283 #endif
1284 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1285    glUniform1ui(location ,v);
1286 #endif
1287 }
1288
1289 /*
1290  *
1291  * Core in:
1292  * OpenGL    : 2.0
1293  * OpenGLES  : 3.0
1294  */
1295 void rglUniform2ui(GLint location, GLuint v0, GLuint v1)
1296 {
1297 #ifdef GLSM_DEBUG
1298    log_cb(RETRO_LOG_INFO, "glUniform2ui.\n");
1299 #endif
1300 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1301    glUniform2ui(location, v0, v1);
1302 #endif
1303 }
1304
1305 /*
1306  *
1307  * Core in:
1308  * OpenGL    : 2.0
1309  * OpenGLES  : 3.0
1310  */
1311 void rglUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
1312 {
1313 #ifdef GLSM_DEBUG
1314    log_cb(RETRO_LOG_INFO, "glUniform3ui.\n");
1315 #endif
1316 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1317    glUniform3ui(location, v0, v1, v2);
1318 #endif
1319 }
1320
1321 /*
1322  *
1323  * Core in:
1324  * OpenGL    : 2.0
1325  * OpenGLES  : 3.0
1326  */
1327 void rglUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
1328 {
1329 #ifdef GLSM_DEBUG
1330    log_cb(RETRO_LOG_INFO, "glUniform4ui.\n");
1331 #endif
1332 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1333    glUniform4ui(location, v0, v1, v2, v3);
1334 #endif
1335 }
1336
1337 /*
1338  *
1339  * Core in:
1340  * OpenGL    : 2.0
1341  */
1342 void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
1343       const GLfloat *value)
1344 {
1345 #ifdef GLSM_DEBUG
1346    log_cb(RETRO_LOG_INFO, "glUniformMatrix4fv.\n");
1347 #endif
1348    glUniformMatrix4fv(location, count, transpose, value);
1349 }
1350
1351 /*
1352  * Category: Shaders
1353  *
1354  * Core in:
1355  * OpenGL    : 2.0
1356  */
1357 void rglDetachShader(GLuint program, GLuint shader)
1358 {
1359 #ifdef GLSM_DEBUG
1360    log_cb(RETRO_LOG_INFO, "glDetachShader.\n");
1361 #endif
1362    glDetachShader(program, shader);
1363 }
1364
1365 /*
1366  * Category: Shaders
1367  *
1368  * Core in:
1369  * OpenGL    : 2.0
1370  */
1371 void rglGetShaderiv(GLuint shader, GLenum pname, GLint *params)
1372 {
1373 #ifdef GLSM_DEBUG
1374    log_cb(RETRO_LOG_INFO, "glGetShaderiv.\n");
1375 #endif
1376    glGetShaderiv(shader, pname, params);
1377 }
1378
1379 /*
1380  * Category: Shaders
1381  *
1382  * Core in:
1383  * OpenGL    : 2.0
1384  */
1385 void rglAttachShader(GLuint program, GLuint shader)
1386 {
1387 #ifdef GLSM_DEBUG
1388    log_cb(RETRO_LOG_INFO, "glAttachShader.\n");
1389 #endif
1390    glAttachShader(program, shader);
1391 }
1392
1393 /*
1394  *
1395  * Core in:
1396  * OpenGL    : 2.0
1397  */
1398 GLint rglGetAttribLocation(GLuint program, const GLchar *name)
1399 {
1400 #ifdef GLSM_DEBUG
1401    log_cb(RETRO_LOG_INFO, "glGetAttribLocation.\n");
1402 #endif
1403    return glGetAttribLocation(program, name);
1404 }
1405
1406 /*
1407  * Category: Shaders
1408  *
1409  * Core in:
1410  * OpenGL    : 2.0
1411  */
1412 void rglShaderSource(GLuint shader, GLsizei count,
1413       const GLchar **string, const GLint *length)
1414 {
1415 #ifdef GLSM_DEBUG
1416    log_cb(RETRO_LOG_INFO, "glShaderSource.\n");
1417 #endif
1418    return glShaderSource(shader, count, string, length);
1419 }
1420
1421 /*
1422  * Category: Shaders
1423  *
1424  * Core in:
1425  * OpenGL    : 2.0
1426  */
1427 void rglCompileShader(GLuint shader)
1428 {
1429 #ifdef GLSM_DEBUG
1430    log_cb(RETRO_LOG_INFO, "glCompileShader.\n");
1431 #endif
1432    glCompileShader(shader);
1433 }
1434
1435 /*
1436  * Category: Shaders
1437  *
1438  * Core in:
1439  * OpenGL    : 2.0
1440  */
1441 GLuint rglCreateProgram(void)
1442 {
1443 #ifdef GLSM_DEBUG
1444    log_cb(RETRO_LOG_INFO, "glCreateProgram.\n");
1445 #endif
1446    return glCreateProgram();
1447 }
1448
1449 /*
1450  *
1451  * Core in:
1452  * OpenGL    : 1.1
1453  */
1454 void rglGenTextures(GLsizei n, GLuint *textures)
1455 {
1456 #ifdef GLSM_DEBUG
1457    log_cb(RETRO_LOG_INFO, "glGenTextures.\n");
1458 #endif
1459    glGenTextures(n, textures);
1460 }
1461
1462 /*
1463  *
1464  * Core in:
1465  * OpenGL    : 2.0
1466  */
1467 void rglGetShaderInfoLog(GLuint shader, GLsizei maxLength,
1468       GLsizei *length, GLchar *infoLog)
1469 {
1470 #ifdef GLSM_DEBUG
1471    log_cb(RETRO_LOG_INFO, "glGetShaderInfoLog.\n");
1472 #endif
1473    glGetShaderInfoLog(shader, maxLength, length, infoLog);
1474 }
1475
1476 /*
1477  *
1478  * Core in:
1479  * OpenGL    : 2.0
1480  */
1481 void rglGetProgramInfoLog(GLuint shader, GLsizei maxLength,
1482       GLsizei *length, GLchar *infoLog)
1483 {
1484 #ifdef GLSM_DEBUG
1485    log_cb(RETRO_LOG_INFO, "glGetProgramInfoLog.\n");
1486 #endif
1487    glGetProgramInfoLog(shader, maxLength, length, infoLog);
1488 }
1489
1490 /*
1491  *
1492  * Core in:
1493  * OpenGL    : 2.0
1494  */
1495 GLboolean rglIsProgram(GLuint program)
1496 {
1497 #ifdef GLSM_DEBUG
1498    log_cb(RETRO_LOG_INFO, "glIsProgram.\n");
1499 #endif
1500    return glIsProgram(program);
1501 }
1502
1503 void rglTexCoord2f(GLfloat s, GLfloat t)
1504 {
1505 #ifdef HAVE_LEGACY_GL
1506 #ifdef GLSM_DEBUG
1507    log_cb(RETRO_LOG_INFO, "glTexCoord2f.\n");
1508 #endif
1509    glTexCoord2f(s, t);
1510 #endif
1511 }
1512
1513 /*
1514  * Category: Generic vertex attributes
1515  *
1516  * Core in:
1517  * OpenGL    : 2.0
1518  *
1519  */
1520 void rglDisableVertexAttribArray(GLuint index)
1521 {
1522 #ifdef GLSM_DEBUG
1523    log_cb(RETRO_LOG_INFO, "glDisableVertexAttribArray.\n");
1524 #endif
1525    gl_state.vertex_attrib_pointer.enabled[index] = 0;
1526    glDisableVertexAttribArray(index);
1527 }
1528
1529 /*
1530  * Category: Generic vertex attributes
1531  *
1532  * Core in:
1533  * OpenGL    : 2.0
1534  */
1535 void rglEnableVertexAttribArray(GLuint index)
1536 {
1537 #ifdef GLSM_DEBUG
1538    log_cb(RETRO_LOG_INFO, "glEnableVertexAttribArray.\n");
1539 #endif
1540    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
1541    gl_state.vertex_attrib_pointer.enabled[index] = 1;
1542    glEnableVertexAttribArray(index);
1543 }
1544
1545 /*
1546  * Category: Shaders
1547  *
1548  * Core in:
1549  * OpenGL    : 2.0
1550  */
1551 void rglVertexAttribIPointer(
1552       GLuint index,
1553       GLint size,
1554       GLenum type,
1555       GLsizei stride,
1556       const GLvoid * pointer)
1557 {
1558 #ifdef GLSM_DEBUG
1559    log_cb(RETRO_LOG_INFO, "glVertexAttribIPointer.\n");
1560 #endif
1561 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
1562    glVertexAttribIPointer(index, size, type, stride, pointer);
1563 #endif
1564 }
1565
1566 void rglVertexAttribLPointer(
1567       GLuint index,
1568       GLint size,
1569       GLenum type,
1570       GLsizei stride,
1571       const GLvoid * pointer)
1572 {
1573 #ifdef GLSM_DEBUG
1574    log_cb(RETRO_LOG_INFO, "glVertexAttribLPointer.\n");
1575 #endif
1576 #if defined(HAVE_OPENGL)
1577    glVertexAttribLPointer(index, size, type, stride, pointer);
1578 #endif
1579 }
1580
1581 /*
1582  * Category: Generic vertex attributes
1583  *
1584  * Core in:
1585  * OpenGL    : 2.0
1586  */
1587 void rglVertexAttribPointer(GLuint name, GLint size,
1588       GLenum type, GLboolean normalized, GLsizei stride,
1589       const GLvoid* pointer)
1590 {
1591 #ifdef GLSM_DEBUG
1592    log_cb(RETRO_LOG_INFO, "glVertexAttribPointer.\n");
1593 #endif
1594    gl_state.attrib_pointer.used[name] = 1;
1595    gl_state.attrib_pointer.size[name] = size;
1596    gl_state.attrib_pointer.type[name] = type;
1597    gl_state.attrib_pointer.normalized[name] = normalized;
1598    gl_state.attrib_pointer.stride[name] = stride;
1599    gl_state.attrib_pointer.pointer[name] = pointer;
1600    gl_state.attrib_pointer.buffer[name] = gl_state.array_buffer;
1601    glVertexAttribPointer(name, size, type, normalized, stride, pointer);
1602 }
1603
1604 /*
1605  * Category: Generic vertex attributes
1606  *
1607  * Core in:
1608  * OpenGL    : 2.0
1609  */
1610 void rglBindAttribLocation(GLuint program, GLuint index, const GLchar *name)
1611 {
1612 #ifdef GLSM_DEBUG
1613    log_cb(RETRO_LOG_INFO, "glBindAttribLocation.\n");
1614 #endif
1615    glBindAttribLocation(program, index, name);
1616 }
1617
1618 /*
1619  *
1620  * Core in:
1621  * OpenGL    : 2.0
1622  */
1623 void rglVertexAttrib4f(GLuint name, GLfloat x, GLfloat y,
1624       GLfloat z, GLfloat w)
1625 {
1626 #ifdef GLSM_DEBUG
1627    log_cb(RETRO_LOG_INFO, "glVertexAttrib4f.\n");
1628 #endif
1629    glVertexAttrib4f(name, x, y, z, w);
1630 }
1631
1632 /*
1633  *
1634  * Core in:
1635  * OpenGL    : 2.0
1636  */
1637 void rglVertexAttrib4fv(GLuint name, GLfloat* v)
1638 {
1639 #ifdef GLSM_DEBUG
1640    log_cb(RETRO_LOG_INFO, "glVertexAttrib4fv.\n");
1641 #endif
1642    glVertexAttrib4fv(name, v);
1643 }
1644
1645 /*
1646  * Category: Shaders
1647  *
1648  * Core in:
1649  * OpenGL    : 2.0
1650  */
1651 GLuint rglCreateShader(GLenum shaderType)
1652 {
1653 #ifdef GLSM_DEBUG
1654    log_cb(RETRO_LOG_INFO, "glCreateShader.\n");
1655 #endif
1656    return glCreateShader(shaderType);
1657 }
1658
1659 /*
1660  * Category: Shaders
1661  *
1662  * Core in:
1663  * OpenGL    : 2.0
1664  */
1665 void rglDeleteProgram(GLuint program)
1666 {
1667 #ifdef GLSM_DEBUG
1668    log_cb(RETRO_LOG_INFO, "glDeleteProgram.\n");
1669 #endif
1670    glDeleteProgram(program);
1671 }
1672
1673 /*
1674  * Category: Shaders
1675  *
1676  * Core in:
1677  * OpenGL    : 2.0
1678  */
1679 void rglDeleteShader(GLuint shader)
1680 {
1681 #ifdef GLSM_DEBUG
1682    log_cb(RETRO_LOG_INFO, "glDeleteShader.\n");
1683 #endif
1684    glDeleteShader(shader);
1685 }
1686
1687 /*
1688  * Category: Shaders
1689  *
1690  * Core in:
1691  * OpenGL    : 2.0
1692  */
1693 GLint rglGetUniformLocation(GLuint program, const GLchar *name)
1694 {
1695 #ifdef GLSM_DEBUG
1696    log_cb(RETRO_LOG_INFO, "glGetUniformLocation.\n");
1697 #endif
1698    return glGetUniformLocation(program, name);
1699 }
1700
1701 /*
1702  * Category: VBO and PBO
1703  *
1704  * Core in:
1705  * OpenGL    : 1.5
1706  */
1707 void rglDeleteBuffers(GLsizei n, const GLuint *buffers)
1708 {
1709 #ifdef GLSM_DEBUG
1710    log_cb(RETRO_LOG_INFO, "glDeleteBuffers.\n");
1711 #endif
1712    glDeleteBuffers(n, buffers);
1713 }
1714
1715 /*
1716  * Category: VBO and PBO
1717  *
1718  * Core in:
1719  * OpenGL    : 1.5
1720  */
1721 void rglGenBuffers(GLsizei n, GLuint *buffers)
1722 {
1723 #ifdef GLSM_DEBUG
1724    log_cb(RETRO_LOG_INFO, "glGenBuffers.\n");
1725 #endif
1726    glGenBuffers(n, buffers);
1727 }
1728
1729 /*
1730  * Category: Shaders
1731  *
1732  * Core in:
1733  * OpenGL    : 2.0
1734  */
1735 void rglUniform1f(GLint location, GLfloat v0)
1736 {
1737 #ifdef GLSM_DEBUG
1738    log_cb(RETRO_LOG_INFO, "glUniform1f.\n");
1739 #endif
1740    glUniform1f(location, v0);
1741 }
1742
1743 /*
1744  * Category: Shaders
1745  *
1746  * Core in:
1747  * OpenGL    : 2.0
1748  */
1749 void rglUniform1fv(GLint location,  GLsizei count,  const GLfloat *value)
1750 {
1751 #ifdef GLSM_DEBUG
1752    log_cb(RETRO_LOG_INFO, "glUniform1fv.\n");
1753 #endif
1754    glUniform1fv(location, count, value);
1755 }
1756
1757 /*
1758  * Category: Shaders
1759  *
1760  * Core in:
1761  * OpenGL    : 2.0
1762  */
1763 void rglUniform1iv(GLint location,  GLsizei count,  const GLint *value)
1764 {
1765 #ifdef GLSM_DEBUG
1766    log_cb(RETRO_LOG_INFO, "glUniform1iv.\n");
1767 #endif
1768    glUniform1iv(location, count, value);
1769 }
1770
1771 void rglClearBufferfv(  GLenum buffer,
1772         GLint drawBuffer,
1773         const GLfloat * value)
1774 {
1775 #ifdef GLSM_DEBUG
1776    log_cb(RETRO_LOG_INFO, "glClearBufferfv.\n");
1777 #endif
1778 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3)
1779    glClearBufferfv(buffer, drawBuffer, value);
1780 #endif
1781 }
1782
1783 void rglTexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
1784 {
1785 #ifdef GLSM_DEBUG
1786    log_cb(RETRO_LOG_INFO, "glTexBuffer.\n");
1787 #endif
1788 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2)
1789    glTexBuffer(target, internalFormat, buffer);
1790 #endif
1791 }
1792
1793 /*
1794  *
1795  * Core in:
1796  * OpenGL    : 2.0
1797  * OpenGLES  : 3.0
1798  */
1799 const GLubyte* rglGetStringi(GLenum name, GLuint index)
1800 {
1801 #ifdef GLSM_DEBUG
1802    log_cb(RETRO_LOG_INFO, "glGetString.\n");
1803 #endif
1804 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3)
1805    return glGetStringi(name, index);
1806 #else
1807    return NULL;
1808 #endif
1809 }
1810
1811 void rglClearBufferfi(  GLenum buffer,
1812         GLint drawBuffer,
1813         GLfloat depth,
1814         GLint stencil)
1815 {
1816 #ifdef GLSM_DEBUG
1817    log_cb(RETRO_LOG_INFO, "glClearBufferfi.\n");
1818 #endif
1819 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3)
1820    glClearBufferfi(buffer, drawBuffer, depth, stencil);
1821 #endif
1822 }
1823
1824 /*
1825  *
1826  * Core in:
1827  * OpenGL    : 3.0
1828  * OpenGLES  : 3.0
1829  */
1830 void rglRenderbufferStorageMultisample(         GLenum target,
1831         GLsizei samples,
1832         GLenum internalformat,
1833         GLsizei width,
1834         GLsizei height)
1835 {
1836 #ifdef GLSM_DEBUG
1837    log_cb(RETRO_LOG_INFO, "glRenderbufferStorageMultisample.\n");
1838 #endif
1839 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3)
1840    glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
1841 #endif
1842 }
1843
1844 /*
1845  * Category: Shaders
1846  *
1847  * Core in:
1848  * OpenGL    : 2.0
1849  */
1850 void rglUniform1i(GLint location, GLint v0)
1851 {
1852 #ifdef GLSM_DEBUG
1853    log_cb(RETRO_LOG_INFO, "glUniform1i.\n");
1854 #endif
1855    glUniform1i(location, v0);
1856 }
1857
1858 /*
1859  * Category: Shaders
1860  *
1861  * Core in:
1862  * OpenGL    : 2.0
1863  */
1864 void rglUniform2f(GLint location, GLfloat v0, GLfloat v1)
1865 {
1866 #ifdef GLSM_DEBUG
1867    log_cb(RETRO_LOG_INFO, "glUniform2f.\n");
1868 #endif
1869    glUniform2f(location, v0, v1);
1870 }
1871
1872 /*
1873  * Category: Shaders
1874  *
1875  * Core in:
1876  * OpenGL    : 2.0
1877  */
1878 void rglUniform2i(GLint location, GLint v0, GLint v1)
1879 {
1880 #ifdef GLSM_DEBUG
1881    log_cb(RETRO_LOG_INFO, "glUniform2i.\n");
1882 #endif
1883    glUniform2i(location, v0, v1);
1884 }
1885
1886 /*
1887  * Category: Shaders
1888  *
1889  * Core in:
1890  * OpenGL    : 2.0
1891  */
1892 void rglUniform2fv(GLint location, GLsizei count, const GLfloat *value)
1893 {
1894 #ifdef GLSM_DEBUG
1895    log_cb(RETRO_LOG_INFO, "glUniform2fv.\n");
1896 #endif
1897    glUniform2fv(location, count, value);
1898 }
1899
1900 /*
1901  * Category: Shaders
1902  *
1903  * Core in:
1904  * OpenGL    : 2.0
1905  */
1906 void rglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
1907 {
1908 #ifdef GLSM_DEBUG
1909    log_cb(RETRO_LOG_INFO, "glUniform3f.\n");
1910 #endif
1911    glUniform3f(location, v0, v1, v2);
1912 }
1913
1914 /*
1915  * Category: Shaders
1916  *
1917  * Core in:
1918  * OpenGL    : 2.0
1919  */
1920 void rglUniform3fv(GLint location, GLsizei count, const GLfloat *value)
1921 {
1922 #ifdef GLSM_DEBUG
1923    log_cb(RETRO_LOG_INFO, "glUniform3fv.\n");
1924 #endif
1925    glUniform3fv(location, count, value);
1926 }
1927
1928 /*
1929  * Category: Shaders
1930  *
1931  * Core in:
1932  * OpenGL    : 2.0
1933  */
1934 void rglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
1935 {
1936 #ifdef GLSM_DEBUG
1937    log_cb(RETRO_LOG_INFO, "glUniform4i.\n");
1938 #endif
1939    glUniform4i(location, v0, v1, v2, v3);
1940 }
1941
1942 /*
1943  * Category: Shaders
1944  *
1945  * Core in:
1946  * OpenGL    : 2.0
1947  */
1948 void rglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
1949 {
1950 #ifdef GLSM_DEBUG
1951    log_cb(RETRO_LOG_INFO, "glUniform4f.\n");
1952 #endif
1953    glUniform4f(location, v0, v1, v2, v3);
1954 }
1955
1956 /*
1957  * Category: Shaders
1958  *
1959  * Core in:
1960  * OpenGL    : 2.0
1961  */
1962 void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value)
1963 {
1964 #ifdef GLSM_DEBUG
1965    log_cb(RETRO_LOG_INFO, "glUniform4fv.\n");
1966 #endif
1967    glUniform4fv(location, count, value);
1968 }
1969
1970 /*
1971  *
1972  * Core in:
1973  * OpenGL    : 1.0
1974  */
1975 void rglPolygonOffset(GLfloat factor, GLfloat units)
1976 {
1977 #ifdef GLSM_DEBUG
1978    log_cb(RETRO_LOG_INFO, "glPolygonOffset.\n");
1979 #endif
1980    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
1981    glPolygonOffset(factor, units);
1982    gl_state.polygonoffset.used   = true;
1983    gl_state.polygonoffset.factor = factor;
1984    gl_state.polygonoffset.units  = units;
1985 }
1986
1987 /*
1988  * Category: FBO
1989  *
1990  * Core in:
1991  * OpenGL    : 3.0
1992  */
1993 void rglGenFramebuffers(GLsizei n, GLuint *ids)
1994 {
1995 #ifdef GLSM_DEBUG
1996    log_cb(RETRO_LOG_INFO, "glGenFramebuffers.\n");
1997 #endif
1998    glGenFramebuffers(n, ids);
1999 }
2000
2001 /*
2002  * Category: FBO
2003  *
2004  * Core in:
2005  * OpenGL    : 3.0
2006  */
2007 void rglBindFramebuffer(GLenum target, GLuint framebuffer)
2008 {
2009 #ifdef GLSM_DEBUG
2010    log_cb(RETRO_LOG_INFO, "glBindFramebuffer.\n");
2011 #endif
2012    glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
2013    glBindFramebuffer(target, framebuffer);
2014    gl_state.framebuf = framebuffer;
2015 }
2016
2017 /*
2018  * Category: FBO
2019  *
2020  * Core in:
2021  * OpenGL    : 2.0
2022  * OpenGLES  : 3.0
2023  */
2024 void rglDrawBuffers(GLsizei n, const GLenum *bufs)
2025 {
2026 #ifdef GLSM_DEBUG
2027    log_cb(RETRO_LOG_INFO, "glDrawBuffers.\n");
2028 #endif
2029 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2030    glDrawBuffers(n, bufs);
2031 #endif
2032 }
2033
2034 /*
2035  * Category: FBO
2036  *
2037  * Core in:
2038  * OpenGL    : 2.0
2039  * OpenGLES  : 3.0
2040  */
2041 void *rglMapBufferRange(        GLenum target,
2042         GLintptr offset,
2043         GLsizeiptr length,
2044         GLbitfield access)
2045 {
2046 #ifdef GLSM_DEBUG
2047    log_cb(RETRO_LOG_INFO, "glMapBufferRange.\n");
2048 #endif
2049 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2050    return glMapBufferRange(target, offset, length, access);
2051 #else
2052    printf("WARNING! Not implemented.\n");
2053    return NULL;
2054 #endif
2055 }
2056
2057 /*
2058  *
2059  * Core in:
2060  * OpenGL    : 4.3
2061  * OpenGLES  : 3.1
2062  */
2063 void rglTexStorage2DMultisample(GLenum target, GLsizei samples,
2064       GLenum internalformat, GLsizei width, GLsizei height,
2065       GLboolean fixedsamplelocations)
2066 {
2067 #ifdef GLSM_DEBUG
2068    log_cb(RETRO_LOG_INFO, "glTexStorage2DMultisample.\n");
2069 #endif
2070 #if defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1)
2071    glTexStorage2DMultisample(target, samples, internalformat,
2072          width, height, fixedsamplelocations);
2073 #endif
2074 }
2075
2076 /*
2077  *
2078  * Core in:
2079  * OpenGLES  : 3.0
2080  */
2081 void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
2082       GLsizei width, GLsizei height)
2083 {
2084 #ifdef GLSM_DEBUG
2085    log_cb(RETRO_LOG_INFO, "glTexStorage2D.\n");
2086 #endif
2087 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2088    glTexStorage2D(target, levels, internalFormat, width, height);
2089 #endif
2090 }
2091 /*
2092  *
2093  * Core in:
2094  * OpenGL    : 3.2
2095  * OpenGLES  : 3.2
2096  */
2097 void rglDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLvoid *indices, GLint basevertex)
2098 {
2099 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2)
2100    glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex);
2101 #endif
2102 }
2103
2104 /*
2105  *
2106  * Core in:
2107  * OpenGL    : 4.2
2108  * OpenGLES  : 3.1
2109  */
2110 void rglMemoryBarrier(  GLbitfield barriers)
2111 {
2112 #ifdef GLSM_DEBUG
2113    log_cb(RETRO_LOG_INFO, "glMemoryBarrier.\n");
2114 #endif
2115 #if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1)
2116    glMemoryBarrier(barriers);
2117 #else
2118    printf("WARNING! Not implemented.\n");
2119 #endif
2120 }
2121
2122 /*
2123  *
2124  * Core in:
2125  * OpenGL    : 4.2
2126  * OpenGLES  : 3.1
2127  */
2128 void rglBindImageTexture(       GLuint unit,
2129         GLuint texture,
2130         GLint level,
2131         GLboolean layered,
2132         GLint layer,
2133         GLenum access,
2134         GLenum format)
2135 {
2136 #ifdef GLSM_DEBUG
2137    log_cb(RETRO_LOG_INFO, "glBindImageTexture.\n");
2138 #endif
2139 #if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1)
2140    glBindImageTexture(unit, texture, level, layered, layer, access, format);
2141 #else
2142    printf("WARNING! Not implemented.\n");
2143 #endif
2144 }
2145
2146 /*
2147  *
2148  * Core in:
2149  * OpenGL    : 4.1
2150  * OpenGLES  : 3.1
2151  */
2152 void rglGetProgramBinary(       GLuint program,
2153         GLsizei bufsize,
2154         GLsizei *length,
2155         GLenum *binaryFormat,
2156         void *binary)
2157 {
2158 #ifdef GLSM_DEBUG
2159    log_cb(RETRO_LOG_INFO, "glGetProgramBinary.\n");
2160 #endif
2161 #if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2162    glGetProgramBinary(program, bufsize, length, binaryFormat, binary);
2163 #else
2164    printf("WARNING! Not implemented.\n");
2165 #endif
2166 }
2167
2168 /*
2169  *
2170  * Core in:
2171  * OpenGL    : 4.1
2172  * OpenGLES  : 3.1
2173  */
2174 void rglProgramBinary(GLuint program,
2175         GLenum binaryFormat,
2176         const void *binary,
2177         GLsizei length)
2178 {
2179 #ifdef GLSM_DEBUG
2180    log_cb(RETRO_LOG_INFO, "glProgramBinary.\n");
2181 #endif
2182 #if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1)
2183    glProgramBinary(program, binaryFormat, binary, length);
2184 #else
2185    printf("WARNING! Not implemented.\n");
2186 #endif
2187 }
2188
2189 void rglTexImage2DMultisample(  GLenum target,
2190         GLsizei samples,
2191         GLenum internalformat,
2192         GLsizei width,
2193         GLsizei height,
2194         GLboolean fixedsamplelocations)
2195 {
2196 #ifdef GLSM_DEBUG
2197    log_cb(RETRO_LOG_INFO, "glTexImage2DMultisample.\n");
2198 #endif
2199 #ifndef HAVE_OPENGLES
2200    glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
2201 #endif
2202 }
2203
2204 void rglTexImage3D(     GLenum target,
2205         GLint level,
2206         GLint internalFormat,
2207         GLsizei width,
2208         GLsizei height,
2209         GLsizei depth,
2210         GLint border,
2211         GLenum format,
2212         GLenum type,
2213         const GLvoid * data)
2214 {
2215 #ifdef GLSM_DEBUG
2216    log_cb(RETRO_LOG_INFO, "glTexImage3D.\n");
2217 #endif
2218 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2219    glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
2220 #endif
2221 }
2222
2223 /*
2224  *
2225  * Core in:
2226  * OpenGL    : 1.5
2227  */
2228 void * rglMapBuffer(    GLenum target, GLenum access)
2229 {
2230 #ifdef GLSM_DEBUG
2231    log_cb(RETRO_LOG_INFO, "glMapBuffer.\n");
2232 #endif
2233 #if defined(HAVE_OPENGLES)
2234    return glMapBufferOES(target, access);
2235 #else
2236    return glMapBuffer(target, access);
2237 #endif
2238 }
2239
2240 /*
2241  *
2242  * Core in:
2243  * OpenGL    : 1.5
2244  */
2245 GLboolean rglUnmapBuffer(       GLenum target)
2246 {
2247 #ifdef GLSM_DEBUG
2248    log_cb(RETRO_LOG_INFO, "glUnmapBuffer.\n");
2249 #endif
2250 #if defined(HAVE_OPENGLES)
2251    return glUnmapBufferOES(target);
2252 #else
2253    return glUnmapBuffer(target);
2254 #endif
2255 }
2256
2257 void rglBlendEquation(GLenum mode)
2258 {
2259 #ifdef GLSM_DEBUG
2260    log_cb(RETRO_LOG_INFO, "glBlendEquation.\n");
2261 #endif
2262    glBlendEquation(mode);
2263 }
2264
2265 void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
2266 {
2267 #ifdef GLSM_DEBUG
2268    log_cb(RETRO_LOG_INFO, "glBlendColor.\n");
2269 #endif
2270    glBlendColor(red, green, blue, alpha);
2271 }
2272
2273 /*
2274  * Category: Blending
2275  *
2276  * Core in:
2277  * OpenGL    : 2.0
2278  */
2279 void rglBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2280 {
2281 #ifdef GLSM_DEBUG
2282    log_cb(RETRO_LOG_INFO, "glBlendEquationSeparate.\n");
2283 #endif
2284    glBlendEquationSeparate(modeRGB, modeAlpha);
2285 }
2286
2287 /*
2288  *
2289  * Core in:
2290  * OpenGL    : 2.0
2291  * OpenGLES  : 3.2
2292  */
2293 void rglCopyImageSubData(       GLuint srcName,
2294         GLenum srcTarget,
2295         GLint srcLevel,
2296         GLint srcX,
2297         GLint srcY,
2298         GLint srcZ,
2299         GLuint dstName,
2300         GLenum dstTarget,
2301         GLint dstLevel,
2302         GLint dstX,
2303         GLint dstY,
2304         GLint dstZ,
2305         GLsizei srcWidth,
2306         GLsizei srcHeight,
2307         GLsizei srcDepth)
2308 {
2309 #ifdef GLSM_DEBUG
2310    log_cb(RETRO_LOG_INFO, "glCopyImageSubData.\n");
2311 #endif
2312 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2)
2313    glCopyImageSubData(srcName,
2314          srcTarget,
2315          srcLevel,
2316          srcX,
2317          srcY,
2318          srcZ,
2319          dstName,
2320          dstTarget,
2321          dstLevel,
2322          dstX,
2323          dstY,
2324          dstZ,
2325          srcWidth,
2326          srcHeight,
2327          srcDepth);
2328 #endif
2329 }
2330
2331 /*
2332  * Category: VAO
2333  *
2334  * Core in:
2335  * OpenGL    : 3.0
2336  * OpenGLES  : 3.0
2337  */
2338 void rglBindVertexArray(GLuint array)
2339 {
2340 #ifdef GLSM_DEBUG
2341    log_cb(RETRO_LOG_INFO, "glBindVertexArray.\n");
2342 #endif
2343 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2344    glBindVertexArray(array);
2345 #endif
2346 }
2347
2348 /*
2349  * Category: VAO
2350  *
2351  * Core in:
2352  * OpenGL    : 3.0
2353  * OpenGLES  : 3.0
2354  */
2355 void rglGenVertexArrays(GLsizei n, GLuint *arrays)
2356 {
2357 #ifdef GLSM_DEBUG
2358    log_cb(RETRO_LOG_INFO, "glGenVertexArrays.\n");
2359 #endif
2360 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2361    glGenVertexArrays(n, arrays);
2362 #endif
2363 }
2364
2365 /*
2366  * Category: VAO
2367  *
2368  * Core in:
2369  * OpenGL    : 3.0
2370  * OpenGLES  : 3.0
2371  */
2372 void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays)
2373 {
2374 #ifdef GLSM_DEBUG
2375    log_cb(RETRO_LOG_INFO, "glDeleteVertexArrays.\n");
2376 #endif
2377 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2378    glDeleteVertexArrays(n, arrays);
2379 #endif
2380 }
2381
2382 /*
2383  *
2384  * Core in:
2385  * OpenGL    : 3.2
2386  * OpenGLES  : 3.0
2387  */
2388 void *rglFenceSync(GLenum condition, GLbitfield flags)
2389 {
2390 #ifdef GLSM_DEBUG
2391    log_cb(RETRO_LOG_INFO, "glFenceSync.\n");
2392 #endif
2393 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2394    return (GLsync)glFenceSync(condition, flags);
2395 #else
2396    return NULL;
2397 #endif
2398 }
2399
2400 /*
2401  *
2402  * Core in:
2403  * OpenGL    : 3.2
2404  * OpenGLES  : 3.0
2405  */
2406 void rglDeleteSync(void * sync)
2407 {
2408 #ifdef GLSM_DEBUG
2409    log_cb(RETRO_LOG_INFO, "glDeleteSync.\n");
2410 #endif
2411 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2412   glDeleteSync((GLsync)sync);
2413 #endif
2414 }
2415
2416 /*
2417  *
2418  * Core in:
2419  * OpenGL    : 3.2
2420  * OpenGLES  : 3.0
2421  */
2422 void rglWaitSync(void *sync, GLbitfield flags, uint64_t timeout)
2423 {
2424 #ifdef GLSM_DEBUG
2425    log_cb(RETRO_LOG_INFO, "glWaitSync.\n");
2426 #endif
2427 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2428    glWaitSync((GLsync)sync, flags, (GLuint64)timeout);
2429 #endif
2430 }
2431
2432 /*
2433  *
2434  * Core in:
2435  * OpenGL    : 4.4
2436  * OpenGLES  : Not available
2437  */
2438 void rglBufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags)
2439 {
2440 #ifdef GLSM_DEBUG
2441    log_cb(RETRO_LOG_INFO, "glBufferStorage.\n");
2442 #endif
2443 #if defined(HAVE_OPENGL)
2444    glBufferStorage(target, size, data, flags);
2445 #endif
2446 }
2447
2448 /*
2449  *
2450  * Core in:
2451  * OpenGL    : 2.0
2452  * OpenGLES  : 2.0
2453  */
2454
2455 void rglUniform2iv(     GLint location,
2456         GLsizei count,
2457         const GLint *value)
2458 {
2459 #ifdef GLSM_DEBUG
2460    log_cb(RETRO_LOG_INFO, "glUniform2iv.\n");
2461 #endif
2462    glUniform2iv(location, count, value);
2463 }
2464
2465 /*
2466  *
2467  * Core in:
2468  * OpenGL    : 3.0
2469  * OpenGLES  : ?.?
2470  */
2471
2472 void rglUniform2uiv(    GLint location,
2473         GLsizei count,
2474         const GLuint *value)
2475 {
2476 #ifdef GLSM_DEBUG
2477    log_cb(RETRO_LOG_INFO, "glUniform2uiv.\n");
2478 #endif
2479 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2480    glUniform2uiv(location, count, value);
2481 #endif
2482 }
2483
2484 /*
2485  *
2486  * Core in:
2487  * OpenGL    : 4.3
2488  * OpenGLES  : ?.?
2489  */
2490 void rglTextureView(    GLuint texture,
2491         GLenum target,
2492         GLuint origtexture,
2493         GLenum internalformat,
2494         GLuint minlevel,
2495         GLuint numlevels,
2496         GLuint minlayer,
2497         GLuint numlayers)
2498 {
2499 #ifdef GLSM_DEBUG
2500    log_cb(RETRO_LOG_INFO, "glTextureView.\n");
2501 #endif
2502 #if defined(HAVE_OPENGL)
2503    glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
2504 #endif
2505 }
2506
2507 /*
2508  *
2509  * Core in:
2510  * OpenGL    : 3.0
2511  * OpenGLES  : 3.0
2512  */
2513 void rglFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
2514 {
2515 #ifdef GLSM_DEBUG
2516    log_cb(RETRO_LOG_INFO, "glFlushMappedBufferRange.\n");
2517 #endif
2518 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2519   glFlushMappedBufferRange(target, offset, length);
2520 #endif
2521 }
2522
2523 #ifndef GL_WAIT_FAILED
2524 #define GL_WAIT_FAILED                                   0x911D
2525 #endif
2526
2527 /*
2528  *
2529  * Core in:
2530  * OpenGL    : 3.2
2531  * OpenGLES  : 3.0
2532  */
2533 GLenum rglClientWaitSync(void *sync, GLbitfield flags, uint64_t timeout)
2534 {
2535 #ifdef GLSM_DEBUG
2536    log_cb(RETRO_LOG_INFO, "glClientWaitSync.\n");
2537 #endif
2538 #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3)
2539   return glClientWaitSync((GLsync)sync, flags, (GLuint64)timeout);
2540 #else
2541   return GL_WAIT_FAILED;
2542 #endif
2543 }
2544
2545 /*
2546  *
2547  * Core in:
2548  * OpenGL    : 3.2
2549  * OpenGLES  : Not available
2550  */
2551 void rglDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
2552                                GLvoid *indices, GLint basevertex)
2553 {
2554 #ifdef GLSM_DEBUG
2555    log_cb(RETRO_LOG_INFO, "glDrawElementsBaseVertex.\n");
2556 #endif
2557 #if defined(HAVE_OPENGL)
2558    glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
2559 #endif
2560 }
2561
2562 /* GLSM-side */
2563
2564 static void glsm_state_setup(void)
2565 {
2566    unsigned i;
2567
2568    gl_state.cap_translate[SGL_DEPTH_TEST]           = GL_DEPTH_TEST;
2569    gl_state.cap_translate[SGL_BLEND]                = GL_BLEND;
2570    gl_state.cap_translate[SGL_POLYGON_OFFSET_FILL]  = GL_POLYGON_OFFSET_FILL;
2571    gl_state.cap_translate[SGL_FOG]                  = GL_FOG;
2572    gl_state.cap_translate[SGL_CULL_FACE]            = GL_CULL_FACE;
2573    gl_state.cap_translate[SGL_ALPHA_TEST]           = GL_ALPHA_TEST;
2574    gl_state.cap_translate[SGL_SCISSOR_TEST]         = GL_SCISSOR_TEST;
2575    gl_state.cap_translate[SGL_STENCIL_TEST]         = GL_STENCIL_TEST;
2576
2577 #ifndef HAVE_OPENGLES
2578    gl_state.cap_translate[SGL_COLOR_LOGIC_OP]       = GL_COLOR_LOGIC_OP;
2579    gl_state.cap_translate[SGL_CLIP_DISTANCE0]       = GL_CLIP_DISTANCE0;
2580    gl_state.cap_translate[SGL_DEPTH_CLAMP]          = GL_DEPTH_CLAMP;
2581 #endif
2582
2583    for (i = 0; i < MAX_ATTRIB; i++)
2584    {
2585       gl_state.vertex_attrib_pointer.enabled[i] = 0;
2586       gl_state.attrib_pointer.used[i] = 0;
2587    }
2588
2589    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &glsm_max_textures);
2590
2591    gl_state.bind_textures.ids           = (GLuint*)calloc(glsm_max_textures, sizeof(GLuint));
2592
2593    default_framebuffer                  = glsm_get_current_framebuffer();
2594    gl_state.framebuf                    = default_framebuffer;
2595    gl_state.cullface.mode               = GL_BACK;
2596    gl_state.frontface.mode              = GL_CCW;
2597
2598    gl_state.blendfunc_separate.used     = false;
2599    gl_state.blendfunc_separate.srcRGB   = GL_ONE;
2600    gl_state.blendfunc_separate.dstRGB   = GL_ZERO;
2601    gl_state.blendfunc_separate.srcAlpha = GL_ONE;
2602    gl_state.blendfunc_separate.dstAlpha = GL_ZERO;
2603
2604    gl_state.depthfunc.used              = false;
2605
2606    gl_state.colormask.used              = false;
2607    gl_state.colormask.red               = GL_TRUE;
2608    gl_state.colormask.green             = GL_TRUE;
2609    gl_state.colormask.blue              = GL_TRUE;
2610    gl_state.colormask.alpha             = GL_TRUE;
2611
2612    gl_state.polygonoffset.used          = false;
2613
2614    gl_state.depthfunc.func              = GL_LESS;
2615
2616 #ifndef HAVE_OPENGLES
2617    gl_state.colorlogicop                = GL_COPY;
2618 #endif
2619
2620 #ifdef CORE
2621    glGenVertexArrays(1, &gl_state.vao);
2622 #endif
2623 }
2624
2625 static void glsm_state_bind(void)
2626 {
2627    unsigned i;
2628 #ifdef CORE
2629    glBindVertexArray(gl_state.vao);
2630 #endif
2631    glBindBuffer(GL_ARRAY_BUFFER, gl_state.array_buffer);
2632
2633    for (i = 0; i < MAX_ATTRIB; i++)
2634    {
2635       if (gl_state.vertex_attrib_pointer.enabled[i])
2636          glEnableVertexAttribArray(i);
2637       else
2638          glDisableVertexAttribArray(i);
2639
2640       if (gl_state.attrib_pointer.used[i] && gl_state.attrib_pointer.buffer[i] == gl_state.array_buffer)
2641       {
2642          glVertexAttribPointer(
2643                i,
2644                gl_state.attrib_pointer.size[i],
2645                gl_state.attrib_pointer.type[i],
2646                gl_state.attrib_pointer.normalized[i],
2647                gl_state.attrib_pointer.stride[i],
2648                gl_state.attrib_pointer.pointer[i]);
2649       }
2650    }
2651
2652    glBindFramebuffer(RARCH_GL_FRAMEBUFFER, default_framebuffer);
2653
2654    if (gl_state.blendfunc.used)
2655       glBlendFunc(
2656             gl_state.blendfunc.sfactor,
2657             gl_state.blendfunc.dfactor);
2658
2659    if (gl_state.blendfunc_separate.used)
2660       glBlendFuncSeparate(
2661             gl_state.blendfunc_separate.srcRGB,
2662             gl_state.blendfunc_separate.dstRGB,
2663             gl_state.blendfunc_separate.srcAlpha,
2664             gl_state.blendfunc_separate.dstAlpha
2665             );
2666
2667    glClearColor(
2668          gl_state.clear_color.r,
2669          gl_state.clear_color.g,
2670          gl_state.clear_color.b,
2671          gl_state.clear_color.a);
2672
2673    if (gl_state.depthfunc.used)
2674       glDepthFunc(gl_state.depthfunc.func);
2675
2676    if (gl_state.colormask.used)
2677       glColorMask(
2678             gl_state.colormask.red,
2679             gl_state.colormask.green,
2680             gl_state.colormask.blue,
2681             gl_state.colormask.alpha);
2682
2683    if (gl_state.cullface.used)
2684       glCullFace(gl_state.cullface.mode);
2685
2686    if (gl_state.depthmask.used)
2687       glDepthMask(gl_state.depthmask.mask);
2688
2689    if (gl_state.polygonoffset.used)
2690       glPolygonOffset(
2691             gl_state.polygonoffset.factor,
2692             gl_state.polygonoffset.units);
2693
2694    if (gl_state.scissor.used)
2695       glScissor(
2696             gl_state.scissor.x,
2697             gl_state.scissor.y,
2698             gl_state.scissor.w,
2699             gl_state.scissor.h);
2700
2701    glUseProgram(gl_state.program);
2702
2703    glViewport(
2704          gl_state.viewport.x,
2705          gl_state.viewport.y,
2706          gl_state.viewport.w,
2707          gl_state.viewport.h);
2708
2709    for(i = 0; i < SGL_CAP_MAX; i ++)
2710    {
2711       if (gl_state.cap_state[i])
2712          glEnable(gl_state.cap_translate[i]);
2713    }
2714
2715    if (gl_state.frontface.used)
2716       glFrontFace(gl_state.frontface.mode);
2717
2718    if (gl_state.stencilmask.used)
2719       glStencilMask(gl_state.stencilmask.mask);
2720
2721    if (gl_state.stencilop.used)
2722       glStencilOp(gl_state.stencilop.sfail,
2723             gl_state.stencilop.dpfail,
2724             gl_state.stencilop.dppass);
2725
2726    if (gl_state.stencilfunc.used)
2727       glStencilFunc(
2728             gl_state.stencilfunc.func,
2729             gl_state.stencilfunc.ref,
2730             gl_state.stencilfunc.mask);
2731
2732    for (i = 0; i < glsm_max_textures; i ++)
2733    {
2734       glActiveTexture(GL_TEXTURE0 + i);
2735       glBindTexture(GL_TEXTURE_2D, gl_state.bind_textures.ids[i]);
2736    }
2737
2738    glActiveTexture(GL_TEXTURE0 + gl_state.active_texture);
2739 }
2740
2741 static void glsm_state_unbind(void)
2742 {
2743    unsigned i;
2744 #ifdef CORE
2745    glBindVertexArray(0);
2746 #endif
2747    for (i = 0; i < SGL_CAP_MAX; i ++)
2748    {
2749       if (gl_state.cap_state[i])
2750          glDisable(gl_state.cap_translate[i]);
2751    }
2752
2753    glBlendFunc(GL_ONE, GL_ZERO);
2754
2755    if (gl_state.colormask.used)
2756       glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2757    if (gl_state.blendfunc_separate.used)
2758       glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
2759
2760    if (gl_state.cullface.used)
2761       glCullFace(GL_BACK);
2762
2763    if (gl_state.depthmask.used)
2764       glDepthMask(GL_TRUE);
2765
2766    if (gl_state.polygonoffset.used)
2767       glPolygonOffset(0, 0);
2768
2769    glUseProgram(0);
2770    glClearColor(0,0,0,0.0f);
2771
2772    if (gl_state.depthrange.used)
2773       rglDepthRange(0, 1);
2774
2775    glStencilMask(1);
2776    glFrontFace(GL_CCW);
2777    if (gl_state.depthfunc.used)
2778       glDepthFunc(GL_LESS);
2779
2780    if (gl_state.stencilop.used)
2781       glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);
2782
2783    if (gl_state.stencilfunc.used)
2784       glStencilFunc(GL_ALWAYS,0,1);
2785
2786    /* Clear textures */
2787    for (i = 0; i < glsm_max_textures; i ++)
2788    {
2789       glActiveTexture(GL_TEXTURE0 + i);
2790       glBindTexture(GL_TEXTURE_2D, 0);
2791    }
2792    glActiveTexture(GL_TEXTURE0);
2793
2794    for (i = 0; i < MAX_ATTRIB; i ++)
2795       glDisableVertexAttribArray(i);
2796
2797    glBindFramebuffer(RARCH_GL_FRAMEBUFFER, 0);
2798 }
2799
2800 static bool glsm_state_ctx_destroy(void *data)
2801 {
2802    if (gl_state.bind_textures.ids)
2803       free(gl_state.bind_textures.ids);
2804    gl_state.bind_textures.ids = NULL;
2805
2806    return true;
2807 }
2808
2809 static bool glsm_state_ctx_init(glsm_ctx_params_t *params)
2810 {
2811    if (!params || !params->environ_cb)
2812       return false;
2813
2814 #ifdef HAVE_OPENGLES
2815 #if defined(HAVE_OPENGLES_3_1)
2816    hw_render.context_type       = RETRO_HW_CONTEXT_OPENGLES_VERSION;
2817    hw_render.version_major      = 3;
2818    hw_render.version_minor      = 1;
2819 #elif defined(HAVE_OPENGLES3)
2820    hw_render.context_type       = RETRO_HW_CONTEXT_OPENGLES3;
2821 #else
2822    hw_render.context_type       = RETRO_HW_CONTEXT_OPENGLES2;
2823 #endif
2824 #else
2825    hw_render.context_type       = RETRO_HW_CONTEXT_OPENGL;
2826    if (params->context_type != RETRO_HW_CONTEXT_NONE)
2827       hw_render.context_type    = params->context_type;
2828    if (params->major != 0)
2829       hw_render.version_major   = params->major;
2830    if (params->minor != 0)
2831       hw_render.version_minor   = params->minor;
2832 #endif
2833
2834    hw_render.context_reset      = params->context_reset;
2835    hw_render.context_destroy    = params->context_destroy;
2836    hw_render.stencil            = params->stencil;
2837    hw_render.depth              = true;
2838    hw_render.bottom_left_origin = true;
2839    hw_render.cache_context      = false;
2840
2841    if (!params->environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
2842       return false;
2843
2844    return true;
2845 }
2846
2847 GLuint glsm_get_current_framebuffer(void)
2848 {
2849    return hw_render.get_current_framebuffer();
2850 }
2851
2852 bool glsm_ctl(enum glsm_state_ctl state, void *data)
2853 {
2854    switch (state)
2855    {
2856       case GLSM_CTL_IMM_VBO_DRAW:
2857          return false;
2858       case GLSM_CTL_IMM_VBO_DISABLE:
2859          return false;
2860       case GLSM_CTL_IS_IMM_VBO:
2861          return false;
2862       case GLSM_CTL_SET_IMM_VBO:
2863          break;
2864       case GLSM_CTL_UNSET_IMM_VBO:
2865          break;
2866       case GLSM_CTL_PROC_ADDRESS_GET:
2867          {
2868             glsm_ctx_proc_address_t *proc = (glsm_ctx_proc_address_t*)data;
2869             if (!hw_render.get_proc_address)
2870                return false;
2871             proc->addr = hw_render.get_proc_address;
2872          }
2873          break;
2874       case GLSM_CTL_STATE_CONTEXT_RESET:
2875          rglgen_resolve_symbols(hw_render.get_proc_address);
2876          break;
2877       case GLSM_CTL_STATE_CONTEXT_DESTROY:
2878          glsm_state_ctx_destroy(data);
2879          break;
2880       case GLSM_CTL_STATE_CONTEXT_INIT:
2881          return glsm_state_ctx_init((glsm_ctx_params_t*)data);
2882       case GLSM_CTL_STATE_SETUP:
2883          glsm_state_setup();
2884          break;
2885       case GLSM_CTL_STATE_UNBIND:
2886          glsm_state_unbind();
2887          break;
2888       case GLSM_CTL_STATE_BIND:
2889          glsm_state_bind();
2890          break;
2891       case GLSM_CTL_NONE:
2892       default:
2893          break;
2894    }
2895
2896    return true;
2897 }