X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flibretro-common%2Fglsm%2Fglsm.c;fp=deps%2Flibretro-common%2Fglsm%2Fglsm.c;h=8b08c575a6028472fa8c658a5d971e123cab5f0c;hb=3719602cbe883fb394a71353e20a10a4a306e814;hp=0000000000000000000000000000000000000000;hpb=8659d7fd2cdb11f63724ead0997f47f4c694f8c2;p=pcsx_rearmed.git diff --git a/deps/libretro-common/glsm/glsm.c b/deps/libretro-common/glsm/glsm.c new file mode 100644 index 00000000..8b08c575 --- /dev/null +++ b/deps/libretro-common/glsm/glsm.c @@ -0,0 +1,2897 @@ +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro SDK code part (glsm). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#ifndef GL_DEPTH_CLAMP +#define GL_DEPTH_CLAMP 0x864F +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_SAMPLE_MASK 0x8E51 +#endif + +#if 0 +extern retro_log_printf_t log_cb; +#define GLSM_DEBUG +#endif + +struct gl_cached_state +{ + struct + { + GLuint *ids; + } bind_textures; + + struct + { + bool used[MAX_ATTRIB]; + GLint size[MAX_ATTRIB]; + GLenum type[MAX_ATTRIB]; + GLboolean normalized[MAX_ATTRIB]; + GLsizei stride[MAX_ATTRIB]; + const GLvoid *pointer[MAX_ATTRIB]; + GLuint buffer[MAX_ATTRIB]; + } attrib_pointer; + +#ifndef HAVE_OPENGLES + GLenum colorlogicop; +#endif + + struct + { + bool enabled[MAX_ATTRIB]; + } vertex_attrib_pointer; + + struct + { + GLenum pname; + GLint param; + } pixelstore_i; + + struct + { + GLuint r; + GLuint g; + GLuint b; + GLuint a; + } clear_color; + + struct + { + bool used; + GLint x; + GLint y; + GLsizei w; + GLsizei h; + } scissor; + + struct + { + GLint x; + GLint y; + GLsizei w; + GLsizei h; + } viewport; + + struct + { + bool used; + GLenum sfactor; + GLenum dfactor; + } blendfunc; + + struct + { + bool used; + GLenum srcRGB; + GLenum dstRGB; + GLenum srcAlpha; + GLenum dstAlpha; + } blendfunc_separate; + + struct + { + bool used; + GLboolean red; + GLboolean green; + GLboolean blue; + GLboolean alpha; + } colormask; + + struct + { + bool used; + GLdouble depth; + } cleardepth; + + struct + { + bool used; + GLenum func; + } depthfunc; + + struct + { + bool used; + GLclampd zNear; + GLclampd zFar; + } depthrange; + + struct + { + bool used; + GLfloat factor; + GLfloat units; + } polygonoffset; + + struct + { + bool used; + GLenum func; + GLint ref; + GLuint mask; + } stencilfunc; + + struct + { + bool used; + GLenum sfail; + GLenum dpfail; + GLenum dppass; + } stencilop; + + struct + { + bool used; + GLenum mode; + } frontface; + + struct + { + bool used; + GLenum mode; + } cullface; + + struct + { + bool used; + GLuint mask; + } stencilmask; + + struct + { + bool used; + GLboolean mask; + } depthmask; + + struct + { + GLenum mode; + } readbuffer; + + GLuint vao; + GLuint framebuf; + GLuint array_buffer; + GLuint program; + GLenum active_texture; + int cap_state[SGL_CAP_MAX]; + int cap_translate[SGL_CAP_MAX]; +}; + +static GLuint default_framebuffer; +static GLint glsm_max_textures; +struct retro_hw_render_callback hw_render; +static struct gl_cached_state gl_state; + +/* GL wrapper-side */ + +/* + * + * Core in: + * OpenGL : 1.0 + */ +GLenum rglGetError(void) +{ + return glGetError(); +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : N/A + */ + +void rglProvokingVertex( GLenum provokeMode) +{ +#if defined(HAVE_OPENGL) + glProvokingVertex(provokeMode); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglGetInteger64v( GLenum pname, int64_t *data) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetInteger64v(pname, (GLint64*)data); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglSamplerParameteri( GLuint sampler, + GLenum pname, + GLint param) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glSamplerParameteri(sampler, pname, param); +#endif +} + +void rglGenSamplers( GLsizei n, + GLuint *samplers) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenSamplers(n, samplers); +#endif +} + +void rglBindSampler( GLuint unit, + GLuint sampler) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindSampler(unit, sampler); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglClear(GLbitfield mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClear.\n"); +#endif + glClear(mask); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglValidateProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glValidateProgram.\n"); +#endif + glValidateProgram(program); +} + +/* + * + * Core in: + * OpenGL : 1.0 + * OpenGLES : N/A + */ +void rglPolygonMode(GLenum face, GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPolygonMode.\n"); +#endif +#ifndef HAVE_OPENGLES + glPolygonMode(face, mode); +#endif +} + +void rglTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid * pixels) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexSubImage2D.\n"); +#endif + glTexSubImage2D(target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + +void rglGetBufferSubData( GLenum target, + GLintptr offset, + GLsizeiptr size, + GLvoid * data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetBufferSubData.\n"); +#endif +#if defined(HAVE_OPENGL) + glGetBufferSubData(target, offset, size, data); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglLineWidth(GLfloat width) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glLineWidth.\n"); +#endif + glLineWidth(width); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglBlitFramebuffer( + GLint srcX0, GLint srcY0, + GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlitFramebuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); +#endif +} + +/* + * + * Core in: + * OpenGLES : 3.0 + */ +void rglReadBuffer(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glReadBuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glReadBuffer(mode); + gl_state.readbuffer.mode = mode; +#endif +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglClearDepth(GLdouble depth) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearDepth.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); +#ifdef HAVE_OPENGLES + glClearDepthf(depth); +#else + glClearDepth(depth); +#endif + gl_state.cleardepth.used = true; + gl_state.cleardepth.depth = depth; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglPixelStorei(GLenum pname, GLint param) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPixelStorei.\n"); +#endif + glPixelStorei(pname, param); + gl_state.pixelstore_i.pname = pname; + gl_state.pixelstore_i.param = param; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglDepthRange(GLclampd zNear, GLclampd zFar) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthRange.\n"); +#endif +#ifdef HAVE_OPENGLES + glDepthRangef(zNear, zFar); +#else + glDepthRange(zNear, zFar); +#endif + gl_state.depthrange.used = true; + gl_state.depthrange.zNear = zNear; + gl_state.depthrange.zFar = zFar; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglFrontFace(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFrontFace.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glFrontFace(mode); + gl_state.frontface.used = true; + gl_state.frontface.mode = mode; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglDepthFunc(GLenum func) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthFunc.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.depthfunc.used = true; + gl_state.depthfunc.func = func; + glDepthFunc(func); +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglColorMask(GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glColorMask.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glColorMask(red, green, blue, alpha); + gl_state.colormask.red = red; + gl_state.colormask.green = green; + gl_state.colormask.blue = blue; + gl_state.colormask.alpha = alpha; + gl_state.colormask.used = true; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglCullFace(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCullFace.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glCullFace(mode); + gl_state.cullface.used = true; + gl_state.cullface.mode = mode; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilOp.\n"); +#endif + glStencilOp(sfail, dpfail, dppass); + gl_state.stencilop.used = true; + gl_state.stencilop.sfail = sfail; + gl_state.stencilop.dpfail = dpfail; + gl_state.stencilop.dppass = dppass; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglStencilFunc(GLenum func, GLint ref, GLuint mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilFunc.\n"); +#endif + glStencilFunc(func, ref, mask); + gl_state.stencilfunc.used = true; + gl_state.stencilfunc.func = func; + gl_state.stencilfunc.ref = ref; + gl_state.stencilfunc.mask = mask; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +GLboolean rglIsEnabled(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glIsEnabled.\n"); +#endif + return gl_state.cap_state[cap] ? GL_TRUE : GL_FALSE; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglClearColor(GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearColor.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glClearColor(red, green, blue, alpha); + gl_state.clear_color.r = red; + gl_state.clear_color.g = green; + gl_state.clear_color.b = blue; + gl_state.clear_color.a = alpha; +} + +/* + * + * Core in: + * OpenGLES : 2.0 (maybe earlier?) + */ +void rglScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glScissor.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glScissor(x, y, width, height); + gl_state.scissor.used = true; + gl_state.scissor.x = x; + gl_state.scissor.y = y; + gl_state.scissor.w = width; + gl_state.scissor.h = height; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glViewport.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glViewport(x, y, width, height); + gl_state.viewport.x = x; + gl_state.viewport.y = y; + gl_state.viewport.w = width; + gl_state.viewport.h = height; +} + +void rglBlendFunc(GLenum sfactor, GLenum dfactor) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendFunc.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.blendfunc.used = true; + gl_state.blendfunc.sfactor = sfactor; + gl_state.blendfunc.dfactor = dfactor; + glBlendFunc(sfactor, dfactor); +} + +/* + * Category: Blending + * + * Core in: + * OpenGL : 1.4 + */ +void rglBlendFuncSeparate(GLenum sfactor, GLenum dfactor) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendFuncSeparate.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.blendfunc_separate.used = true; + gl_state.blendfunc_separate.srcRGB = sfactor; + gl_state.blendfunc_separate.dstRGB = dfactor; + gl_state.blendfunc_separate.srcAlpha = sfactor; + gl_state.blendfunc_separate.dstAlpha = dfactor; + glBlendFunc(sfactor, dfactor); +} + +/* + * Category: Textures + * + * Core in: + * OpenGL : 1.3 + */ +void rglActiveTexture(GLenum texture) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glActiveTexture.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glActiveTexture(texture); + gl_state.active_texture = texture - GL_TEXTURE0; +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglBindTexture(GLenum target, GLuint texture) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindTexture.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindTexture(target, texture); + gl_state.bind_textures.ids[gl_state.active_texture] = texture; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglDisable(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDisable.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glDisable(gl_state.cap_translate[cap]); + gl_state.cap_state[cap] = 0; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglEnable(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEnable.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glEnable(gl_state.cap_translate[cap]); + gl_state.cap_state[cap] = 1; +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUseProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUseProgram.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.program = program; + glUseProgram(program); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglDepthMask(GLboolean flag) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthMask.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glDepthMask(flag); + gl_state.depthmask.used = true; + gl_state.depthmask.mask = flag; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglStencilMask(GLenum mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilMask.\n"); +#endif + glStencilMask(mask); + gl_state.stencilmask.used = true; + gl_state.stencilmask.mask = mask; +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBufferData(GLenum target, GLsizeiptr size, + const GLvoid *data, GLenum usage) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferData.\n"); +#endif + glBufferData(target, size, data, usage); +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBufferSubData(GLenum target, GLintptr offset, + GLsizeiptr size, const GLvoid *data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferSubData.\n"); +#endif + glBufferSubData(target, offset, size, data); +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBindBuffer(GLenum target, GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindBuffer.\n"); +#endif + if (target == GL_ARRAY_BUFFER) + gl_state.array_buffer = buffer; + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindBuffer(target, buffer); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglLinkProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glLinkProgram.\n"); +#endif + glLinkProgram(program); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferTexture2D.\n"); +#endif + glFramebufferTexture2D(target, attachment, textarget, texture, level); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.2 + */ +void rglFramebufferTexture(GLenum target, GLenum attachment, + GLuint texture, GLint level) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferTexture.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glFramebufferTexture(target, attachment, texture, level); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglDrawArrays(GLenum mode, GLint first, GLsizei count) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawArrays.\n"); +#endif + glDrawArrays(mode, first, count); +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglDrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawElements.\n"); +#endif + glDrawElements(mode, count, type, indices); +} + +void rglCompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const GLvoid *data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCompressedTexImage2D.\n"); +#endif + glCompressedTexImage2D(target, level, internalformat, + width, height, border, imageSize, data); +} + +void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteFramebuffers.\n"); +#endif + glDeleteFramebuffers(n, framebuffers); +} + +void rglDeleteTextures(GLsizei n, const GLuint *textures) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteTextures.\n"); +#endif + glDeleteTextures(n, textures); +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglRenderbufferStorage(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glRenderbufferStorage.\n"); +#endif + glRenderbufferStorage(target, internalFormat, width, height); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindRenderbuffer.\n"); +#endif + glBindRenderbuffer(target, renderbuffer); +} + +/* + * + * Core in: + * + * OpenGLES : 2.0 + */ +void rglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteRenderbuffers.\n"); +#endif + glDeleteRenderbuffers(n, renderbuffers); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenRenderbuffers.\n"); +#endif + glGenRenderbuffers(n, renderbuffers); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglGenerateMipmap(GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenerateMipmap.\n"); +#endif + glGenerateMipmap(target); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +GLenum rglCheckFramebufferStatus(GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCheckFramebufferStatus.\n"); +#endif + return glCheckFramebufferStatus(target); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglFramebufferRenderbuffer(GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferRenderbuffer.\n"); +#endif + glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 3.0 + */ +void rglBindFragDataLocation(GLuint program, GLuint colorNumber, + const char * name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindFragDataLocation.\n"); +#endif +#if !defined(HAVE_OPENGLES2) + glBindFragDataLocation(program, colorNumber, name); +#endif +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetProgramiv(GLuint shader, GLenum pname, GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramiv.\n"); +#endif + glGetProgramiv(shader, pname, params); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.0 + */ +void rglProgramParameteri( GLuint program, + GLenum pname, + GLint value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glProgramParameteri.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && (defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1)) + glProgramParameteri(program, pname, value); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniform.\n"); +#endif + glGetActiveUniform(program, index, bufsize, length, size, type, name); +} + +void rglGenQueries( GLsizei n, + GLuint * ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenQueries.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenQueries(n, ids); +#endif +} + +void rglGetQueryObjectuiv( GLuint id, + GLenum pname, + GLuint * params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetQueryObjectuiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetQueryObjectuiv(id, pname, params); +#endif +} + +void rglDeleteQueries( GLsizei n, + const GLuint * ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteQueries.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteQueries(n, ids); +#endif +} + +void rglBeginQuery( GLenum target, + GLuint id) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBeginQuery.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBeginQuery(target, id); +#endif +} + +void rglEndQuery( GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEndQuery.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glEndQuery(target); +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglGetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniformBlockiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformBlockiv(program, uniformBlockIndex, + pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetActiveUniformsiv( GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniformsiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformsiv(program, uniformCount, + uniformIndices, pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar **uniformNames, + GLuint *uniformIndices) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformIndices.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetUniformIndices(program, uniformCount, + uniformNames, uniformIndices); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglBindBufferBase( GLenum target, + GLuint index, + GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindBufferBase.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindBufferBase(target, index, buffer); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +GLuint rglGetUniformBlockIndex( GLuint program, + const GLchar *uniformBlockName) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformBlockIndex.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glGetUniformBlockIndex(program, uniformBlockName); +#else + printf("WARNING! Not implemented.\n"); + return 0; +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglUniformBlockBinding( GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniformBlockBinding.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniformBlockBinding(program, uniformBlockIndex, + uniformBlockBinding); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform1ui(GLint location, GLuint v) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform1ui(location ,v); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform2ui(GLint location, GLuint v0, GLuint v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform2ui(location, v0, v1); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform3ui(location, v0, v1, v2); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform4ui(location, v0, v1, v2, v3); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniformMatrix4fv.\n"); +#endif + glUniformMatrix4fv(location, count, transpose, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDetachShader(GLuint program, GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDetachShader.\n"); +#endif + glDetachShader(program, shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetShaderiv.\n"); +#endif + glGetShaderiv(shader, pname, params); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglAttachShader(GLuint program, GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glAttachShader.\n"); +#endif + glAttachShader(program, shader); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +GLint rglGetAttribLocation(GLuint program, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetAttribLocation.\n"); +#endif + return glGetAttribLocation(program, name); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglShaderSource(GLuint shader, GLsizei count, + const GLchar **string, const GLint *length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glShaderSource.\n"); +#endif + return glShaderSource(shader, count, string, length); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglCompileShader(GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCompileShader.\n"); +#endif + glCompileShader(shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLuint rglCreateProgram(void) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCreateProgram.\n"); +#endif + return glCreateProgram(); +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglGenTextures(GLsizei n, GLuint *textures) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenTextures.\n"); +#endif + glGenTextures(n, textures); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetShaderInfoLog(GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *infoLog) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetShaderInfoLog.\n"); +#endif + glGetShaderInfoLog(shader, maxLength, length, infoLog); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetProgramInfoLog(GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *infoLog) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramInfoLog.\n"); +#endif + glGetProgramInfoLog(shader, maxLength, length, infoLog); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +GLboolean rglIsProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glIsProgram.\n"); +#endif + return glIsProgram(program); +} + +void rglTexCoord2f(GLfloat s, GLfloat t) +{ +#ifdef HAVE_LEGACY_GL +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexCoord2f.\n"); +#endif + glTexCoord2f(s, t); +#endif +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + * + */ +void rglDisableVertexAttribArray(GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDisableVertexAttribArray.\n"); +#endif + gl_state.vertex_attrib_pointer.enabled[index] = 0; + glDisableVertexAttribArray(index); +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglEnableVertexAttribArray(GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEnableVertexAttribArray.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.vertex_attrib_pointer.enabled[index] = 1; + glEnableVertexAttribArray(index); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttribIPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribIPointer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glVertexAttribIPointer(index, size, type, stride, pointer); +#endif +} + +void rglVertexAttribLPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribLPointer.\n"); +#endif +#if defined(HAVE_OPENGL) + glVertexAttribLPointer(index, size, type, stride, pointer); +#endif +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttribPointer(GLuint name, GLint size, + GLenum type, GLboolean normalized, GLsizei stride, + const GLvoid* pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribPointer.\n"); +#endif + gl_state.attrib_pointer.used[name] = 1; + gl_state.attrib_pointer.size[name] = size; + gl_state.attrib_pointer.type[name] = type; + gl_state.attrib_pointer.normalized[name] = normalized; + gl_state.attrib_pointer.stride[name] = stride; + gl_state.attrib_pointer.pointer[name] = pointer; + gl_state.attrib_pointer.buffer[name] = gl_state.array_buffer; + glVertexAttribPointer(name, size, type, normalized, stride, pointer); +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglBindAttribLocation(GLuint program, GLuint index, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindAttribLocation.\n"); +#endif + glBindAttribLocation(program, index, name); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttrib4f(GLuint name, GLfloat x, GLfloat y, + GLfloat z, GLfloat w) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttrib4f.\n"); +#endif + glVertexAttrib4f(name, x, y, z, w); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttrib4fv(GLuint name, GLfloat* v) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttrib4fv.\n"); +#endif + glVertexAttrib4fv(name, v); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLuint rglCreateShader(GLenum shaderType) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCreateShader.\n"); +#endif + return glCreateShader(shaderType); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDeleteProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteProgram.\n"); +#endif + glDeleteProgram(program); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDeleteShader(GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteShader.\n"); +#endif + glDeleteShader(shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLint rglGetUniformLocation(GLuint program, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformLocation.\n"); +#endif + return glGetUniformLocation(program, name); +} + +/* + * Category: VBO and PBO + * + * Core in: + * OpenGL : 1.5 + */ +void rglDeleteBuffers(GLsizei n, const GLuint *buffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteBuffers.\n"); +#endif + glDeleteBuffers(n, buffers); +} + +/* + * Category: VBO and PBO + * + * Core in: + * OpenGL : 1.5 + */ +void rglGenBuffers(GLsizei n, GLuint *buffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenBuffers.\n"); +#endif + glGenBuffers(n, buffers); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1f(GLint location, GLfloat v0) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1f.\n"); +#endif + glUniform1f(location, v0); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1fv.\n"); +#endif + glUniform1fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1iv(GLint location, GLsizei count, const GLint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1iv.\n"); +#endif + glUniform1iv(location, count, value); +} + +void rglClearBufferfv( GLenum buffer, + GLint drawBuffer, + const GLfloat * value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearBufferfv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glClearBufferfv(buffer, drawBuffer, value); +#endif +} + +void rglTexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexBuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glTexBuffer(target, internalFormat, buffer); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +const GLubyte* rglGetStringi(GLenum name, GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetString.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + return glGetStringi(name, index); +#else + return NULL; +#endif +} + +void rglClearBufferfi( GLenum buffer, + GLint drawBuffer, + GLfloat depth, + GLint stencil) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearBufferfi.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glClearBufferfi(buffer, drawBuffer, depth, stencil); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglRenderbufferStorageMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glRenderbufferStorageMultisample.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glRenderbufferStorageMultisample(target, samples, internalformat, width, height); +#endif +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1i(GLint location, GLint v0) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1i.\n"); +#endif + glUniform1i(location, v0); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2f(GLint location, GLfloat v0, GLfloat v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2f.\n"); +#endif + glUniform2f(location, v0, v1); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2i(GLint location, GLint v0, GLint v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2i.\n"); +#endif + glUniform2i(location, v0, v1); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2fv.\n"); +#endif + glUniform2fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3f.\n"); +#endif + glUniform3f(location, v0, v1, v2); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform3fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3fv.\n"); +#endif + glUniform3fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4i.\n"); +#endif + glUniform4i(location, v0, v1, v2, v3); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4f.\n"); +#endif + glUniform4f(location, v0, v1, v2, v3); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4fv.\n"); +#endif + glUniform4fv(location, count, value); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglPolygonOffset(GLfloat factor, GLfloat units) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPolygonOffset.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glPolygonOffset(factor, units); + gl_state.polygonoffset.used = true; + gl_state.polygonoffset.factor = factor; + gl_state.polygonoffset.units = units; +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +void rglGenFramebuffers(GLsizei n, GLuint *ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenFramebuffers.\n"); +#endif + glGenFramebuffers(n, ids); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +void rglBindFramebuffer(GLenum target, GLuint framebuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindFramebuffer.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindFramebuffer(target, framebuffer); + gl_state.framebuf = framebuffer; +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglDrawBuffers(GLsizei n, const GLenum *bufs) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawBuffers.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDrawBuffers(n, bufs); +#endif +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void *rglMapBufferRange( GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMapBufferRange.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glMapBufferRange(target, offset, length, access); +#else + printf("WARNING! Not implemented.\n"); + return NULL; +#endif +} + +/* + * + * Core in: + * OpenGL : 4.3 + * OpenGLES : 3.1 + */ +void rglTexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexStorage2DMultisample.\n"); +#endif +#if defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glTexStorage2DMultisample(target, samples, internalformat, + width, height, fixedsamplelocations); +#endif +} + +/* + * + * Core in: + * OpenGLES : 3.0 + */ +void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexStorage2D.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glTexStorage2D(target, levels, internalFormat, width, height); +#endif +} +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.2 + */ +void rglDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLvoid *indices, GLint basevertex) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglMemoryBarrier( GLbitfield barriers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMemoryBarrier.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glMemoryBarrier(barriers); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglBindImageTexture( GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindImageTexture.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glBindImageTexture(unit, texture, level, layered, layer, access, format); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglGetProgramBinary( GLuint program, + GLsizei bufsize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramBinary.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetProgramBinary(program, bufsize, length, binaryFormat, binary); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glProgramBinary.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glProgramBinary(program, binaryFormat, binary, length); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +void rglTexImage2DMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexImage2DMultisample.\n"); +#endif +#ifndef HAVE_OPENGLES + glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); +#endif +} + +void rglTexImage3D( GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid * data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexImage3D.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void * rglMapBuffer( GLenum target, GLenum access) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMapBuffer.\n"); +#endif +#if defined(HAVE_OPENGLES) + return glMapBufferOES(target, access); +#else + return glMapBuffer(target, access); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +GLboolean rglUnmapBuffer( GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUnmapBuffer.\n"); +#endif +#if defined(HAVE_OPENGLES) + return glUnmapBufferOES(target); +#else + return glUnmapBuffer(target); +#endif +} + +void rglBlendEquation(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendEquation.\n"); +#endif + glBlendEquation(mode); +} + +void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendColor.\n"); +#endif + glBlendColor(red, green, blue, alpha); +} + +/* + * Category: Blending + * + * Core in: + * OpenGL : 2.0 + */ +void rglBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendEquationSeparate.\n"); +#endif + glBlendEquationSeparate(modeRGB, modeAlpha); +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.2 + */ +void rglCopyImageSubData( GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCopyImageSubData.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glCopyImageSubData(srcName, + srcTarget, + srcLevel, + srcX, + srcY, + srcZ, + dstName, + dstTarget, + dstLevel, + dstX, + dstY, + dstZ, + srcWidth, + srcHeight, + srcDepth); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglBindVertexArray(GLuint array) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindVertexArray.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindVertexArray(array); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglGenVertexArrays(GLsizei n, GLuint *arrays) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenVertexArrays.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenVertexArrays(n, arrays); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteVertexArrays.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteVertexArrays(n, arrays); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void *rglFenceSync(GLenum condition, GLbitfield flags) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFenceSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return (GLsync)glFenceSync(condition, flags); +#else + return NULL; +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglDeleteSync(void * sync) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteSync((GLsync)sync); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglWaitSync(void *sync, GLbitfield flags, uint64_t timeout) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glWaitSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glWaitSync((GLsync)sync, flags, (GLuint64)timeout); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.4 + * OpenGLES : Not available + */ +void rglBufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferStorage.\n"); +#endif +#if defined(HAVE_OPENGL) + glBufferStorage(target, size, data, flags); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 2.0 + */ + +void rglUniform2iv( GLint location, + GLsizei count, + const GLint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2iv.\n"); +#endif + glUniform2iv(location, count, value); +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : ?.? + */ + +void rglUniform2uiv( GLint location, + GLsizei count, + const GLuint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2uiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform2uiv(location, count, value); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.3 + * OpenGLES : ?.? + */ +void rglTextureView( GLuint texture, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTextureView.\n"); +#endif +#if defined(HAVE_OPENGL) + glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFlushMappedBufferRange.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glFlushMappedBufferRange(target, offset, length); +#endif +} + +#ifndef GL_WAIT_FAILED +#define GL_WAIT_FAILED 0x911D +#endif + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +GLenum rglClientWaitSync(void *sync, GLbitfield flags, uint64_t timeout) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClientWaitSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glClientWaitSync((GLsync)sync, flags, (GLuint64)timeout); +#else + return GL_WAIT_FAILED; +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : Not available + */ +void rglDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + GLvoid *indices, GLint basevertex) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawElementsBaseVertex.\n"); +#endif +#if defined(HAVE_OPENGL) + glDrawElementsBaseVertex(mode, count, type, indices, basevertex); +#endif +} + +/* GLSM-side */ + +static void glsm_state_setup(void) +{ + unsigned i; + + gl_state.cap_translate[SGL_DEPTH_TEST] = GL_DEPTH_TEST; + gl_state.cap_translate[SGL_BLEND] = GL_BLEND; + gl_state.cap_translate[SGL_POLYGON_OFFSET_FILL] = GL_POLYGON_OFFSET_FILL; + gl_state.cap_translate[SGL_FOG] = GL_FOG; + gl_state.cap_translate[SGL_CULL_FACE] = GL_CULL_FACE; + gl_state.cap_translate[SGL_ALPHA_TEST] = GL_ALPHA_TEST; + gl_state.cap_translate[SGL_SCISSOR_TEST] = GL_SCISSOR_TEST; + gl_state.cap_translate[SGL_STENCIL_TEST] = GL_STENCIL_TEST; + +#ifndef HAVE_OPENGLES + gl_state.cap_translate[SGL_COLOR_LOGIC_OP] = GL_COLOR_LOGIC_OP; + gl_state.cap_translate[SGL_CLIP_DISTANCE0] = GL_CLIP_DISTANCE0; + gl_state.cap_translate[SGL_DEPTH_CLAMP] = GL_DEPTH_CLAMP; +#endif + + for (i = 0; i < MAX_ATTRIB; i++) + { + gl_state.vertex_attrib_pointer.enabled[i] = 0; + gl_state.attrib_pointer.used[i] = 0; + } + + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &glsm_max_textures); + + gl_state.bind_textures.ids = (GLuint*)calloc(glsm_max_textures, sizeof(GLuint)); + + default_framebuffer = glsm_get_current_framebuffer(); + gl_state.framebuf = default_framebuffer; + gl_state.cullface.mode = GL_BACK; + gl_state.frontface.mode = GL_CCW; + + gl_state.blendfunc_separate.used = false; + gl_state.blendfunc_separate.srcRGB = GL_ONE; + gl_state.blendfunc_separate.dstRGB = GL_ZERO; + gl_state.blendfunc_separate.srcAlpha = GL_ONE; + gl_state.blendfunc_separate.dstAlpha = GL_ZERO; + + gl_state.depthfunc.used = false; + + gl_state.colormask.used = false; + gl_state.colormask.red = GL_TRUE; + gl_state.colormask.green = GL_TRUE; + gl_state.colormask.blue = GL_TRUE; + gl_state.colormask.alpha = GL_TRUE; + + gl_state.polygonoffset.used = false; + + gl_state.depthfunc.func = GL_LESS; + +#ifndef HAVE_OPENGLES + gl_state.colorlogicop = GL_COPY; +#endif + +#ifdef CORE + glGenVertexArrays(1, &gl_state.vao); +#endif +} + +static void glsm_state_bind(void) +{ + unsigned i; +#ifdef CORE + glBindVertexArray(gl_state.vao); +#endif + glBindBuffer(GL_ARRAY_BUFFER, gl_state.array_buffer); + + for (i = 0; i < MAX_ATTRIB; i++) + { + if (gl_state.vertex_attrib_pointer.enabled[i]) + glEnableVertexAttribArray(i); + else + glDisableVertexAttribArray(i); + + if (gl_state.attrib_pointer.used[i] && gl_state.attrib_pointer.buffer[i] == gl_state.array_buffer) + { + glVertexAttribPointer( + i, + gl_state.attrib_pointer.size[i], + gl_state.attrib_pointer.type[i], + gl_state.attrib_pointer.normalized[i], + gl_state.attrib_pointer.stride[i], + gl_state.attrib_pointer.pointer[i]); + } + } + + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, default_framebuffer); + + if (gl_state.blendfunc.used) + glBlendFunc( + gl_state.blendfunc.sfactor, + gl_state.blendfunc.dfactor); + + if (gl_state.blendfunc_separate.used) + glBlendFuncSeparate( + gl_state.blendfunc_separate.srcRGB, + gl_state.blendfunc_separate.dstRGB, + gl_state.blendfunc_separate.srcAlpha, + gl_state.blendfunc_separate.dstAlpha + ); + + glClearColor( + gl_state.clear_color.r, + gl_state.clear_color.g, + gl_state.clear_color.b, + gl_state.clear_color.a); + + if (gl_state.depthfunc.used) + glDepthFunc(gl_state.depthfunc.func); + + if (gl_state.colormask.used) + glColorMask( + gl_state.colormask.red, + gl_state.colormask.green, + gl_state.colormask.blue, + gl_state.colormask.alpha); + + if (gl_state.cullface.used) + glCullFace(gl_state.cullface.mode); + + if (gl_state.depthmask.used) + glDepthMask(gl_state.depthmask.mask); + + if (gl_state.polygonoffset.used) + glPolygonOffset( + gl_state.polygonoffset.factor, + gl_state.polygonoffset.units); + + if (gl_state.scissor.used) + glScissor( + gl_state.scissor.x, + gl_state.scissor.y, + gl_state.scissor.w, + gl_state.scissor.h); + + glUseProgram(gl_state.program); + + glViewport( + gl_state.viewport.x, + gl_state.viewport.y, + gl_state.viewport.w, + gl_state.viewport.h); + + for(i = 0; i < SGL_CAP_MAX; i ++) + { + if (gl_state.cap_state[i]) + glEnable(gl_state.cap_translate[i]); + } + + if (gl_state.frontface.used) + glFrontFace(gl_state.frontface.mode); + + if (gl_state.stencilmask.used) + glStencilMask(gl_state.stencilmask.mask); + + if (gl_state.stencilop.used) + glStencilOp(gl_state.stencilop.sfail, + gl_state.stencilop.dpfail, + gl_state.stencilop.dppass); + + if (gl_state.stencilfunc.used) + glStencilFunc( + gl_state.stencilfunc.func, + gl_state.stencilfunc.ref, + gl_state.stencilfunc.mask); + + for (i = 0; i < glsm_max_textures; i ++) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, gl_state.bind_textures.ids[i]); + } + + glActiveTexture(GL_TEXTURE0 + gl_state.active_texture); +} + +static void glsm_state_unbind(void) +{ + unsigned i; +#ifdef CORE + glBindVertexArray(0); +#endif + for (i = 0; i < SGL_CAP_MAX; i ++) + { + if (gl_state.cap_state[i]) + glDisable(gl_state.cap_translate[i]); + } + + glBlendFunc(GL_ONE, GL_ZERO); + + if (gl_state.colormask.used) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if (gl_state.blendfunc_separate.used) + glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + + if (gl_state.cullface.used) + glCullFace(GL_BACK); + + if (gl_state.depthmask.used) + glDepthMask(GL_TRUE); + + if (gl_state.polygonoffset.used) + glPolygonOffset(0, 0); + + glUseProgram(0); + glClearColor(0,0,0,0.0f); + + if (gl_state.depthrange.used) + rglDepthRange(0, 1); + + glStencilMask(1); + glFrontFace(GL_CCW); + if (gl_state.depthfunc.used) + glDepthFunc(GL_LESS); + + if (gl_state.stencilop.used) + glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP); + + if (gl_state.stencilfunc.used) + glStencilFunc(GL_ALWAYS,0,1); + + /* Clear textures */ + for (i = 0; i < glsm_max_textures; i ++) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + } + glActiveTexture(GL_TEXTURE0); + + for (i = 0; i < MAX_ATTRIB; i ++) + glDisableVertexAttribArray(i); + + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, 0); +} + +static bool glsm_state_ctx_destroy(void *data) +{ + if (gl_state.bind_textures.ids) + free(gl_state.bind_textures.ids); + gl_state.bind_textures.ids = NULL; + + return true; +} + +static bool glsm_state_ctx_init(glsm_ctx_params_t *params) +{ + if (!params || !params->environ_cb) + return false; + +#ifdef HAVE_OPENGLES +#if defined(HAVE_OPENGLES_3_1) + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES_VERSION; + hw_render.version_major = 3; + hw_render.version_minor = 1; +#elif defined(HAVE_OPENGLES3) + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES3; +#else + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES2; +#endif +#else + hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; + if (params->context_type != RETRO_HW_CONTEXT_NONE) + hw_render.context_type = params->context_type; + if (params->major != 0) + hw_render.version_major = params->major; + if (params->minor != 0) + hw_render.version_minor = params->minor; +#endif + + hw_render.context_reset = params->context_reset; + hw_render.context_destroy = params->context_destroy; + hw_render.stencil = params->stencil; + hw_render.depth = true; + hw_render.bottom_left_origin = true; + hw_render.cache_context = false; + + if (!params->environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render)) + return false; + + return true; +} + +GLuint glsm_get_current_framebuffer(void) +{ + return hw_render.get_current_framebuffer(); +} + +bool glsm_ctl(enum glsm_state_ctl state, void *data) +{ + switch (state) + { + case GLSM_CTL_IMM_VBO_DRAW: + return false; + case GLSM_CTL_IMM_VBO_DISABLE: + return false; + case GLSM_CTL_IS_IMM_VBO: + return false; + case GLSM_CTL_SET_IMM_VBO: + break; + case GLSM_CTL_UNSET_IMM_VBO: + break; + case GLSM_CTL_PROC_ADDRESS_GET: + { + glsm_ctx_proc_address_t *proc = (glsm_ctx_proc_address_t*)data; + if (!hw_render.get_proc_address) + return false; + proc->addr = hw_render.get_proc_address; + } + break; + case GLSM_CTL_STATE_CONTEXT_RESET: + rglgen_resolve_symbols(hw_render.get_proc_address); + break; + case GLSM_CTL_STATE_CONTEXT_DESTROY: + glsm_state_ctx_destroy(data); + break; + case GLSM_CTL_STATE_CONTEXT_INIT: + return glsm_state_ctx_init((glsm_ctx_params_t*)data); + case GLSM_CTL_STATE_SETUP: + glsm_state_setup(); + break; + case GLSM_CTL_STATE_UNBIND: + glsm_state_unbind(); + break; + case GLSM_CTL_STATE_BIND: + glsm_state_bind(); + break; + case GLSM_CTL_NONE: + default: + break; + } + + return true; +}