2014-09-07 15:27:49 +00:00
|
|
|
/* * Copyright (C) 2011-2014 Gregory hainaut
|
2013-01-14 09:15:39 +00:00
|
|
|
* Copyright (C) 2007-2009 Gabest
|
|
|
|
*
|
|
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This Program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "GLLoader.h"
|
2013-05-27 16:53:38 +00:00
|
|
|
#include "GSdx.h"
|
2013-01-14 09:15:39 +00:00
|
|
|
|
2015-10-18 09:16:54 +00:00
|
|
|
PFNGLACTIVETEXTUREPROC gl_ActiveTexture = NULL;
|
|
|
|
PFNGLBLENDCOLORPROC gl_BlendColor = NULL;
|
|
|
|
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLATTACHSHADERPROC glAttachShader = NULL;
|
|
|
|
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
|
|
|
|
PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
|
|
|
|
PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
|
|
|
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL;
|
|
|
|
PFNGLBINDSAMPLERPROC glBindSampler = NULL;
|
|
|
|
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
|
|
|
|
PFNGLBLENDEQUATIONSEPARATEIARBPROC glBlendEquationSeparateiARB = NULL;
|
|
|
|
PFNGLBLENDFUNCSEPARATEIARBPROC glBlendFuncSeparateiARB = NULL;
|
|
|
|
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL;
|
|
|
|
PFNGLBUFFERDATAPROC glBufferData = NULL;
|
|
|
|
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL;
|
|
|
|
PFNGLCLEARBUFFERFVPROC glClearBufferfv = NULL;
|
|
|
|
PFNGLCLEARBUFFERIVPROC glClearBufferiv = NULL;
|
|
|
|
PFNGLCLEARBUFFERUIVPROC glClearBufferuiv = NULL;
|
|
|
|
PFNGLCOLORMASKIPROC glColorMaski = NULL;
|
|
|
|
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
|
|
|
|
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
|
|
|
|
PFNGLCREATESHADERPROC glCreateShader = NULL;
|
|
|
|
PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv = NULL;
|
|
|
|
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
|
|
|
|
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
|
|
|
|
PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
|
|
|
|
PFNGLDELETESAMPLERSPROC glDeleteSamplers = NULL;
|
|
|
|
PFNGLDELETESHADERPROC glDeleteShader = NULL;
|
|
|
|
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
|
|
|
|
PFNGLDETACHSHADERPROC glDetachShader = NULL;
|
|
|
|
PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL;
|
|
|
|
PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex = NULL;
|
|
|
|
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
|
|
|
|
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL;
|
|
|
|
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL;
|
|
|
|
PFNGLGENBUFFERSPROC glGenBuffers = NULL;
|
|
|
|
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL;
|
|
|
|
PFNGLGENSAMPLERSPROC glGenSamplers = NULL;
|
|
|
|
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
|
|
|
|
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = NULL;
|
|
|
|
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
|
|
|
|
PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback = NULL;
|
|
|
|
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
|
|
|
|
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
|
|
|
|
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
|
|
|
|
PFNGLGETSTRINGIPROC glGetStringi = NULL;
|
|
|
|
PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL;
|
|
|
|
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
|
|
|
|
PFNGLMAPBUFFERPROC glMapBuffer = NULL;
|
|
|
|
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
|
|
|
|
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = NULL;
|
|
|
|
PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf = NULL;
|
|
|
|
PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri = NULL;
|
|
|
|
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
|
|
|
|
PFNGLUNIFORM1IPROC glUniform1i = NULL;
|
|
|
|
PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL;
|
|
|
|
PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages = NULL;
|
|
|
|
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
|
|
|
|
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
|
|
|
|
PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL;
|
|
|
|
PFNGLFENCESYNCPROC glFenceSync = NULL;
|
|
|
|
PFNGLDELETESYNCPROC glDeleteSync = NULL;
|
|
|
|
PFNGLCLIENTWAITSYNCPROC glClientWaitSync = NULL;
|
|
|
|
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = NULL;
|
|
|
|
PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate = NULL;
|
|
|
|
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = NULL;
|
2013-08-10 19:43:59 +00:00
|
|
|
// GL4.0
|
|
|
|
// GL4.1
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline = NULL;
|
|
|
|
PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines = NULL;
|
|
|
|
PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines = NULL;
|
|
|
|
PFNGLGETPROGRAMPIPELINEIVPROC glGetProgramPipelineiv = NULL;
|
|
|
|
PFNGLVALIDATEPROGRAMPIPELINEPROC glValidateProgramPipeline = NULL;
|
|
|
|
PFNGLGETPROGRAMPIPELINEINFOLOGPROC glGetProgramPipelineInfoLog = NULL;
|
|
|
|
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = NULL;
|
2013-05-19 12:42:55 +00:00
|
|
|
// NO GL4.1
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
|
|
|
|
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
|
|
|
|
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = NULL;
|
2013-08-03 08:29:01 +00:00
|
|
|
// GL4.3
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData = NULL;
|
|
|
|
PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage = NULL;
|
|
|
|
PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup = NULL;
|
|
|
|
PFNGLPOPDEBUGGROUPPROC glPopDebugGroup = NULL;
|
|
|
|
PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert = NULL;
|
2015-10-24 12:05:00 +00:00
|
|
|
PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl = NULL;
|
2013-07-28 14:40:43 +00:00
|
|
|
// GL4.2
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLBINDIMAGETEXTUREPROC glBindImageTexture = NULL;
|
|
|
|
PFNGLMEMORYBARRIERPROC glMemoryBarrier = NULL;
|
|
|
|
PFNGLTEXSTORAGE2DPROC glTexStorage2D = NULL;
|
2013-08-02 16:38:12 +00:00
|
|
|
// GL4.4
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLCLEARTEXIMAGEPROC glClearTexImage = NULL;
|
|
|
|
PFNGLBUFFERSTORAGEPROC glBufferStorage = NULL;
|
2014-09-07 15:27:49 +00:00
|
|
|
|
|
|
|
// GL4.5
|
2015-10-17 15:05:15 +00:00
|
|
|
PFNGLCREATETEXTURESPROC glCreateTextures = NULL;
|
|
|
|
PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D = NULL;
|
|
|
|
PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D = NULL;
|
|
|
|
PFNGLCOPYTEXTURESUBIMAGE2DPROC glCopyTextureSubImage2D = NULL;
|
|
|
|
PFNGLBINDTEXTUREUNITPROC glBindTextureUnit = NULL;
|
|
|
|
PFNGLGETTEXTUREIMAGEPROC glGetTextureImage = NULL;
|
|
|
|
PFNGLTEXTUREPARAMETERIPROC glTextureParameteri = NULL;
|
|
|
|
|
|
|
|
PFNGLCREATEFRAMEBUFFERSPROC glCreateFramebuffers = NULL;
|
|
|
|
PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv = NULL;
|
|
|
|
PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glClearNamedFramebufferiv = NULL;
|
|
|
|
PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glClearNamedFramebufferuiv = NULL;
|
|
|
|
PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glNamedFramebufferTexture = NULL;
|
|
|
|
PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glNamedFramebufferDrawBuffers = NULL;
|
|
|
|
PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glNamedFramebufferReadBuffer = NULL;
|
|
|
|
PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glCheckNamedFramebufferStatus = NULL;
|
|
|
|
|
|
|
|
PFNGLCREATEBUFFERSPROC glCreateBuffers = NULL;
|
|
|
|
PFNGLNAMEDBUFFERSTORAGEPROC glNamedBufferStorage = NULL;
|
|
|
|
PFNGLNAMEDBUFFERDATAPROC glNamedBufferData = NULL;
|
|
|
|
PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData = NULL;
|
|
|
|
PFNGLMAPNAMEDBUFFERPROC glMapNamedBuffer = NULL;
|
|
|
|
PFNGLMAPNAMEDBUFFERRANGEPROC glMapNamedBufferRange = NULL;
|
|
|
|
PFNGLUNMAPNAMEDBUFFERPROC glUnmapNamedBuffer = NULL;
|
|
|
|
PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glFlushMappedNamedBufferRange = NULL;
|
|
|
|
|
|
|
|
PFNGLCREATESAMPLERSPROC glCreateSamplers = NULL;
|
|
|
|
PFNGLCREATEPROGRAMPIPELINESPROC glCreateProgramPipelines = NULL;
|
|
|
|
|
|
|
|
PFNGLCLIPCONTROLPROC glClipControl = NULL;
|
|
|
|
PFNGLTEXTUREBARRIERPROC glTextureBarrier = NULL;
|
2014-01-31 21:30:54 +00:00
|
|
|
|
2015-04-24 17:32:00 +00:00
|
|
|
namespace Emulate_DSA {
|
2015-04-25 09:41:46 +00:00
|
|
|
// Texture entry point
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY BindTextureUnit(GLuint unit, GLuint texture) {
|
2015-10-18 09:16:54 +00:00
|
|
|
gl_ActiveTexture(GL_TEXTURE0 + unit);
|
2015-04-24 17:32:00 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, texture);
|
|
|
|
}
|
|
|
|
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY CreateTexture(GLenum target, GLsizei n, GLuint *textures) {
|
2015-04-24 17:32:00 +00:00
|
|
|
glGenTextures(1, textures);
|
|
|
|
}
|
|
|
|
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY TextureStorage(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
|
2015-04-24 17:32:00 +00:00
|
|
|
BindTextureUnit(7, texture);
|
2015-10-17 15:05:15 +00:00
|
|
|
glTexStorage2D(GL_TEXTURE_2D, levels, internalformat, width, height);
|
2015-04-24 17:32:00 +00:00
|
|
|
}
|
|
|
|
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY TextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
|
2015-04-24 17:32:00 +00:00
|
|
|
BindTextureUnit(7, texture);
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, width, height, format, type, pixels);
|
|
|
|
}
|
|
|
|
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY CopyTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
2015-04-24 17:32:00 +00:00
|
|
|
BindTextureUnit(7, texture);
|
|
|
|
glCopyTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, x, y, width, height);
|
|
|
|
}
|
|
|
|
|
2015-04-24 23:32:09 +00:00
|
|
|
void APIENTRY GetTexureImage(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels) {
|
2015-04-24 17:32:00 +00:00
|
|
|
BindTextureUnit(7, texture);
|
|
|
|
glGetTexImage(GL_TEXTURE_2D, level, format, type, pixels);
|
|
|
|
}
|
|
|
|
|
2015-06-14 08:02:30 +00:00
|
|
|
void APIENTRY TextureParameteri (GLuint texture, GLenum pname, GLint param) {
|
|
|
|
BindTextureUnit(7, texture);
|
2015-06-25 08:25:24 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, pname, param);
|
2015-06-14 08:02:30 +00:00
|
|
|
}
|
|
|
|
|
2015-04-25 09:41:46 +00:00
|
|
|
// Framebuffer entry point
|
2015-04-25 10:06:30 +00:00
|
|
|
GLenum fb_target = 0;
|
|
|
|
void SetFramebufferTarget(GLenum target) {
|
|
|
|
fb_target = target;
|
|
|
|
}
|
|
|
|
|
2015-04-25 09:41:46 +00:00
|
|
|
void APIENTRY CreateFramebuffers(GLsizei n, GLuint *framebuffers) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glGenFramebuffers(n, framebuffers);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
glClearBufferfv(buffer, drawbuffer, value);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
glClearBufferiv(buffer, drawbuffer, value);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
glClearBufferuiv(buffer, drawbuffer, value);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY NamedFramebufferTexture(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
glFramebufferTexture2D(fb_target, attachment, GL_TEXTURE_2D, texture, level);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum *bufs) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
glDrawBuffers(n, bufs);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
2015-04-25 10:06:30 +00:00
|
|
|
glReadBuffer(src);
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, 0);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GLenum APIENTRY CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindFramebuffer(fb_target, framebuffer);
|
|
|
|
return glCheckFramebufferStatus(fb_target);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Buffer entry point
|
2015-04-25 10:06:30 +00:00
|
|
|
GLenum buffer_target = 0;
|
|
|
|
void SetBufferTarget(GLenum target) {
|
|
|
|
buffer_target = target;
|
|
|
|
}
|
|
|
|
|
2015-04-25 09:41:46 +00:00
|
|
|
void APIENTRY CreateBuffers(GLsizei n, GLuint *buffers) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glGenBuffers(1, buffers);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 13:33:57 +00:00
|
|
|
void APIENTRY NamedBufferStorage(GLuint buffer, buffer_proc_t size, const void *data, GLbitfield flags) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
glBufferStorage(buffer_target, size, data, flags);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 13:33:57 +00:00
|
|
|
void APIENTRY NamedBufferData(GLuint buffer, buffer_proc_t size, const void *data, GLenum usage) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
glBufferData(buffer_target, size, data, usage);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 13:33:57 +00:00
|
|
|
void APIENTRY NamedBufferSubData(GLuint buffer, GLintptr offset, buffer_proc_t size, const void *data) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
glBufferSubData(buffer_target, offset, size, data);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *APIENTRY MapNamedBuffer(GLuint buffer, GLenum access) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
return glMapBuffer(buffer_target, access);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 13:33:57 +00:00
|
|
|
void *APIENTRY MapNamedBufferRange(GLuint buffer, GLintptr offset, buffer_proc_t length, GLbitfield access) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
return glMapBufferRange(buffer_target, offset, length, access);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GLboolean APIENTRY UnmapNamedBuffer(GLuint buffer) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
return glUnmapBuffer(buffer_target);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 13:33:57 +00:00
|
|
|
void APIENTRY FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, buffer_proc_t length) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindBuffer(buffer_target, buffer);
|
|
|
|
glFlushMappedBufferRange(buffer_target, offset, length);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Misc entry point
|
|
|
|
// (only purpose is to have a consistent API otherwise it is useless)
|
|
|
|
void APIENTRY CreateProgramPipelines(GLsizei n, GLuint *pipelines) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glGenProgramPipelines(n, pipelines);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void APIENTRY CreateSamplers(GLsizei n, GLuint *samplers) {
|
2015-10-17 15:05:15 +00:00
|
|
|
glGenSamplers(n, samplers);
|
2015-04-25 09:41:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Replace function pointer to emulate DSA behavior
|
2015-04-24 17:32:00 +00:00
|
|
|
void Init() {
|
2015-06-06 19:28:59 +00:00
|
|
|
fprintf(stderr, "DSA is not supported. Replacing the GL function pointer to emulate it\n");
|
2015-10-17 15:05:15 +00:00
|
|
|
glBindTextureUnit = BindTextureUnit;
|
|
|
|
glCreateTextures = CreateTexture;
|
|
|
|
glTextureStorage2D = TextureStorage;
|
|
|
|
glTextureSubImage2D = TextureSubImage;
|
|
|
|
glCopyTextureSubImage2D = CopyTextureSubImage;
|
|
|
|
glGetTextureImage = GetTexureImage;
|
|
|
|
glTextureParameteri = TextureParameteri;
|
|
|
|
|
|
|
|
glCreateFramebuffers = CreateFramebuffers;
|
|
|
|
glClearNamedFramebufferfv = ClearNamedFramebufferfv;
|
|
|
|
glClearNamedFramebufferiv = ClearNamedFramebufferiv;
|
|
|
|
glClearNamedFramebufferuiv = ClearNamedFramebufferuiv;
|
|
|
|
glNamedFramebufferDrawBuffers = NamedFramebufferDrawBuffers;
|
|
|
|
glNamedFramebufferReadBuffer = NamedFramebufferReadBuffer;
|
|
|
|
glCheckNamedFramebufferStatus = CheckNamedFramebufferStatus;
|
|
|
|
|
|
|
|
glCreateBuffers = CreateBuffers;
|
|
|
|
glNamedBufferStorage = NamedBufferStorage;
|
|
|
|
glNamedBufferData = NamedBufferData;
|
|
|
|
glNamedBufferSubData = NamedBufferSubData;
|
|
|
|
glMapNamedBuffer = MapNamedBuffer;
|
|
|
|
glMapNamedBufferRange = MapNamedBufferRange;
|
|
|
|
glUnmapNamedBuffer = UnmapNamedBuffer;
|
|
|
|
glFlushMappedNamedBufferRange = FlushMappedNamedBufferRange;
|
|
|
|
|
|
|
|
glCreateProgramPipelines = CreateProgramPipelines;
|
|
|
|
glCreateSamplers = CreateSamplers;
|
2015-04-24 17:32:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-14 09:15:39 +00:00
|
|
|
namespace GLLoader {
|
|
|
|
|
2014-03-29 09:47:53 +00:00
|
|
|
bool fglrx_buggy_driver = false;
|
|
|
|
bool mesa_amd_buggy_driver = false;
|
|
|
|
bool nvidia_buggy_driver = false;
|
|
|
|
bool intel_buggy_driver = false;
|
|
|
|
bool in_replayer = false;
|
2013-07-11 17:08:42 +00:00
|
|
|
|
2015-08-07 12:46:57 +00:00
|
|
|
|
|
|
|
// GL4 hardware (due to proprietary driver limitation)
|
2016-01-01 13:43:47 +00:00
|
|
|
bool found_GL_ARB_separate_shader_objects = false; // Issue with Catalyst...
|
2014-09-30 20:04:42 +00:00
|
|
|
bool found_geometry_shader = true; // we require GL3.3 so geometry must be supported by default
|
2015-05-02 08:53:19 +00:00
|
|
|
bool found_GL_EXT_texture_filter_anisotropic = false;
|
2015-05-15 18:58:14 +00:00
|
|
|
bool found_GL_ARB_clear_texture = false; // Don't know if GL3 GPU can support it
|
2014-11-01 19:17:08 +00:00
|
|
|
bool found_GL_ARB_buffer_storage = false;
|
2013-08-17 08:57:52 +00:00
|
|
|
bool found_GL_ARB_copy_image = false; // Not sure actually maybe GL3 GPU can do it
|
2013-06-16 16:33:08 +00:00
|
|
|
bool found_GL_ARB_gpu_shader5 = false;
|
2014-03-29 09:47:53 +00:00
|
|
|
bool found_GL_ARB_shader_image_load_store = false; // GLES3.1
|
2015-08-07 12:46:57 +00:00
|
|
|
// DX10 GPU limited driver
|
2016-01-01 13:43:47 +00:00
|
|
|
bool found_GL_ARB_texture_barrier = false; // Well maybe supported by older hardware I don't know
|
2015-08-07 12:46:57 +00:00
|
|
|
bool found_GL_ARB_draw_buffers_blend = false;
|
2014-09-07 15:27:49 +00:00
|
|
|
bool found_GL_ARB_clip_control = false;
|
|
|
|
bool found_GL_ARB_direct_state_access = false;
|
|
|
|
|
2013-08-03 08:29:01 +00:00
|
|
|
// Mandatory
|
|
|
|
bool found_GL_ARB_texture_storage = false;
|
2014-10-01 07:50:59 +00:00
|
|
|
bool found_GL_ARB_shading_language_420pack = false;
|
2013-08-03 08:29:01 +00:00
|
|
|
|
|
|
|
static bool status_and_override(bool& found, const std::string& name, bool mandatory = false)
|
|
|
|
{
|
2015-05-01 12:18:05 +00:00
|
|
|
if (mandatory) {
|
|
|
|
if (!found) {
|
2014-10-01 07:50:59 +00:00
|
|
|
fprintf(stderr, "ERROR: %s is NOT SUPPORTED\n", name.c_str());
|
|
|
|
}
|
2015-05-01 12:18:05 +00:00
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
2015-12-20 13:01:01 +00:00
|
|
|
fprintf(stdout, "INFO: %s is NOT SUPPORTED\n", name.c_str());
|
2014-02-01 11:11:14 +00:00
|
|
|
} else {
|
2015-12-20 13:01:01 +00:00
|
|
|
fprintf(stdout, "INFO: %s is available\n", name.c_str());
|
2013-08-03 08:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string opt("override_");
|
|
|
|
opt += name;
|
|
|
|
|
|
|
|
if (theApp.GetConfig(opt.c_str(), -1) != -1) {
|
|
|
|
found = !!theApp.GetConfig(opt.c_str(), -1);
|
|
|
|
fprintf(stderr, "Override %s detection (%s)\n", name.c_str(), found ? "Enabled" : "Disabled");
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-05-19 12:42:55 +00:00
|
|
|
|
2015-07-13 10:35:55 +00:00
|
|
|
bool check_gl_version(int major, int minor) {
|
2013-05-19 12:42:55 +00:00
|
|
|
|
|
|
|
const GLubyte* s = glGetString(GL_VERSION);
|
2013-07-28 14:40:43 +00:00
|
|
|
if (s == NULL) {
|
|
|
|
fprintf(stderr, "Error: GLLoader failed to get GL version\n");
|
|
|
|
return false;
|
|
|
|
}
|
2015-07-13 10:35:55 +00:00
|
|
|
GLuint v = 1;
|
|
|
|
while (s[v] != '\0' && s[v-1] != ' ') v++;
|
2013-05-19 12:42:55 +00:00
|
|
|
|
2013-06-11 11:14:26 +00:00
|
|
|
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
2015-12-20 13:01:01 +00:00
|
|
|
fprintf(stdout, "OpenGL information. GPU: %s. Vendor: %s. Driver: %s\n", glGetString(GL_RENDERER), vendor, &s[v]);
|
2013-06-11 11:14:26 +00:00
|
|
|
|
2015-08-07 12:46:57 +00:00
|
|
|
// Name changed but driver is still bad!
|
2013-06-11 11:14:26 +00:00
|
|
|
if (strstr(vendor, "ATI") || strstr(vendor, "Advanced Micro Devices"))
|
2013-05-19 12:42:55 +00:00
|
|
|
fglrx_buggy_driver = true;
|
2013-07-11 17:08:42 +00:00
|
|
|
if (strstr(vendor, "NVIDIA Corporation"))
|
|
|
|
nvidia_buggy_driver = true;
|
2013-12-30 09:30:10 +00:00
|
|
|
if (strstr(vendor, "Intel"))
|
|
|
|
intel_buggy_driver = true;
|
2015-06-30 21:04:54 +00:00
|
|
|
if (strstr(vendor, "X.Org") || strstr(vendor, "nouveau")) // Note: it might actually catch nouveau too, but bugs are likely to be the same anyway
|
2014-03-29 09:47:53 +00:00
|
|
|
mesa_amd_buggy_driver = true;
|
2014-12-12 19:44:58 +00:00
|
|
|
if (strstr(vendor, "VMware")) // Assume worst case because I don't know the real status
|
|
|
|
mesa_amd_buggy_driver = intel_buggy_driver = true;
|
2013-01-14 09:15:39 +00:00
|
|
|
|
2015-06-16 16:32:23 +00:00
|
|
|
if (mesa_amd_buggy_driver) {
|
|
|
|
fprintf(stderr, "Buggy driver detected. Geometry shaders will be disabled\n");
|
|
|
|
found_geometry_shader = false;
|
|
|
|
}
|
2013-05-27 16:53:38 +00:00
|
|
|
if (theApp.GetConfig("override_geometry_shader", -1) != -1) {
|
|
|
|
found_geometry_shader = !!theApp.GetConfig("override_geometry_shader", -1);
|
2015-06-06 19:28:59 +00:00
|
|
|
fprintf(stderr, "Overriding geometry shaders detection\n");
|
2013-05-27 16:53:38 +00:00
|
|
|
}
|
2015-07-13 10:35:55 +00:00
|
|
|
|
|
|
|
GLint major_gl = 0;
|
|
|
|
GLint minor_gl = 0;
|
|
|
|
glGetIntegerv(GL_MAJOR_VERSION, &major_gl);
|
|
|
|
glGetIntegerv(GL_MINOR_VERSION, &minor_gl);
|
2013-01-14 09:15:39 +00:00
|
|
|
if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) {
|
2015-06-30 21:04:54 +00:00
|
|
|
fprintf(stderr, "OpenGL %d.%d is not supported. Only OpenGL %d.%d\n was found", major, minor, major_gl, minor_gl);
|
2013-01-14 09:15:39 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool check_gl_supported_extension() {
|
|
|
|
int max_ext = 0;
|
|
|
|
glGetIntegerv(GL_NUM_EXTENSIONS, &max_ext);
|
|
|
|
|
2015-10-17 15:05:15 +00:00
|
|
|
if (glGetStringi && max_ext) {
|
2013-01-14 09:15:39 +00:00
|
|
|
for (GLint i = 0; i < max_ext; i++) {
|
2015-10-17 15:05:15 +00:00
|
|
|
string ext((const char*)glGetStringi(GL_EXTENSIONS, i));
|
2015-05-02 08:53:19 +00:00
|
|
|
// Bonus
|
|
|
|
if (ext.compare("GL_EXT_texture_filter_anisotropic") == 0) found_GL_EXT_texture_filter_anisotropic = true;
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.0
|
|
|
|
if (ext.compare("GL_ARB_gpu_shader5") == 0) found_GL_ARB_gpu_shader5 = true;
|
2015-05-29 16:38:19 +00:00
|
|
|
if (ext.compare("GL_ARB_draw_buffers_blend") == 0) found_GL_ARB_draw_buffers_blend = true;
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.1
|
2013-01-14 09:15:39 +00:00
|
|
|
if (ext.compare("GL_ARB_separate_shader_objects") == 0) {
|
2014-08-23 15:09:38 +00:00
|
|
|
if (!fglrx_buggy_driver && !mesa_amd_buggy_driver && !intel_buggy_driver) found_GL_ARB_separate_shader_objects = true;
|
2016-01-01 13:43:47 +00:00
|
|
|
else fprintf(stderr, "Buggy driver detected, GL_ARB_separate_shader_objects will be disabled\n"
|
|
|
|
"Note the extension was fixed on Mesa 11.1, you will need a manual overwrite to use it\n");
|
2013-01-14 09:15:39 +00:00
|
|
|
}
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.2
|
|
|
|
if (ext.compare("GL_ARB_shading_language_420pack") == 0) found_GL_ARB_shading_language_420pack = true;
|
|
|
|
if (ext.compare("GL_ARB_texture_storage") == 0) found_GL_ARB_texture_storage = true;
|
2015-05-08 08:40:43 +00:00
|
|
|
if (ext.compare("GL_ARB_shader_image_load_store") == 0) found_GL_ARB_shader_image_load_store = true;
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.3
|
|
|
|
if (ext.compare("GL_ARB_copy_image") == 0) found_GL_ARB_copy_image = true;
|
|
|
|
// GL4.4
|
|
|
|
if (ext.compare("GL_ARB_buffer_storage") == 0) found_GL_ARB_buffer_storage = true;
|
2015-05-15 18:58:14 +00:00
|
|
|
if (ext.compare("GL_ARB_clear_texture") == 0) found_GL_ARB_clear_texture = true;
|
2014-09-15 20:28:35 +00:00
|
|
|
// GL4.5
|
|
|
|
if (ext.compare("GL_ARB_direct_state_access") == 0) found_GL_ARB_direct_state_access = true;
|
|
|
|
if (ext.compare("GL_ARB_clip_control") == 0) found_GL_ARB_clip_control = true;
|
2015-04-25 07:59:25 +00:00
|
|
|
if (ext.compare("GL_ARB_texture_barrier") == 0) found_GL_ARB_texture_barrier = true;
|
2014-09-30 19:56:36 +00:00
|
|
|
|
|
|
|
//fprintf(stderr, "DEBUG ext: %s\n", ext.c_str());
|
2013-01-14 09:15:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-03 08:29:01 +00:00
|
|
|
bool status = true;
|
2013-01-14 09:15:39 +00:00
|
|
|
|
2015-05-02 08:53:19 +00:00
|
|
|
// Bonus
|
|
|
|
status &= status_and_override(found_GL_EXT_texture_filter_anisotropic, "GL_EXT_texture_filter_anisotropic");
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.0
|
2015-05-02 08:53:19 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_gpu_shader5, "GL_ARB_gpu_shader5");
|
2015-06-10 20:55:27 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_draw_buffers_blend, "GL_ARB_draw_buffers_blend");
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.1
|
2015-05-02 08:53:19 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_separate_shader_objects, "GL_ARB_separate_shader_objects");
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.2
|
2015-05-02 08:53:19 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_shader_image_load_store, "GL_ARB_shader_image_load_store");
|
|
|
|
status &= status_and_override(found_GL_ARB_shading_language_420pack, "GL_ARB_shading_language_420pack", true);
|
2013-08-03 08:29:01 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_texture_storage, "GL_ARB_texture_storage", true);
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.3
|
|
|
|
status &= status_and_override(found_GL_ARB_copy_image, "GL_ARB_copy_image");
|
|
|
|
// GL4.4
|
|
|
|
status &= status_and_override(found_GL_ARB_buffer_storage,"GL_ARB_buffer_storage");
|
2015-05-15 18:58:14 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_clear_texture,"GL_ARB_clear_texture");
|
2014-09-27 17:12:30 +00:00
|
|
|
// GL4.5
|
2014-09-07 15:27:49 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_clip_control, "GL_ARB_clip_control");
|
2014-09-28 10:11:22 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_direct_state_access, "GL_ARB_direct_state_access");
|
2015-04-25 07:59:25 +00:00
|
|
|
status &= status_and_override(found_GL_ARB_texture_barrier, "GL_ARB_texture_barrier");
|
2015-05-01 17:16:18 +00:00
|
|
|
|
2015-04-24 17:32:00 +00:00
|
|
|
if (!found_GL_ARB_direct_state_access) {
|
|
|
|
Emulate_DSA::Init();
|
|
|
|
}
|
2015-10-17 15:05:15 +00:00
|
|
|
if (glBindTextureUnit == NULL) {
|
2015-04-25 07:50:19 +00:00
|
|
|
fprintf(stderr, "FATAL ERROR !!!! Failed to setup DSA function pointer!!!\n");
|
|
|
|
status = false;
|
|
|
|
}
|
|
|
|
|
2015-05-09 16:33:28 +00:00
|
|
|
if (!found_GL_ARB_texture_barrier) {
|
2015-07-19 07:34:32 +00:00
|
|
|
fprintf(stderr, "Error GL_ARB_texture_barrier is not supported by your driver. You can't emulate correctly the GS blending unit! Sorry!\n");
|
|
|
|
theApp.SetConfig("accurate_blending_unit", 0);
|
2015-07-25 15:13:37 +00:00
|
|
|
theApp.SetConfig("accurate_date", 0);
|
2015-05-09 16:33:28 +00:00
|
|
|
}
|
|
|
|
|
2015-12-20 13:01:01 +00:00
|
|
|
#ifdef _WINDOWS
|
|
|
|
if (status) {
|
|
|
|
if (intel_buggy_driver) {
|
|
|
|
fprintf(stderr, "OpenGL renderer isn't compatible with SandyBridge/IvyBridge GPU due to issues. Sorry.\n"
|
|
|
|
"Tip:Try it on Linux");
|
|
|
|
}
|
|
|
|
if (fglrx_buggy_driver) {
|
|
|
|
fprintf(stderr, "OpenGL renderer is slow on AMD GPU due to inefficient driver. Sorry.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fprintf(stdout, "\n");
|
2013-05-26 13:05:03 +00:00
|
|
|
|
2013-08-03 08:29:01 +00:00
|
|
|
return status;
|
2013-01-14 09:15:39 +00:00
|
|
|
}
|
|
|
|
}
|