diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index b0eb286275..c02c5d6e7b 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -224,7 +224,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs); CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs); - for(int i = 0; i < countof(m_convert.ps); i++) + for(uint i = 0; i < countof(m_convert.ps); i++) CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i]); // Note the following object are initialized to 0 so disabled. @@ -252,7 +252,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameteri(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX); + glSamplerParameterf(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX); // FIXME: seems there is 2 possibility in opengl // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; // glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_NONE); @@ -268,7 +268,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameteri(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX); + glSamplerParameterf(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX); // FIXME: seems there is 2 possibility in opengl // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; // glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_NONE); @@ -284,7 +284,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** m_merge_obj.cb = new GSUniformBufferOGL(1, sizeof(MergeConstantBuffer)); - for(int i = 0; i < countof(m_merge_obj.ps); i++) + for(uint i = 0; i < countof(m_merge_obj.ps); i++) CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i]); m_merge_obj.bs = new GSBlendStateOGL(); @@ -296,7 +296,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** m_interlace.cb = new GSUniformBufferOGL(2, sizeof(InterlaceConstantBuffer)); - for(int i = 0; i < countof(m_interlace.ps); i++) + for(uint i = 0; i < countof(m_interlace.ps); i++) CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i]); // **************************************************************** // Shade boost @@ -1167,8 +1167,6 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer) void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref) { - uint ref = sref; - if(m_state.dss != dss) { m_state.dss = dss; m_state.sref = sref; diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index a8b1223f4a..dfa580e6ca 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -25,6 +25,8 @@ #include "GSDevice.h" #include "GSTextureOGL.h" #include "GSdx.h" +#include "GSVertexArrayOGL.h" +#include "GSUniformBufferOGL.h" class GSBlendStateOGL { // Note: You can also select the index of the draw buffer for which to set the blend setting @@ -228,281 +230,6 @@ public: } }; -class GSUniformBufferOGL { - GLuint buffer; // data object - GLuint index; // GLSL slot - uint size; // size of the data - const GLenum target; - -public: - GSUniformBufferOGL(GLuint index, uint size) : index(index) - , size(size) - ,target(GL_UNIFORM_BUFFER) - { - glGenBuffers(1, &buffer); - bind(); - allocate(); - attach(); - } - - void bind() - { - glBindBuffer(target, buffer); - } - - void allocate() - { - glBufferData(target, size, NULL, GL_STREAM_DRAW); - } - - void attach() - { - glBindBufferBase(target, index, buffer); - } - - void upload(const void* src) - { - uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; - uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags); - memcpy(dst, src, size); - glUnmapBuffer(target); - } - - ~GSUniformBufferOGL() { - glDeleteBuffers(1, &buffer); - } -}; - -struct GSInputLayoutOGL { - GLuint index; - GLint size; - GLenum type; - GLboolean normalize; - GLsizei stride; - const GLvoid* offset; -}; - -class GSVertexBufferStateOGL { - class GSBufferOGL { - size_t m_stride; - size_t m_start; - size_t m_count; - size_t m_limit; - GLenum m_target; - GLuint m_buffer; - size_t m_default_size; - - public: - GSBufferOGL(GLenum target, size_t stride) : - m_stride(stride) - , m_start(0) - , m_count(0) - , m_limit(0) - , m_target(target) - { - glGenBuffers(1, &m_buffer); - // Opengl works best with 1-4MB buffer. - m_default_size = 2 * 1024 * 1024 / m_stride; - } - - ~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); } - - void allocate() { allocate(m_default_size); } - - void allocate(size_t new_limit) - { - m_start = 0; - m_limit = new_limit; - glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW); - } - - void bind() - { - glBindBuffer(m_target, m_buffer); - } - - void upload(const void* src, uint32 count) - { - // Upload the data to the buffer - void* dst; - if (Map(&dst, count)) { - // FIXME which one to use - // GSVector4i::storent(dst, src, m_count * m_stride); - memcpy(dst, src, m_stride*m_count); - Unmap(); - } - } - - bool Map(void** pointer, uint32 count ) { -#ifdef OGL_DEBUG - GLint b_size = -1; - glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); - - if (b_size <= 0) return false; -#endif - - m_count = count; - - // Note: For an explanation of the map flag - // see http://www.opengl.org/wiki/Buffer_Object_Streaming - uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; - - // Current GPU buffer is really too small need to allocate a new one - if (m_count > m_limit) { - allocate(std::max(m_count * 3 / 2, m_default_size)); - - } else if (m_count > (m_limit - m_start) ) { - // Not enough left free room. Just go back at the beginning - m_start = 0; - - // Tell the driver that it can orphan previous buffer and restart from a scratch buffer. - // Technically the buffer will not be accessible by the application anymore but the - // GL will effectively remove it when draws call are finised. - map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT; - } else { - // Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map - map_flags |= GL_MAP_INVALIDATE_RANGE_BIT; - } - - // Upload the data to the buffer - *pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); - //fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count); -#ifdef OGL_DEBUG - if (*pointer == NULL) { - fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); - return false; - } -#endif - return true; - } - - void Unmap() { glUnmapBuffer(m_target); } - - void EndScene() - { - m_start += m_count; - m_count = 0; - } - - void Draw(GLenum mode) - { - glDrawArrays(mode, m_start, m_count); - } - - void Draw(GLenum mode, GLint basevertex) - { - glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex); - } - - void Draw(GLenum mode, GLint basevertex, int offset, int count) - { - glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex); - } - - size_t GetStart() { return m_start; } - - void debug() - { - fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count); - } - - } *m_vb, *m_ib; - - GLuint m_va; - GLenum m_topology; - -public: - GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr) - { - glGenVertexArrays(1, &m_va); - - m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride); - m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32)); - - bind(); - // Note: index array are part of the VA state so it need to be bind only once. - m_ib->bind(); - - m_vb->allocate(); - m_ib->allocate(); - set_internal_format(layout, layout_nbr); - } - - void bind() - { - glBindVertexArray(m_va); - m_vb->bind(); - } - - void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr) - { - for (int i = 0; i < layout_nbr; i++) { - // Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer - glEnableVertexAttribArray(layout[i].index); - switch (layout[i].type) { - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - // Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I) - glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset); - break; - default: - glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset); - break; - } - } - } - - void EndScene() - { - m_vb->EndScene(); - m_ib->EndScene(); - } - - void DrawPrimitive() { m_vb->Draw(m_topology); } - - void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); } - - void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); } - - void SetTopology(GLenum topology) { m_topology = topology; } - - void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); } - - void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); } - - bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); } - - void UnmapVB() { m_vb->Unmap(); } - - ~GSVertexBufferStateOGL() - { - glDeleteVertexArrays(1, &m_va); - } - - void debug() - { - string topo; - switch (m_topology) { - case GL_POINTS: - topo = "point"; - break; - case GL_LINES: - topo = "line"; - break; - case GL_TRIANGLES: - topo = "triangle"; - break; - case GL_TRIANGLE_STRIP: - topo = "triangle strip"; - break; - } - m_vb->debug(); - m_ib->debug(); - fprintf(stderr, "primitives of %s\n", topo.c_str()); - - } -}; - class GSDeviceOGL : public GSDevice { public: diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index e7eb694af3..ef354d7758 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -38,7 +38,7 @@ void GSDeviceOGL::CreateTextureFX() glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX); + glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX); // FIXME: seems there is 2 possibility in opengl // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; // glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE); @@ -225,7 +225,7 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS glSamplerParameteri(ss0, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX); + glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX); // FIXME: seems there is 2 possibility in opengl // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; // glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE); diff --git a/plugins/GSdx/GSUniformBufferOGL.h b/plugins/GSdx/GSUniformBufferOGL.h new file mode 100644 index 0000000000..fce882a332 --- /dev/null +++ b/plugins/GSdx/GSUniformBufferOGL.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011-2011 Gregory hainaut + * 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +class GSUniformBufferOGL { + GLuint buffer; // data object + GLuint index; // GLSL slot + uint size; // size of the data + const GLenum target; + +public: + GSUniformBufferOGL(GLuint index, uint size) : index(index) + , size(size) + ,target(GL_UNIFORM_BUFFER) + { + glGenBuffers(1, &buffer); + bind(); + allocate(); + attach(); + } + + void bind() + { + glBindBuffer(target, buffer); + } + + void allocate() + { + glBufferData(target, size, NULL, GL_STREAM_DRAW); + } + + void attach() + { + glBindBufferBase(target, index, buffer); + } + + void upload(const void* src) + { + uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags); + memcpy(dst, src, size); + glUnmapBuffer(target); + } + + ~GSUniformBufferOGL() { + glDeleteBuffers(1, &buffer); + } +}; diff --git a/plugins/GSdx/GSVertexArrayOGL.h b/plugins/GSdx/GSVertexArrayOGL.h new file mode 100644 index 0000000000..f63882d27d --- /dev/null +++ b/plugins/GSdx/GSVertexArrayOGL.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2011-2011 Gregory hainaut + * 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#pragma once + +struct GSInputLayoutOGL { + GLuint index; + GLint size; + GLenum type; + GLboolean normalize; + GLsizei stride; + const GLvoid* offset; +}; + +class GSVertexBufferStateOGL { + class GSBufferOGL { + size_t m_stride; + size_t m_start; + size_t m_count; + size_t m_limit; + GLenum m_target; + GLuint m_buffer; + size_t m_default_size; + + public: + GSBufferOGL(GLenum target, size_t stride) : + m_stride(stride) + , m_start(0) + , m_count(0) + , m_limit(0) + , m_target(target) + { + glGenBuffers(1, &m_buffer); + // Opengl works best with 1-4MB buffer. + m_default_size = 2 * 1024 * 1024 / m_stride; + } + + ~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); } + + void allocate() { allocate(m_default_size); } + + void allocate(size_t new_limit) + { + m_start = 0; + m_limit = new_limit; + glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW); + } + + void bind() + { + glBindBuffer(m_target, m_buffer); + } + + void upload(const void* src, uint32 count) + { + // Upload the data to the buffer + void* dst; + if (Map(&dst, count)) { + // FIXME which one to use + // GSVector4i::storent(dst, src, m_count * m_stride); + memcpy(dst, src, m_stride*m_count); + Unmap(); + } + } + + bool Map(void** pointer, uint32 count ) { +#ifdef OGL_DEBUG + GLint b_size = -1; + glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); + + if (b_size <= 0) return false; +#endif + + m_count = count; + + // Note: For an explanation of the map flag + // see http://www.opengl.org/wiki/Buffer_Object_Streaming + uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + + // Current GPU buffer is really too small need to allocate a new one + if (m_count > m_limit) { + allocate(std::max(m_count * 3 / 2, m_default_size)); + + } else if (m_count > (m_limit - m_start) ) { + // Not enough left free room. Just go back at the beginning + m_start = 0; + + // Tell the driver that it can orphan previous buffer and restart from a scratch buffer. + // Technically the buffer will not be accessible by the application anymore but the + // GL will effectively remove it when draws call are finised. + map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT; + } else { + // Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map + map_flags |= GL_MAP_INVALIDATE_RANGE_BIT; + } + + // Upload the data to the buffer + *pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); + //fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count); +#ifdef OGL_DEBUG + if (*pointer == NULL) { + fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); + return false; + } +#endif + return true; + } + + void Unmap() { glUnmapBuffer(m_target); } + + void EndScene() + { + m_start += m_count; + m_count = 0; + } + + void Draw(GLenum mode) + { + glDrawArrays(mode, m_start, m_count); + } + + void Draw(GLenum mode, GLint basevertex) + { + glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex); + } + + void Draw(GLenum mode, GLint basevertex, int offset, int count) + { + glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex); + } + + size_t GetStart() { return m_start; } + + void debug() + { + fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count); + } + + } *m_vb, *m_ib; + + GLuint m_va; + GLenum m_topology; + +public: + GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr) + { + glGenVertexArrays(1, &m_va); + + m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride); + m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32)); + + bind(); + // Note: index array are part of the VA state so it need to be bind only once. + m_ib->bind(); + + m_vb->allocate(); + m_ib->allocate(); + set_internal_format(layout, layout_nbr); + } + + void bind() + { + glBindVertexArray(m_va); + m_vb->bind(); + } + + void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr) + { + for (uint i = 0; i < layout_nbr; i++) { + // Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer + glEnableVertexAttribArray(layout[i].index); + switch (layout[i].type) { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + // Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I) + glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset); + break; + default: + glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset); + break; + } + } + } + + void EndScene() + { + m_vb->EndScene(); + m_ib->EndScene(); + } + + void DrawPrimitive() { m_vb->Draw(m_topology); } + + void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); } + + void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); } + + void SetTopology(GLenum topology) { m_topology = topology; } + + void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); } + + void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); } + + bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); } + + void UnmapVB() { m_vb->Unmap(); } + + ~GSVertexBufferStateOGL() + { + glDeleteVertexArrays(1, &m_va); + } + + void debug() + { + string topo; + switch (m_topology) { + case GL_POINTS: + topo = "point"; + break; + case GL_LINES: + topo = "line"; + break; + case GL_TRIANGLES: + topo = "triangle"; + break; + case GL_TRIANGLE_STRIP: + topo = "triangle strip"; + break; + } + m_vb->debug(); + m_ib->debug(); + fprintf(stderr, "primitives of %s\n", topo.c_str()); + + } +}; diff --git a/plugins/zzogl-pg/opengl/GLWinX11.cpp b/plugins/zzogl-pg/opengl/GLWinX11.cpp index ed286c196e..bfd5b1c989 100644 --- a/plugins/zzogl-pg/opengl/GLWinX11.cpp +++ b/plugins/zzogl-pg/opengl/GLWinX11.cpp @@ -230,7 +230,7 @@ void GLWindow::CreateContextGL() { #if defined(OGL4_LOG) || defined(GLSL4_API) // We need to define a debug context. So we need at a 3.0 context (if not 3.2 actually) - CreateContextGL(4, 2); + CreateContextGL(3, 3); #else // FIXME there was some issue with previous context creation on Geforce7. Code was rewritten // for GSdx unfortunately it was not tested on Geforce7 so keep the 2.0 context for now. diff --git a/plugins/zzogl-pg/opengl/GSUniformBufferOGL.h b/plugins/zzogl-pg/opengl/GSUniformBufferOGL.h new file mode 100644 index 0000000000..b66e893caa --- /dev/null +++ b/plugins/zzogl-pg/opengl/GSUniformBufferOGL.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011-2011 Gregory hainaut + * 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +// Note: it is same code that was developed for GSdx plugin + +#pragma once + +#ifdef GLSL4_API +class GSUniformBufferOGL { + GLuint buffer; // data object + GLuint index; // GLSL slot + uint size; // size of the data + const GLenum target; + +public: + GSUniformBufferOGL(GLuint index, uint size) : index(index) + , size(size) + ,target(GL_UNIFORM_BUFFER) + { + glGenBuffers(1, &buffer); + bind(); + allocate(); + attach(); + } + + void bind() + { + glBindBuffer(target, buffer); + } + + void allocate() + { + glBufferData(target, size, NULL, GL_STREAM_DRAW); + } + + void attach() + { + glBindBufferBase(target, index, buffer); + } + + void upload(const void* src) + { + uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags); + memcpy(dst, src, size); + glUnmapBuffer(target); + } + + ~GSUniformBufferOGL() { + glDeleteBuffers(1, &buffer); + } +}; +#endif diff --git a/plugins/zzogl-pg/opengl/GSVertexArrayOGL.h b/plugins/zzogl-pg/opengl/GSVertexArrayOGL.h new file mode 100644 index 0000000000..db836ed445 --- /dev/null +++ b/plugins/zzogl-pg/opengl/GSVertexArrayOGL.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2011-2011 Gregory hainaut + * 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +// Note: it is same code that was developed for GSdx plugin + +#pragma once + +#ifdef GLSL4_API +struct GSInputLayoutOGL { + GLuint index; + GLint size; + GLenum type; + GLboolean normalize; + GLsizei stride; + const GLvoid* offset; +}; + +class GSVertexBufferStateOGL { + class GSBufferOGL { + size_t m_stride; + size_t m_start; + size_t m_count; + size_t m_limit; + GLenum m_target; + GLuint m_buffer; + size_t m_default_size; + + public: + GSBufferOGL(GLenum target, size_t stride) : + m_stride(stride) + , m_start(0) + , m_count(0) + , m_limit(0) + , m_target(target) + { + glGenBuffers(1, &m_buffer); + // Opengl works best with 1-4MB buffer. + m_default_size = 2 * 1024 * 1024 / m_stride; + } + + ~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); } + + void allocate() { allocate(m_default_size); } + + void allocate(size_t new_limit) + { + m_start = 0; + m_limit = new_limit; + glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW); + } + + void bind() + { + glBindBuffer(m_target, m_buffer); + } + + void upload(const void* src, uint32 count) + { + // Upload the data to the buffer + void* dst; + if (Map(&dst, count)) { + // FIXME which one to use + // GSVector4i::storent(dst, src, m_count * m_stride); + memcpy(dst, src, m_stride*m_count); + Unmap(); + } + } + + bool Map(void** pointer, uint32 count ) { +#ifdef OGL_DEBUG + GLint b_size = -1; + glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); + + if (b_size <= 0) return false; +#endif + + m_count = count; + + // Note: For an explanation of the map flag + // see http://www.opengl.org/wiki/Buffer_Object_Streaming + uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + + // Current GPU buffer is really too small need to allocate a new one + if (m_count > m_limit) { + allocate(std::max(m_count * 3 / 2, m_default_size)); + + } else if (m_count > (m_limit - m_start) ) { + // Not enough left free room. Just go back at the beginning + m_start = 0; + + // Tell the driver that it can orphan previous buffer and restart from a scratch buffer. + // Technically the buffer will not be accessible by the application anymore but the + // GL will effectively remove it when draws call are finised. + map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT; + } else { + // Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map + map_flags |= GL_MAP_INVALIDATE_RANGE_BIT; + } + + // Upload the data to the buffer + *pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); + //fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count); +#ifdef OGL_DEBUG + if (*pointer == NULL) { + fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); + return false; + } +#endif + return true; + } + + void Unmap() { glUnmapBuffer(m_target); } + + void EndScene() + { + m_start += m_count; + m_count = 0; + } + + void Draw(GLenum mode) + { + glDrawArrays(mode, m_start, m_count); + } + + void Draw(GLenum mode, GLint basevertex) + { + glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex); + } + + void Draw(GLenum mode, GLint basevertex, int offset, int count) + { + glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex); + } + + size_t GetStart() { return m_start; } + + void debug() + { + fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count); + } + + } *m_vb, *m_ib; + + GLuint m_va; + GLenum m_topology; + +public: + GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr) + { + glGenVertexArrays(1, &m_va); + + m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride); + m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32)); + + bind(); + // Note: index array are part of the VA state so it need to be bind only once. + m_ib->bind(); + + m_vb->allocate(); + m_ib->allocate(); + set_internal_format(layout, layout_nbr); + } + + void bind() + { + glBindVertexArray(m_va); + m_vb->bind(); + } + + void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr) + { + for (uint i = 0; i < layout_nbr; i++) { + // Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer + glEnableVertexAttribArray(layout[i].index); + switch (layout[i].type) { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + // Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I) + glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset); + break; + default: + glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset); + break; + } + } + } + + void EndScene() + { + m_vb->EndScene(); + m_ib->EndScene(); + } + + void DrawPrimitive() { m_vb->Draw(m_topology); } + + void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); } + + void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); } + + void SetTopology(GLenum topology) { m_topology = topology; } + + void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); } + + void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); } + + bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); } + + void UnmapVB() { m_vb->Unmap(); } + + ~GSVertexBufferStateOGL() + { + glDeleteVertexArrays(1, &m_va); + } + + void debug() + { + string topo; + switch (m_topology) { + case GL_POINTS: + topo = "point"; + break; + case GL_LINES: + topo = "line"; + break; + case GL_TRIANGLES: + topo = "triangle"; + break; + case GL_TRIANGLE_STRIP: + topo = "triangle strip"; + break; + } + m_vb->debug(); + m_ib->debug(); + fprintf(stderr, "primitives of %s\n", topo.c_str()); + + } +}; +#endif diff --git a/plugins/zzogl-pg/opengl/Util.h b/plugins/zzogl-pg/opengl/Util.h index 387a514efa..b4f4b2ab53 100644 --- a/plugins/zzogl-pg/opengl/Util.h +++ b/plugins/zzogl-pg/opengl/Util.h @@ -72,6 +72,16 @@ extern "C" u32 CALLBACK PS2EgetLibVersion2(u32 type); extern "C" char* CALLBACK PS2EgetLibName(void); #endif +// Allow easy copy/past between GSdx and zzogl +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned long long uint64; +typedef signed long long int64; + #include "ZZoglMath.h" #include "Profile.h" #include "GSDump.h" diff --git a/plugins/zzogl-pg/opengl/ZZoglShaders.h b/plugins/zzogl-pg/opengl/ZZoglShaders.h index 6dd3141aea..be7e9294a5 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShaders.h +++ b/plugins/zzogl-pg/opengl/ZZoglShaders.h @@ -59,6 +59,10 @@ inline bool ZZshActiveParameter(ZZshParameter param) {return (param !=NULL); } #endif // end NVIDIA cg-toolkit API +#ifdef GLSL4_API +#include "GSUniformBufferOGL.h" +#endif + #ifdef GLSL_API enum ZZshPARAMTYPE { @@ -118,53 +122,6 @@ enum { ZZSH_CTX_ALL = 2 }; -class GSUniformBufferOGL { - GLuint buffer; // data object - GLuint index; // GLSL slot - uint size; // size of the data - const GLenum target; - -public: - GSUniformBufferOGL(GLuint index, uint size) : index(index) - , size(size) - ,target(GL_UNIFORM_BUFFER) - { - glGenBuffers(1, &buffer); - bind(); - allocate(); - attach(); - } - - void bind() - { - glBindBuffer(target, buffer); - } - - void allocate() - { - glBufferData(target, size, NULL, GL_STREAM_DRAW); - } - - void attach() - { - glBindBufferBase(target, index, buffer); - } - - void upload(const void* src) - { - u32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; - u8* dst = (u8*) glMapBufferRange(target, 0, size, flags); - memcpy(dst, src, size); - glUnmapBuffer(target); - } - - ~GSUniformBufferOGL() { - glDeleteBuffers(1, &buffer); - } -}; - - - // Note A nice template could be better // Warning order is important for buffer (see GLSL) // Note must be keep POD (so you can map it to GLSL) diff --git a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp index 5e226704b3..c87bed1676 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp @@ -93,9 +93,6 @@ ZZshProgram ZZshMainProgram; char* ZZshSource; // Shader's source data. off_t ZZshSourceSize; -extern char* EFFECT_NAME; // All this variables used for testing and set manually -extern char* EFFECT_DIR; - bool g_bCRTCBilinear = true; float4 g_vdepth, vlogz; @@ -109,37 +106,23 @@ VERTEXSHADER pvsBitBlt; inline bool LoadEffects(); extern bool s_bWriteDepth; -struct SHADERHEADER -{ - unsigned int index, offset, size; // if highest bit of index is set, pixel shader -}; -map mapShaderResources; - // Debug variable, store name of the function that call the shader. const char* ShaderCallerName = ""; const char* ShaderHandleName = ""; int NumActiveUniforms, NumGlobalUniforms; -ZZshParamInfo UniformsIndex[MAX_ACTIVE_UNIFORMS] = {qZero}; const char* ShaderNames[MAX_ACTIVE_SHADERS] = {""}; ZZshShaderType ShaderTypes[MAX_ACTIVE_SHADERS] = {ZZ_SH_NONE}; ZZshProgram CompiledPrograms[MAX_ACTIVE_SHADERS][MAX_ACTIVE_SHADERS] = {{0}}; -const char* TextureUnits[NUMBER_OF_SAMPLERS] = - {"g_sMemory[0]", "g_sMemory[1]", "g_sSrcFinal", "g_sBitwiseANDX", "g_sBitwiseANDY", "g_sInterlace", \ - "g_sCLUT", "g_sBlocks", "g_sBilinearBlocks", "g_sConv16to32", "g_sConv32to16"}; -ZZshPARAMTYPE TextureTypes[NUMBER_OF_SAMPLERS] = - {ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, \ - ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_3D} ; -#ifdef GLSL4_API +// new for GLSL4 GSUniformBufferOGL *constant_buffer; GSUniformBufferOGL *common_buffer; GSUniformBufferOGL *vertex_buffer; GSUniformBufferOGL *fragment_buffer; COMMONSHADER g_cs; -#endif //------------------ Code @@ -162,28 +145,6 @@ void HandleCgError(ZZshContext ctx, ZZshError err, void* appdata) */ } -float ZeroFloat4[4] = {0}; - -inline void SettleFloat(float* f, const float* v) { - f[0] = v[0]; - f[1] = v[1]; - f[2] = v[2]; - f[3] = v[3]; -} - -inline ZZshParamInfo ParamInfo(const char* ShName, ZZshPARAMTYPE type, const float fvalue[], GLuint sampler, GLint texid, bool Constant, bool Settled) { - ZZshParamInfo x; - x.ShName = new char[MAX_UNIFORM_NAME_SIZE]; - x.ShName = ShName; - x.type = type; - SettleFloat(x.fvalue, fvalue); - x.sampler = sampler; - x.texid = texid; - x.Constant = Constant; - x.Settled = Settled; - return x; -} - bool ZZshStartUsingShaders() { ZZLog::Error_Log("Creating effects."); @@ -331,25 +292,6 @@ void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) { const GLchar * EmptyVertex = "void main(void) {gl_Position = ftransform();}"; const GLchar * EmptyFragment = "void main(void) {gl_FragColor = gl_Color;}"; -inline ZZshProgram UseEmptyProgram(const char* name, GLenum shaderType) { - GLuint shader = glCreateShader(shaderType); - if (shaderType == GL_VERTEX_SHADER) - glShaderSource(shader, 1, &EmptyVertex, NULL); - else - glShaderSource(shader, 1, &EmptyFragment, NULL); - - glCompileShader(shader); - ZZshProgram prog = glCreateProgram(); - glAttachShader(prog, shader); - glLinkProgram(prog); - if( !glIsProgram(prog) || glGetError() != GL_NO_ERROR ) { - ZZLog::Error_Log("Failed to load empty shader for %s:", name); - return -1; - } - ZZLog::Error_Log("Used Empty program for %s... Ok.",name); - return prog; -} - ZZshShaderType ZZshGetShaderType(const char* name) { if (strncmp(name, "TextureFog", 10) == 0) return ZZ_SH_TEXTURE_FOG; if (strncmp(name, "Texture", 7) == 0) return ZZ_SH_TEXTURE; @@ -381,10 +323,10 @@ inline bool GetCompilationLog(GLuint shader) { if (CompileStatus == GL_TRUE) return true; - int* lenght, infologlength; + int lenght, infologlength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologlength); char* InfoLog = new char[infologlength]; - glGetShaderInfoLog(shader, infologlength, lenght, InfoLog); + glGetShaderInfoLog(shader, infologlength, &lenght, InfoLog); ZZLog::Error_Log("Compiling... %d:\t %s", shader, InfoLog); return false; @@ -413,6 +355,10 @@ inline bool CompileShader(ZZshProgram& shader, const char* DefineString, const c } inline bool LoadShaderFromFile(ZZshShader& shader, const char* DefineString, const char* name, GLenum ShaderType) { // Linux specific, as I presume + + // Emit annotation for apitrace + // if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, DefineString); + if (!CompileShader(shader, DefineString, name, ShaderType)) { ZZLog::Error_Log("Failed to compile shader for %s: ", name); return false; @@ -454,10 +400,10 @@ static bool ValidateProgram(ZZshProgram Prog) { if (!isValid) { glValidateProgram(Prog); - int* lenght, infologlength; + int lenght, infologlength; glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength); char* InfoLog = new char[infologlength]; - glGetProgramInfoLog(Prog, infologlength, lenght, InfoLog); + glGetProgramInfoLog(Prog, infologlength, &lenght, InfoLog); ZZLog::Error_Log("Validation %d... %d:\t %s", Prog, infologlength, InfoLog); } return (isValid != 0); @@ -542,8 +488,14 @@ void ZZshSetPixelShader(ZZshShaderLink prog) { //------------------------------------------------------------------------------------------------------------------ -#ifdef GLSL4_API static void init_shader() { + // TODO: + // Note it would be more clever to allocate buffer inside SHADER class + // Add a dirty flags to avoid to upload twice same data... + // You need to attach() properly the uniform buffer; + // Note: don't put GSUniformBuffer creation inside constructor of static object (context won't + // be set to call gl command) + // Warning put same order than GLSL constant_buffer = new GSUniformBufferOGL(0, sizeof(ConstantUniform)); common_buffer = new GSUniformBufferOGL(1, sizeof(GlobalUniform)); @@ -565,55 +517,13 @@ static void PutParametersInProgam(VERTEXSHADER* vs, FRAGMENTSHADER* ps, int cont fragment_buffer->bind(); fragment_buffer->upload((void*)&ps->uniform_buffer[context]); - // FIXME DEBUG -#ifdef _DEBUG - GLint cb_idx = glGetUniformBlockIndex(ZZshMainProgram, "constant_buffer"); - GLint co_idx = glGetUniformBlockIndex(ZZshMainProgram, "common_buffer"); - GLint fb_idx = glGetUniformBlockIndex(ZZshMainProgram, "fragment_buffer"); - GLint vb_idx = glGetUniformBlockIndex(ZZshMainProgram, "vertex_buffer"); - - GLint debug; - - ZZLog::Error_Log("NEW !!!"); - if (cb_idx != GL_INVALID_INDEX) { - glGetActiveUniformBlockiv(ZZshMainProgram, cb_idx, GL_UNIFORM_BLOCK_BINDING, &debug); - ZZLog::Error_Log("cb active : %d", debug); - glGetActiveUniformBlockiv(ZZshMainProgram, cb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug); - ZZLog::Error_Log("size : %d", debug); - } - - if (co_idx != GL_INVALID_INDEX) { - glGetActiveUniformBlockiv(ZZshMainProgram, co_idx, GL_UNIFORM_BLOCK_BINDING, &debug); - ZZLog::Error_Log("co active : %d", debug); - glGetActiveUniformBlockiv(ZZshMainProgram, co_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug); - ZZLog::Error_Log("size : %d", debug); - } - - if (vb_idx != GL_INVALID_INDEX) { - glGetActiveUniformBlockiv(ZZshMainProgram, vb_idx, GL_UNIFORM_BLOCK_BINDING, &debug); - ZZLog::Error_Log("vb active : %d", debug); - glGetActiveUniformBlockiv(ZZshMainProgram, vb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug); - ZZLog::Error_Log("size : %d", debug); - } - - if (fb_idx != GL_INVALID_INDEX) { - glGetActiveUniformBlockiv(ZZshMainProgram, fb_idx, GL_UNIFORM_BLOCK_BINDING, &debug); - ZZLog::Error_Log("fb active : %d", debug); - glGetActiveUniformBlockiv(ZZshMainProgram, fb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug); - ZZLog::Error_Log("size : %d", debug); - } -#endif - g_cs.enable_texture(); ps->enable_texture(context); } -#endif - static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type) { // uniform parameters - GLint p; pf->prog.link = (void*)pf; // Setting autolink pf->prog.isFragment = true; // Setting autolink pf->ShaderType = ShaderTypes[pf->Shader]; @@ -628,7 +538,6 @@ static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int void SetupVertexProgramParameters(VERTEXSHADER* pf, int context) { - GLint p; pf->prog.link = (void*)pf; // Setting autolink pf->prog.isFragment = false; // Setting autolink pf->ShaderType = ShaderTypes[pf->Shader]; @@ -637,12 +546,12 @@ void SetupVertexProgramParameters(VERTEXSHADER* pf, int context) } //const int GLSL_VERSION = 130; // Sampler2DRect appear in 1.3 -const int GLSL_VERSION = 420; +const int GLSL_VERSION = 330; // We use strictly compilation from source for GSLS static __forceinline void GlslHeaderString(char* header_string, const char* name, const char* depth) { - sprintf(header_string, "#version %d\n#define %s main\n%s\n", GLSL_VERSION, name, depth); + sprintf(header_string, "#version %d compatibility\n#define %s main\n%s\n", GLSL_VERSION, name, depth); } static __forceinline bool LOAD_VS(char* DefineString, const char* name, VERTEXSHADER& vertex, int shaderver, ZZshProfile context, const char* depth) @@ -702,7 +611,6 @@ bool ZZshLoadExtraEffects() { pvs[i] = pvsStore[i].prog; if (!LOAD_VS(DefineString, "BitBltVS", pvsBitBlt, cgvProf, 0, "")) bLoadSuccess = false; - GLint p; GL_REPORT_ERRORD(); if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[0], cgfProf, 0, "")) bLoadSuccess = false; @@ -755,13 +663,10 @@ bool ZZshLoadExtraEffects() { const static char* g_pPsTexWrap[] = { "#define REPEAT 1\n", "#define CLAMP 1\n", "#define REGION_REPEAT 1\n", "" }; -static ZZshShader LoadShaderFromType(const char* srcdir, const char* srcfile, int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context) { +static ZZshShader LoadShaderFromType(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context) { assert( texwrap < NUM_TEXWRAPS); assert( type < NUM_TYPES ); - //ZZLog::Error_Log("\n"); - - ZZshProgram prog; char* name = new char[MAX_SHADER_NAME_SIZE]; sprintf(name, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]); @@ -818,7 +723,7 @@ FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testae { return pf; } - pf->Shader = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context); + pf->Shader = LoadShaderFromType(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context); if (ZZshExistProgram(pf)) { SetupFragmentProgramParameters(pf, context, type); @@ -840,4 +745,4 @@ FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testae return NULL; } -#endif // GLSL_API +#endif // GLSL4_API diff --git a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl index 4f910f9e32..1856714296 100644 --- a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl +++ b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl @@ -5,7 +5,12 @@ // fixes kh textures #extension ARB_texture_rectangle: require -#define GL_compatibility_profile 1 +#extension GL_ARB_shading_language_420pack: require +#extension GL_ARB_separate_shader_objects : require +// Set with version +// #define GL_compatibility_profile 1 + + #define PERSPECTIVE_CORRECT_TEX // When writting GLSL code we should change variables in code according to denominator