gsdx-ogl: merge the two vertex buffer format

* Only a single VAO
    => Format is set once
    => Only a single bind at startup
    => GSVertexBufferStateOGL is nearly useless
    => barely faster but better than nothing :)
This commit is contained in:
Gregory Hainaut 2014-10-02 09:33:41 +02:00
parent 10c7be8c50
commit ccc1137e12
7 changed files with 39 additions and 63 deletions

View File

@ -46,7 +46,7 @@ GSDeviceOGL::GSDeviceOGL()
, m_window(NULL)
, m_fbo(0)
, m_fbo_read(0)
, m_vb_sr(NULL)
, m_va(NULL)
, m_shader(NULL)
{
memset(&m_merge_obj, 0, sizeof(m_merge_obj));
@ -70,7 +70,7 @@ GSDeviceOGL::~GSDeviceOGL()
return;
// Clean vertex buffer state
delete (m_vb_sr);
delete (m_va);
// Clean m_merge_obj
for (size_t i = 0; i < countof(m_merge_obj.ps); i++)
@ -111,7 +111,6 @@ GSDeviceOGL::~GSDeviceOGL()
delete m_vs_cb;
delete m_ps_cb;
gl_DeleteSamplers(1, &m_palette_ss);
delete m_vb;
m_shader->Delete(m_apitrace);
for (uint32 key = 0; key < VSSelector::size(); key++) m_shader->Delete(m_vs[key]);
@ -189,12 +188,19 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
// Vertex buffer state
// ****************************************************************
GSInputLayoutOGL il_convert[2] =
ASSERT(sizeof(GSVertexPT1) == sizeof(GSVertex));
GSInputLayoutOGL il_convert[] =
{
{0, 2, GL_FLOAT, GL_FALSE, sizeof(GSVertexPT1), (const GLvoid*)offsetof(struct GSVertexPT1, p) },
{1, 2, GL_FLOAT, GL_FALSE, sizeof(GSVertexPT1), (const GLvoid*)offsetof(struct GSVertexPT1, t) },
{2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexPT1) , (const GLvoid*)(0) } ,
{2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexPT1) , (const GLvoid*)(16) } ,
{4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(8) } ,
{1 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(12) } ,
{2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(16) } ,
{1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(20) } ,
{2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(24) } ,
{4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } ,
};
m_vb_sr = new GSVertexBufferStateOGL(sizeof(GSVertexPT1), il_convert, countof(il_convert));
m_va = new GSVertexBufferStateOGL(sizeof(GSVertexPT1), il_convert, countof(il_convert));
// ****************************************************************
// Texture unit state
@ -432,14 +438,14 @@ void GSDeviceOGL::AfterDraw()
void GSDeviceOGL::DrawPrimitive()
{
BeforeDraw();
m_state.vb->DrawPrimitive();
m_va->DrawPrimitive();
AfterDraw();
}
void GSDeviceOGL::DrawIndexedPrimitive()
{
BeforeDraw();
m_state.vb->DrawIndexedPrimitive();
m_va->DrawIndexedPrimitive();
AfterDraw();
}
@ -448,7 +454,7 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
ASSERT(offset + count <= (int)m_index.count);
BeforeDraw();
m_state.vb->DrawIndexedPrimitive(offset, count);
m_va->DrawIndexedPrimitive(offset, count);
AfterDraw();
}
@ -859,7 +865,6 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
{GSVector4(right , bottom, 0.0f, 0.0f) , GSVector2(flip_sr.z , flip_sr.w)} ,
};
IASetVertexState(m_vb_sr);
IASetVertexBuffer(vertices, 4);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
@ -986,7 +991,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
// ia
IASetVertexState(m_vb_sr);
IASetVertexBuffer(vertices, 4);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
@ -1022,42 +1026,32 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
void GSDeviceOGL::EndScene()
{
m_state.vb->EndScene();
}
void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb)
{
if (vb == NULL) vb = m_vb;
if (m_state.vb != vb) {
m_state.vb = vb;
vb->bind();
}
m_va->EndScene();
}
void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count)
{
m_state.vb->UploadVB(vertices, count);
m_va->UploadVB(vertices, count);
}
bool GSDeviceOGL::IAMapVertexBuffer(void** vertex, size_t stride, size_t count)
{
return m_state.vb->MapVB(vertex, count);
return m_va->MapVB(vertex, count);
}
void GSDeviceOGL::IAUnmapVertexBuffer()
{
m_state.vb->UnmapVB();
m_va->UnmapVB();
}
void GSDeviceOGL::IASetIndexBuffer(const void* index, size_t count)
{
m_state.vb->UploadIB(index, count);
m_va->UploadIB(index, count);
}
void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
{
m_state.vb->SetTopology(topology);
m_va->SetTopology(topology);
}
void GSDeviceOGL::PSSetShaderResource(GLuint sr)

View File

@ -477,8 +477,7 @@ class GSDeviceOGL : public GSDevice
GLuint m_fbo; // frame buffer container
GLuint m_fbo_read; // frame buffer container only for reading
GSVertexBufferStateOGL* m_vb; // vb_state for HW renderer
GSVertexBufferStateOGL* m_vb_sr; // vb_state for StretchRect
GSVertexBufferStateOGL* m_va;// state of the vertex buffer/array
struct {
GLuint ps[2]; // program object
@ -517,7 +516,6 @@ class GSDeviceOGL : public GSDevice
} m_shadeboost;
struct {
GSVertexBufferStateOGL* vb;
GSDepthStencilOGL* dss;
GSBlendStateOGL* bs;
float bf; // blend factor
@ -608,7 +606,6 @@ class GSDeviceOGL : public GSDevice
bool IAMapVertexBuffer(void** vertex, size_t stride, size_t count);
void IAUnmapVertexBuffer();
void IASetIndexBuffer(const void* index, size_t count);
void IASetVertexState(GSVertexBufferStateOGL* vb = NULL);
void PSSetShaderResource(GLuint sr);
void PSSetShaderResources(GLuint tex[2]);

View File

@ -124,8 +124,6 @@ void GSRendererOGL::SetupIA()
void* ptr = NULL;
dev->IASetVertexState();
if(UserHacks_WildHack && !isPackedUV_HackFlag) {
// FIXME: why not put it on the Vertex shader
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))

View File

@ -35,18 +35,6 @@ void GSDeviceOGL::CreateTextureFX()
m_palette_ss = CreateSampler(false, false, false);
gl_BindSampler(1, m_palette_ss);
GSInputLayoutOGL vert_format[] =
{
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(0) } ,
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(8) } ,
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(12) } ,
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(16) } ,
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(20) } ,
{5 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(24) } ,
{6 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } ,
};
m_vb = new GSVertexBufferStateOGL(sizeof(GSVertex), vert_format, countof(vert_format));
// Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution
m_gs = CompileGS();

View File

@ -28,7 +28,6 @@ extern uint32 g_vertex_upload_byte;
#endif
struct GSInputLayoutOGL {
GLuint index;
GLint size;
GLenum type;
GLboolean normalize;
@ -287,19 +286,19 @@ public:
{
for (uint32 i = 0; i < layout_nbr; i++) {
// Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer
gl_EnableVertexAttribArray(layout[i].index);
gl_EnableVertexAttribArray(i);
switch (layout[i].type) {
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
if (layout[i].normalize) {
gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
gl_VertexAttribPointer(i, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
} else {
// Rule: when shader use integral (not normalized) you must use gl_VertexAttribIPointer (note the extra I)
gl_VertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
gl_VertexAttribIPointer(i, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
}
break;
default:
gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
gl_VertexAttribPointer(i, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
break;
}
}

View File

@ -500,12 +500,12 @@ static const char* tfx_glsl =
"\n"
"#ifdef VERTEX_SHADER\n"
"layout(location = 0) in vec2 i_st;\n"
"layout(location = 1) in vec4 i_c;\n"
"layout(location = 2) in float i_q;\n"
"layout(location = 3) in uvec2 i_p;\n"
"layout(location = 4) in uint i_z;\n"
"layout(location = 5) in uvec2 i_uv;\n"
"layout(location = 6) in vec4 i_f;\n"
"layout(location = 2) in vec4 i_c;\n"
"layout(location = 3) in float i_q;\n"
"layout(location = 4) in uvec2 i_p;\n"
"layout(location = 5) in uint i_z;\n"
"layout(location = 6) in uvec2 i_uv;\n"
"layout(location = 7) in vec4 i_f;\n"
"\n"
"out SHADER\n"
"{\n"

View File

@ -49,12 +49,12 @@ struct vertex
#ifdef VERTEX_SHADER
layout(location = 0) in vec2 i_st;
layout(location = 1) in vec4 i_c;
layout(location = 2) in float i_q;
layout(location = 3) in uvec2 i_p;
layout(location = 4) in uint i_z;
layout(location = 5) in uvec2 i_uv;
layout(location = 6) in vec4 i_f;
layout(location = 2) in vec4 i_c;
layout(location = 3) in float i_q;
layout(location = 4) in uvec2 i_p;
layout(location = 5) in uint i_z;
layout(location = 6) in uvec2 i_uv;
layout(location = 7) in vec4 i_f;
out SHADER
{