mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: GL_ARB_separate_shader_objects is now mandatory
This commit is contained in:
parent
f751f70b1e
commit
52e3c3516d
|
@ -41,15 +41,11 @@ PFNGLCLEARBUFFERFVPROC glClearBufferfv = NUL
|
|||
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;
|
||||
|
@ -69,7 +65,6 @@ PFNGLGETPROGRAMIVPROC glGetProgramiv = NUL
|
|||
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
|
||||
PFNGLGETSTRINGIPROC glGetStringi = NULL;
|
||||
PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
|
||||
PFNGLMAPBUFFERPROC glMapBuffer = NULL;
|
||||
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
|
||||
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = NULL;
|
||||
|
@ -111,10 +106,6 @@ PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf = NUL
|
|||
PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv = NULL;
|
||||
PFNGLSCISSORINDEXEDPROC glScissorIndexed = NULL;
|
||||
PFNGLSCISSORINDEXEDVPROC glScissorIndexedv = NULL;
|
||||
// NO GL4.1
|
||||
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
|
||||
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
|
||||
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = NULL;
|
||||
// GL4.3
|
||||
PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData = NULL;
|
||||
PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage = NULL;
|
||||
|
@ -350,7 +341,7 @@ namespace GLLoader {
|
|||
bool found_GL_ARB_texture_barrier = false;
|
||||
bool found_GL_ARB_clip_control = false;
|
||||
bool found_GL_ARB_direct_state_access = false;
|
||||
bool found_GL_ARB_separate_shader_objects = false; // Issue with Catalyst...
|
||||
bool found_GL_ARB_separate_shader_objects = false;
|
||||
bool found_GL_ARB_buffer_storage = false;
|
||||
// DX11 GPU
|
||||
bool found_GL_ARB_draw_buffers_blend = false; // Not supported on AMD R600 (80 nm class chip, HD2900). Nvidia requires FERMI. Intel SB
|
||||
|
@ -448,15 +439,7 @@ namespace GLLoader {
|
|||
if (ext.compare("GL_ARB_draw_buffers_blend") == 0) found_GL_ARB_draw_buffers_blend = true;
|
||||
// GL4.1
|
||||
if (ext.compare("GL_ARB_viewport_array") == 0) found_GL_ARB_viewport_array = true;
|
||||
if (ext.compare("GL_ARB_separate_shader_objects") == 0) {
|
||||
if (!fglrx_buggy_driver && !mesa_amd_buggy_driver && !intel_buggy_driver) found_GL_ARB_separate_shader_objects = true;
|
||||
else fprintf(stderr, "Buggy driver detected, GL_ARB_separate_shader_objects will be disabled\n"
|
||||
#ifdef __linux__
|
||||
"Note the extension will be fixed on Mesa 11.2 or 11.1.2.\n"
|
||||
#endif
|
||||
"AMD proprietary driver => https://community.amd.com/thread/194895\n"
|
||||
"If you want to try it, you can set the variable override_GL_ARB_separate_shader_objects to 1 in the ini file\n");
|
||||
}
|
||||
if (ext.compare("GL_ARB_separate_shader_objects") == 0) found_GL_ARB_separate_shader_objects = true;
|
||||
// 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;
|
||||
|
@ -484,7 +467,7 @@ namespace GLLoader {
|
|||
status &= status_and_override(found_GL_ARB_draw_buffers_blend, "GL_ARB_draw_buffers_blend");
|
||||
// GL4.1
|
||||
status &= status_and_override(found_GL_ARB_viewport_array, "GL_ARB_viewport_array");
|
||||
status &= status_and_override(found_GL_ARB_separate_shader_objects, "GL_ARB_separate_shader_objects");
|
||||
status &= status_and_override(found_GL_ARB_separate_shader_objects, "GL_ARB_separate_shader_objects", true);
|
||||
// GL4.2
|
||||
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);
|
||||
|
|
|
@ -215,16 +215,12 @@ extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
|||
extern PFNGLCLEARBUFFERFVPROC glClearBufferfv;
|
||||
extern PFNGLCLEARBUFFERIVPROC glClearBufferiv;
|
||||
extern PFNGLCLEARBUFFERUIVPROC glClearBufferuiv;
|
||||
extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
extern PFNGLCOLORMASKIPROC glColorMaski;
|
||||
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
extern PFNGLCREATESHADERPROC glCreateShader;
|
||||
extern PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv;
|
||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||
extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||
extern PFNGLDELETESAMPLERSPROC glDeleteSamplers;
|
||||
extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLDETACHSHADERPROC glDetachShader;
|
||||
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||
|
@ -244,7 +240,6 @@ extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
|||
extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
extern PFNGLGETSTRINGIPROC glGetStringi;
|
||||
extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
|
||||
extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
|
||||
|
@ -286,10 +281,6 @@ extern PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf;
|
|||
extern PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv;
|
||||
extern PFNGLSCISSORINDEXEDPROC glScissorIndexed;
|
||||
extern PFNGLSCISSORINDEXEDVPROC glScissorIndexedv;
|
||||
// NO GL4.1
|
||||
extern PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
|
||||
// GL4.2
|
||||
extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
|
||||
extern PFNGLMEMORYBARRIERPROC glMemoryBarrier;
|
||||
|
@ -356,7 +347,6 @@ namespace GLLoader {
|
|||
extern bool in_replayer;
|
||||
|
||||
// GL
|
||||
extern bool found_GL_ARB_separate_shader_objects;
|
||||
extern bool found_GL_ARB_copy_image;
|
||||
extern bool found_geometry_shader;
|
||||
extern bool found_GL_ARB_gpu_shader5;
|
||||
|
|
|
@ -54,8 +54,6 @@ namespace GLState {
|
|||
GLuint ps;
|
||||
GLuint gs;
|
||||
GLuint vs;
|
||||
GLuint program;
|
||||
bool dirty_prog;
|
||||
|
||||
void Clear() {
|
||||
fbo = 0;
|
||||
|
@ -91,7 +89,5 @@ namespace GLState {
|
|||
ps = 0;
|
||||
gs = 0;
|
||||
vs = 0;
|
||||
program = 0;
|
||||
dirty_prog = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,8 +56,6 @@ namespace GLState {
|
|||
extern GLuint ps;
|
||||
extern GLuint gs;
|
||||
extern GLuint vs;
|
||||
extern GLuint program; // monolith program (when sso isn't supported)
|
||||
extern bool dirty_prog;
|
||||
|
||||
extern void Clear();
|
||||
}
|
||||
|
|
|
@ -448,7 +448,6 @@ void GSDeviceOGL::Flip()
|
|||
|
||||
void GSDeviceOGL::BeforeDraw()
|
||||
{
|
||||
m_shader->UseProgram();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::AfterDraw()
|
||||
|
|
|
@ -28,16 +28,13 @@ GSShaderOGL::GSShaderOGL(bool debug) :
|
|||
m_debug_shader(debug)
|
||||
{
|
||||
m_single_prog.clear();
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
glGenProgramPipelines(1, &m_pipeline);
|
||||
glBindProgramPipeline(m_pipeline);
|
||||
}
|
||||
glGenProgramPipelines(1, &m_pipeline);
|
||||
glBindProgramPipeline(m_pipeline);
|
||||
}
|
||||
|
||||
GSShaderOGL::~GSShaderOGL()
|
||||
{
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects)
|
||||
glDeleteProgramPipelines(1, &m_pipeline);
|
||||
glDeleteProgramPipelines(1, &m_pipeline);
|
||||
|
||||
for (auto it = m_single_prog.begin(); it != m_single_prog.end() ; it++) glDeleteProgram(it->second);
|
||||
m_single_prog.clear();
|
||||
|
@ -48,9 +45,7 @@ void GSShaderOGL::VS(GLuint s)
|
|||
if (GLState::vs != s)
|
||||
{
|
||||
GLState::vs = s;
|
||||
GLState::dirty_prog = true;
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects)
|
||||
glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, s);
|
||||
glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,10 +59,7 @@ void GSShaderOGL::PS(GLuint s)
|
|||
{
|
||||
// In debug always sets the program. It allow to replace the program in apitrace easily.
|
||||
GLState::ps = s;
|
||||
GLState::dirty_prog = true;
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, s);
|
||||
}
|
||||
glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,33 +68,10 @@ void GSShaderOGL::GS(GLuint s)
|
|||
if (GLState::gs != s)
|
||||
{
|
||||
GLState::gs = s;
|
||||
GLState::dirty_prog = true;
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects)
|
||||
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, s);
|
||||
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, s);
|
||||
}
|
||||
}
|
||||
|
||||
bool GSShaderOGL::ValidateShader(GLuint s)
|
||||
{
|
||||
if (!m_debug_shader) return true;
|
||||
|
||||
GLint status = 0;
|
||||
glGetShaderiv(s, GL_COMPILE_STATUS, &status);
|
||||
if (status) return true;
|
||||
|
||||
GLint log_length = 0;
|
||||
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if (log_length > 0) {
|
||||
char* log = new char[log_length];
|
||||
glGetShaderInfoLog(s, log_length, NULL, log);
|
||||
fprintf(stderr, "%s", log);
|
||||
delete[] log;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GSShaderOGL::ValidateProgram(GLuint p)
|
||||
{
|
||||
if (!m_debug_shader) return true;
|
||||
|
@ -148,62 +117,14 @@ bool GSShaderOGL::ValidatePipeline(GLuint p)
|
|||
return false;
|
||||
}
|
||||
|
||||
GLuint GSShaderOGL::LinkNewProgram()
|
||||
{
|
||||
GLuint p = glCreateProgram();
|
||||
if (GLState::vs) glAttachShader(p, GLState::vs);
|
||||
if (GLState::ps) glAttachShader(p, GLState::ps);
|
||||
if (GLState::gs) glAttachShader(p, GLState::gs);
|
||||
|
||||
glLinkProgram(p);
|
||||
|
||||
ValidateProgram(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void GSShaderOGL::UseProgram()
|
||||
{
|
||||
if (GLState::dirty_prog) {
|
||||
if (!GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
hash_map<uint64, GLuint >::iterator it;
|
||||
// Note: shader are integer lookup pointer. They start from 1 and incr
|
||||
// every time you create a new shader OR a new program.
|
||||
// Note2: vs & gs are precompiled at startup. FGLRX and radeon got value < 128. GS has only 2 programs
|
||||
// We migth be able to pack the value in a 32bits int
|
||||
// I would need to check the behavior on Nvidia (pause/resume).
|
||||
uint64 sel = (uint64)GLState::vs << 40 | (uint64)GLState::gs << 20 | GLState::ps;
|
||||
it = m_single_prog.find(sel);
|
||||
if (it == m_single_prog.end()) {
|
||||
GLState::program = LinkNewProgram();
|
||||
m_single_prog[sel] = GLState::program;
|
||||
|
||||
ValidateProgram(GLState::program);
|
||||
|
||||
glUseProgram(GLState::program);
|
||||
} else {
|
||||
GLuint prog = it->second;
|
||||
if (prog != GLState::program) {
|
||||
GLState::program = prog;
|
||||
glUseProgram(GLState::program);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLState::dirty_prog = false;
|
||||
}
|
||||
|
||||
std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, const std::string& macro)
|
||||
{
|
||||
std::string header;
|
||||
header = "#version 330 core\n";
|
||||
// Need GL version 420
|
||||
header += "#extension GL_ARB_shading_language_420pack: require\n";
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
// Need GL version 410
|
||||
header += "#extension GL_ARB_separate_shader_objects: require\n";
|
||||
}
|
||||
// Need GL version 410
|
||||
header += "#extension GL_ARB_separate_shader_objects: require\n";
|
||||
if (GLLoader::found_GL_ARB_shader_image_load_store) {
|
||||
// Need GL version 420
|
||||
header += "#extension GL_ARB_shader_image_load_store: require\n";
|
||||
|
@ -263,19 +184,9 @@ GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& ent
|
|||
sources[0] = header.append(glsl_h_code).c_str();
|
||||
#endif
|
||||
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
program = glCreateShaderProgramv(type, shader_nb, sources);
|
||||
} else {
|
||||
program = glCreateShader(type);
|
||||
glShaderSource(program, shader_nb, sources, NULL);
|
||||
glCompileShader(program);
|
||||
}
|
||||
program = glCreateShaderProgramv(type, shader_nb, sources);
|
||||
|
||||
bool status;
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects)
|
||||
status = ValidateProgram(program);
|
||||
else
|
||||
status = ValidateShader(program);
|
||||
bool status = ValidateProgram(program);
|
||||
|
||||
if (!status) {
|
||||
// print extra info
|
||||
|
@ -347,9 +258,5 @@ int GSShaderOGL::DumpAsm(const std::string& file, GLuint p)
|
|||
|
||||
void GSShaderOGL::Delete(GLuint s)
|
||||
{
|
||||
if (GLLoader::found_GL_ARB_separate_shader_objects) {
|
||||
glDeleteProgram(s);
|
||||
} else {
|
||||
glDeleteShader(s);
|
||||
}
|
||||
glDeleteProgram(s);
|
||||
}
|
||||
|
|
|
@ -26,12 +26,10 @@ class GSShaderOGL {
|
|||
hash_map<uint64, GLuint > m_single_prog;
|
||||
const bool m_debug_shader;
|
||||
|
||||
bool ValidateShader(GLuint p);
|
||||
bool ValidateProgram(GLuint p);
|
||||
bool ValidatePipeline(GLuint p);
|
||||
|
||||
std::string GenGlslHeader(const std::string& entry, GLenum type, const std::string& macro);
|
||||
GLuint LinkNewProgram();
|
||||
|
||||
public:
|
||||
GSShaderOGL(bool debug);
|
||||
|
@ -41,8 +39,6 @@ class GSShaderOGL {
|
|||
void PS(GLuint s);
|
||||
void VS(GLuint s);
|
||||
|
||||
void UseProgram();
|
||||
|
||||
GLuint Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel = "");
|
||||
|
||||
int DumpAsm(const std::string& file, GLuint p);
|
||||
|
|
|
@ -100,15 +100,14 @@ void GSWndGL::PopulateGlFunction()
|
|||
GL_EXT_LOAD_OPT(glBlendEquationSeparateiARB);
|
||||
GL_EXT_LOAD_OPT(glBlendFuncSeparateiARB);
|
||||
// GL4.1
|
||||
GL_EXT_LOAD_OPT(glCreateShaderProgramv);
|
||||
GL_EXT_LOAD_OPT(glBindProgramPipeline);
|
||||
GL_EXT_LOAD_OPT(glDeleteProgramPipelines);
|
||||
GL_EXT_LOAD_OPT(glGenProgramPipelines);
|
||||
GL_EXT_LOAD_OPT(glGetProgramPipelineiv);
|
||||
GL_EXT_LOAD_OPT(glGetProgramPipelineInfoLog);
|
||||
GL_EXT_LOAD_OPT(glValidateProgramPipeline);
|
||||
GL_EXT_LOAD_OPT(glUseProgramStages);
|
||||
GL_EXT_LOAD_OPT(glProgramUniform1i); // but no GL4.2
|
||||
GL_EXT_LOAD(glCreateShaderProgramv);
|
||||
GL_EXT_LOAD(glBindProgramPipeline);
|
||||
GL_EXT_LOAD(glDeleteProgramPipelines);
|
||||
GL_EXT_LOAD(glGenProgramPipelines);
|
||||
GL_EXT_LOAD(glGetProgramPipelineiv);
|
||||
GL_EXT_LOAD(glGetProgramPipelineInfoLog);
|
||||
GL_EXT_LOAD(glValidateProgramPipeline);
|
||||
GL_EXT_LOAD(glUseProgramStages);
|
||||
GL_EXT_LOAD_OPT(glGetProgramBinary);
|
||||
GL_EXT_LOAD_OPT(glViewportIndexedf);
|
||||
GL_EXT_LOAD_OPT(glViewportIndexedfv);
|
||||
|
@ -116,13 +115,6 @@ void GSWndGL::PopulateGlFunction()
|
|||
GL_EXT_LOAD_OPT(glScissorIndexedv);
|
||||
// NO GL4.1
|
||||
GL_EXT_LOAD(glDeleteProgram);
|
||||
GL_EXT_LOAD(glDeleteShader);
|
||||
GL_EXT_LOAD(glCompileShader);
|
||||
GL_EXT_LOAD(glCreateProgram);
|
||||
GL_EXT_LOAD(glCreateShader);
|
||||
GL_EXT_LOAD(glUseProgram);
|
||||
GL_EXT_LOAD(glGetShaderInfoLog);
|
||||
GL_EXT_LOAD(glLinkProgram);
|
||||
// GL4.2
|
||||
GL_EXT_LOAD_OPT(glBindImageTexture);
|
||||
GL_EXT_LOAD_OPT(glMemoryBarrier);
|
||||
|
|
Loading…
Reference in New Issue