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_window(NULL)
, m_fbo(0) , m_fbo(0)
, m_fbo_read(0) , m_fbo_read(0)
, m_vb_sr(NULL) , m_va(NULL)
, m_shader(NULL) , m_shader(NULL)
{ {
memset(&m_merge_obj, 0, sizeof(m_merge_obj)); memset(&m_merge_obj, 0, sizeof(m_merge_obj));
@ -70,7 +70,7 @@ GSDeviceOGL::~GSDeviceOGL()
return; return;
// Clean vertex buffer state // Clean vertex buffer state
delete (m_vb_sr); delete (m_va);
// Clean m_merge_obj // Clean m_merge_obj
for (size_t i = 0; i < countof(m_merge_obj.ps); i++) for (size_t i = 0; i < countof(m_merge_obj.ps); i++)
@ -111,7 +111,6 @@ GSDeviceOGL::~GSDeviceOGL()
delete m_vs_cb; delete m_vs_cb;
delete m_ps_cb; delete m_ps_cb;
gl_DeleteSamplers(1, &m_palette_ss); gl_DeleteSamplers(1, &m_palette_ss);
delete m_vb;
m_shader->Delete(m_apitrace); m_shader->Delete(m_apitrace);
for (uint32 key = 0; key < VSSelector::size(); key++) m_shader->Delete(m_vs[key]); 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 // 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) }, {2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexPT1) , (const GLvoid*)(0) } ,
{1, 2, GL_FLOAT, GL_FALSE, sizeof(GSVertexPT1), (const GLvoid*)offsetof(struct GSVertexPT1, t) }, {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 // Texture unit state
@ -432,14 +438,14 @@ void GSDeviceOGL::AfterDraw()
void GSDeviceOGL::DrawPrimitive() void GSDeviceOGL::DrawPrimitive()
{ {
BeforeDraw(); BeforeDraw();
m_state.vb->DrawPrimitive(); m_va->DrawPrimitive();
AfterDraw(); AfterDraw();
} }
void GSDeviceOGL::DrawIndexedPrimitive() void GSDeviceOGL::DrawIndexedPrimitive()
{ {
BeforeDraw(); BeforeDraw();
m_state.vb->DrawIndexedPrimitive(); m_va->DrawIndexedPrimitive();
AfterDraw(); AfterDraw();
} }
@ -448,7 +454,7 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
ASSERT(offset + count <= (int)m_index.count); ASSERT(offset + count <= (int)m_index.count);
BeforeDraw(); BeforeDraw();
m_state.vb->DrawIndexedPrimitive(offset, count); m_va->DrawIndexedPrimitive(offset, count);
AfterDraw(); 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)} , {GSVector4(right , bottom, 0.0f, 0.0f) , GSVector2(flip_sr.z , flip_sr.w)} ,
}; };
IASetVertexState(m_vb_sr);
IASetVertexBuffer(vertices, 4); IASetVertexBuffer(vertices, 4);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP); IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
@ -986,7 +991,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
// ia // ia
IASetVertexState(m_vb_sr);
IASetVertexBuffer(vertices, 4); IASetVertexBuffer(vertices, 4);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP); IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
@ -1022,42 +1026,32 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
void GSDeviceOGL::EndScene() void GSDeviceOGL::EndScene()
{ {
m_state.vb->EndScene(); m_va->EndScene();
}
void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb)
{
if (vb == NULL) vb = m_vb;
if (m_state.vb != vb) {
m_state.vb = vb;
vb->bind();
}
} }
void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count) 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) 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() void GSDeviceOGL::IAUnmapVertexBuffer()
{ {
m_state.vb->UnmapVB(); m_va->UnmapVB();
} }
void GSDeviceOGL::IASetIndexBuffer(const void* index, size_t count) 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) void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
{ {
m_state.vb->SetTopology(topology); m_va->SetTopology(topology);
} }
void GSDeviceOGL::PSSetShaderResource(GLuint sr) void GSDeviceOGL::PSSetShaderResource(GLuint sr)

View File

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

View File

@ -124,8 +124,6 @@ void GSRendererOGL::SetupIA()
void* ptr = NULL; void* ptr = NULL;
dev->IASetVertexState();
if(UserHacks_WildHack && !isPackedUV_HackFlag) { if(UserHacks_WildHack && !isPackedUV_HackFlag) {
// FIXME: why not put it on the Vertex shader // FIXME: why not put it on the Vertex shader
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next)) 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); m_palette_ss = CreateSampler(false, false, false);
gl_BindSampler(1, m_palette_ss); 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 // Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution // It might cost a seconds at startup but it would reduce benchmark pollution
m_gs = CompileGS(); m_gs = CompileGS();

View File

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

View File

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

View File

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