mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl:
* split GSDeviceOGl header. Will allow easy sharing with zzogl. * fix some gcc warning zzogl: * import Uniform buffer and Vertex array from GSdx git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5207 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
2f9e35e5ae
commit
b665499a6b
|
@ -224,7 +224,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs);
|
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs);
|
||||||
CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs);
|
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]);
|
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.
|
// 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_S, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
// 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
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
// glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
// 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_S, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
// 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
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
// glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
// 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));
|
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]);
|
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i]);
|
||||||
|
|
||||||
m_merge_obj.bs = new GSBlendStateOGL();
|
m_merge_obj.bs = new GSBlendStateOGL();
|
||||||
|
@ -296,7 +296,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
m_interlace.cb = new GSUniformBufferOGL(2, sizeof(InterlaceConstantBuffer));
|
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]);
|
CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i]);
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
// Shade boost
|
// Shade boost
|
||||||
|
@ -1167,8 +1167,6 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer)
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
||||||
{
|
{
|
||||||
uint ref = sref;
|
|
||||||
|
|
||||||
if(m_state.dss != dss) {
|
if(m_state.dss != dss) {
|
||||||
m_state.dss = dss;
|
m_state.dss = dss;
|
||||||
m_state.sref = sref;
|
m_state.sref = sref;
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "GSDevice.h"
|
#include "GSDevice.h"
|
||||||
#include "GSTextureOGL.h"
|
#include "GSTextureOGL.h"
|
||||||
#include "GSdx.h"
|
#include "GSdx.h"
|
||||||
|
#include "GSVertexArrayOGL.h"
|
||||||
|
#include "GSUniformBufferOGL.h"
|
||||||
|
|
||||||
class GSBlendStateOGL {
|
class GSBlendStateOGL {
|
||||||
// Note: You can also select the index of the draw buffer for which to set the blend setting
|
// 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<int>(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
|
class GSDeviceOGL : public GSDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -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_S, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
// 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
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
// 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);
|
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
// 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
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
|
@ -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<int>(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());
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
|
@ -230,7 +230,7 @@ void GLWindow::CreateContextGL()
|
||||||
{
|
{
|
||||||
#if defined(OGL4_LOG) || defined(GLSL4_API)
|
#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)
|
// 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
|
#else
|
||||||
// FIXME there was some issue with previous context creation on Geforce7. Code was rewritten
|
// 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.
|
// for GSdx unfortunately it was not tested on Geforce7 so keep the 2.0 context for now.
|
||||||
|
|
|
@ -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
|
|
@ -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<int>(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
|
|
@ -72,6 +72,16 @@ extern "C" u32 CALLBACK PS2EgetLibVersion2(u32 type);
|
||||||
extern "C" char* CALLBACK PS2EgetLibName(void);
|
extern "C" char* CALLBACK PS2EgetLibName(void);
|
||||||
#endif
|
#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 "ZZoglMath.h"
|
||||||
#include "Profile.h"
|
#include "Profile.h"
|
||||||
#include "GSDump.h"
|
#include "GSDump.h"
|
||||||
|
|
|
@ -59,6 +59,10 @@ inline bool ZZshActiveParameter(ZZshParameter param) {return (param !=NULL); }
|
||||||
|
|
||||||
#endif // end NVIDIA cg-toolkit API
|
#endif // end NVIDIA cg-toolkit API
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
#include "GSUniformBufferOGL.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GLSL_API
|
#ifdef GLSL_API
|
||||||
|
|
||||||
enum ZZshPARAMTYPE {
|
enum ZZshPARAMTYPE {
|
||||||
|
@ -118,53 +122,6 @@ enum {
|
||||||
ZZSH_CTX_ALL = 2
|
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
|
// Note A nice template could be better
|
||||||
// Warning order is important for buffer (see GLSL)
|
// Warning order is important for buffer (see GLSL)
|
||||||
// Note must be keep POD (so you can map it to GLSL)
|
// Note must be keep POD (so you can map it to GLSL)
|
||||||
|
|
|
@ -93,9 +93,6 @@ ZZshProgram ZZshMainProgram;
|
||||||
char* ZZshSource; // Shader's source data.
|
char* ZZshSource; // Shader's source data.
|
||||||
off_t ZZshSourceSize;
|
off_t ZZshSourceSize;
|
||||||
|
|
||||||
extern char* EFFECT_NAME; // All this variables used for testing and set manually
|
|
||||||
extern char* EFFECT_DIR;
|
|
||||||
|
|
||||||
bool g_bCRTCBilinear = true;
|
bool g_bCRTCBilinear = true;
|
||||||
|
|
||||||
float4 g_vdepth, vlogz;
|
float4 g_vdepth, vlogz;
|
||||||
|
@ -109,37 +106,23 @@ VERTEXSHADER pvsBitBlt;
|
||||||
inline bool LoadEffects();
|
inline bool LoadEffects();
|
||||||
extern bool s_bWriteDepth;
|
extern bool s_bWriteDepth;
|
||||||
|
|
||||||
struct SHADERHEADER
|
|
||||||
{
|
|
||||||
unsigned int index, offset, size; // if highest bit of index is set, pixel shader
|
|
||||||
};
|
|
||||||
map<int, SHADERHEADER*> mapShaderResources;
|
|
||||||
|
|
||||||
// Debug variable, store name of the function that call the shader.
|
// Debug variable, store name of the function that call the shader.
|
||||||
const char* ShaderCallerName = "";
|
const char* ShaderCallerName = "";
|
||||||
const char* ShaderHandleName = "";
|
const char* ShaderHandleName = "";
|
||||||
|
|
||||||
int NumActiveUniforms, NumGlobalUniforms;
|
int NumActiveUniforms, NumGlobalUniforms;
|
||||||
ZZshParamInfo UniformsIndex[MAX_ACTIVE_UNIFORMS] = {qZero};
|
|
||||||
const char* ShaderNames[MAX_ACTIVE_SHADERS] = {""};
|
const char* ShaderNames[MAX_ACTIVE_SHADERS] = {""};
|
||||||
ZZshShaderType ShaderTypes[MAX_ACTIVE_SHADERS] = {ZZ_SH_NONE};
|
ZZshShaderType ShaderTypes[MAX_ACTIVE_SHADERS] = {ZZ_SH_NONE};
|
||||||
|
|
||||||
ZZshProgram CompiledPrograms[MAX_ACTIVE_SHADERS][MAX_ACTIVE_SHADERS] = {{0}};
|
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 *constant_buffer;
|
||||||
GSUniformBufferOGL *common_buffer;
|
GSUniformBufferOGL *common_buffer;
|
||||||
GSUniformBufferOGL *vertex_buffer;
|
GSUniformBufferOGL *vertex_buffer;
|
||||||
GSUniformBufferOGL *fragment_buffer;
|
GSUniformBufferOGL *fragment_buffer;
|
||||||
|
|
||||||
COMMONSHADER g_cs;
|
COMMONSHADER g_cs;
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------ Code
|
//------------------ 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() {
|
bool ZZshStartUsingShaders() {
|
||||||
|
|
||||||
ZZLog::Error_Log("Creating effects.");
|
ZZLog::Error_Log("Creating effects.");
|
||||||
|
@ -331,25 +292,6 @@ void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
|
||||||
const GLchar * EmptyVertex = "void main(void) {gl_Position = ftransform();}";
|
const GLchar * EmptyVertex = "void main(void) {gl_Position = ftransform();}";
|
||||||
const GLchar * EmptyFragment = "void main(void) {gl_FragColor = gl_Color;}";
|
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) {
|
ZZshShaderType ZZshGetShaderType(const char* name) {
|
||||||
if (strncmp(name, "TextureFog", 10) == 0) return ZZ_SH_TEXTURE_FOG;
|
if (strncmp(name, "TextureFog", 10) == 0) return ZZ_SH_TEXTURE_FOG;
|
||||||
if (strncmp(name, "Texture", 7) == 0) return ZZ_SH_TEXTURE;
|
if (strncmp(name, "Texture", 7) == 0) return ZZ_SH_TEXTURE;
|
||||||
|
@ -381,10 +323,10 @@ inline bool GetCompilationLog(GLuint shader) {
|
||||||
if (CompileStatus == GL_TRUE)
|
if (CompileStatus == GL_TRUE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int* lenght, infologlength;
|
int lenght, infologlength;
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologlength);
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
char* InfoLog = new char[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);
|
ZZLog::Error_Log("Compiling... %d:\t %s", shader, InfoLog);
|
||||||
|
|
||||||
return false;
|
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
|
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)) {
|
if (!CompileShader(shader, DefineString, name, ShaderType)) {
|
||||||
ZZLog::Error_Log("Failed to compile shader for %s: ", name);
|
ZZLog::Error_Log("Failed to compile shader for %s: ", name);
|
||||||
return false;
|
return false;
|
||||||
|
@ -454,10 +400,10 @@ static bool ValidateProgram(ZZshProgram Prog) {
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
glValidateProgram(Prog);
|
glValidateProgram(Prog);
|
||||||
int* lenght, infologlength;
|
int lenght, infologlength;
|
||||||
glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength);
|
glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
char* InfoLog = new char[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);
|
ZZLog::Error_Log("Validation %d... %d:\t %s", Prog, infologlength, InfoLog);
|
||||||
}
|
}
|
||||||
return (isValid != 0);
|
return (isValid != 0);
|
||||||
|
@ -542,8 +488,14 @@ void ZZshSetPixelShader(ZZshShaderLink prog) {
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef GLSL4_API
|
|
||||||
static void init_shader() {
|
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
|
// Warning put same order than GLSL
|
||||||
constant_buffer = new GSUniformBufferOGL(0, sizeof(ConstantUniform));
|
constant_buffer = new GSUniformBufferOGL(0, sizeof(ConstantUniform));
|
||||||
common_buffer = new GSUniformBufferOGL(1, sizeof(GlobalUniform));
|
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->bind();
|
||||||
fragment_buffer->upload((void*)&ps->uniform_buffer[context]);
|
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();
|
g_cs.enable_texture();
|
||||||
ps->enable_texture(context);
|
ps->enable_texture(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type)
|
static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type)
|
||||||
{
|
{
|
||||||
// uniform parameters
|
// uniform parameters
|
||||||
GLint p;
|
|
||||||
pf->prog.link = (void*)pf; // Setting autolink
|
pf->prog.link = (void*)pf; // Setting autolink
|
||||||
pf->prog.isFragment = true; // Setting autolink
|
pf->prog.isFragment = true; // Setting autolink
|
||||||
pf->ShaderType = ShaderTypes[pf->Shader];
|
pf->ShaderType = ShaderTypes[pf->Shader];
|
||||||
|
@ -628,7 +538,6 @@ static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int
|
||||||
|
|
||||||
void SetupVertexProgramParameters(VERTEXSHADER* pf, int context)
|
void SetupVertexProgramParameters(VERTEXSHADER* pf, int context)
|
||||||
{
|
{
|
||||||
GLint p;
|
|
||||||
pf->prog.link = (void*)pf; // Setting autolink
|
pf->prog.link = (void*)pf; // Setting autolink
|
||||||
pf->prog.isFragment = false; // Setting autolink
|
pf->prog.isFragment = false; // Setting autolink
|
||||||
pf->ShaderType = ShaderTypes[pf->Shader];
|
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 = 130; // Sampler2DRect appear in 1.3
|
||||||
const int GLSL_VERSION = 420;
|
const int GLSL_VERSION = 330;
|
||||||
|
|
||||||
// We use strictly compilation from source for GSLS
|
// We use strictly compilation from source for GSLS
|
||||||
static __forceinline void GlslHeaderString(char* header_string, const char* name, const char* depth)
|
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)
|
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;
|
pvs[i] = pvsStore[i].prog;
|
||||||
|
|
||||||
if (!LOAD_VS(DefineString, "BitBltVS", pvsBitBlt, cgvProf, 0, "")) bLoadSuccess = false;
|
if (!LOAD_VS(DefineString, "BitBltVS", pvsBitBlt, cgvProf, 0, "")) bLoadSuccess = false;
|
||||||
GLint p;
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[0], cgfProf, 0, "")) bLoadSuccess = false;
|
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", "" };
|
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( texwrap < NUM_TEXWRAPS);
|
||||||
assert( type < NUM_TYPES );
|
assert( type < NUM_TYPES );
|
||||||
//ZZLog::Error_Log("\n");
|
|
||||||
|
|
||||||
ZZshProgram prog;
|
|
||||||
|
|
||||||
char* name = new char[MAX_SHADER_NAME_SIZE];
|
char* name = new char[MAX_SHADER_NAME_SIZE];
|
||||||
sprintf(name, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
|
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;
|
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)) {
|
if (ZZshExistProgram(pf)) {
|
||||||
SetupFragmentProgramParameters(pf, context, type);
|
SetupFragmentProgramParameters(pf, context, type);
|
||||||
|
@ -840,4 +745,4 @@ FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testae
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLSL_API
|
#endif // GLSL4_API
|
||||||
|
|
|
@ -5,7 +5,12 @@
|
||||||
// fixes kh textures
|
// fixes kh textures
|
||||||
|
|
||||||
#extension ARB_texture_rectangle: require
|
#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
|
#define PERSPECTIVE_CORRECT_TEX
|
||||||
|
|
||||||
// When writting GLSL code we should change variables in code according to denominator
|
// When writting GLSL code we should change variables in code according to denominator
|
||||||
|
|
Loading…
Reference in New Issue