gsdx-ogl: use DSA for texture management

Yeah code is much nicer :)
This commit is contained in:
Gregory Hainaut 2015-04-24 19:34:17 +02:00
parent 6d31d1e0d0
commit 672e3f9533
7 changed files with 22 additions and 81 deletions

View File

@ -55,7 +55,6 @@ namespace GLState {
GLuint rt = 0; GLuint rt = 0;
GLuint ds = 0; GLuint ds = 0;
GLuint tex_unit[2] = {0, 0}; GLuint tex_unit[2] = {0, 0};
GLuint tex = 0;
GLuint64 tex_handle[2] = { 0, 0}; GLuint64 tex_handle[2] = { 0, 0};
bool dirty_ressources = false; bool dirty_ressources = false;
@ -109,7 +108,6 @@ namespace GLState {
ds = 0; ds = 0;
tex_unit[0] = 0; tex_unit[0] = 0;
tex_unit[1] = 0; tex_unit[1] = 0;
tex = 0;
tex_handle[0] = 0; tex_handle[0] = 0;
tex_handle[1] = 0; tex_handle[1] = 0;

View File

@ -57,7 +57,6 @@ namespace GLState {
extern GLuint rt; // render target extern GLuint rt; // render target
extern GLuint ds; // Depth-Stencil extern GLuint ds; // Depth-Stencil
extern GLuint tex_unit[2]; // shader input texture extern GLuint tex_unit[2]; // shader input texture
extern GLuint tex; // Generic texture (for tex operation)
extern GLuint64 tex_handle[2]; // shader input texture extern GLuint64 tex_handle[2]; // shader input texture
extern GLuint ps; extern GLuint ps;

View File

@ -212,13 +212,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
}; };
m_va = new GSVertexBufferStateOGL(sizeof(GSVertexPT1), il_convert, countof(il_convert)); m_va = new GSVertexBufferStateOGL(sizeof(GSVertexPT1), il_convert, countof(il_convert));
// ****************************************************************
// Texture unit state
// ****************************************************************
// By default use unit 3 for texture modification
// unit 0-2 will allocated to shader input
gl_ActiveTexture(GL_TEXTURE0 + 3);
// **************************************************************** // ****************************************************************
// Pre Generate the different sampler object // Pre Generate the different sampler object
// **************************************************************** // ****************************************************************
@ -578,10 +571,7 @@ void GSDeviceOGL::InitPrimDateTexture(int w, int h)
ClearRenderTarget_ui(m_date.t, 0x0FFFFFFF); ClearRenderTarget_ui(m_date.t, 0x0FFFFFFF);
#ifdef ENABLE_OGL_STENCIL_DEBUG #ifdef ENABLE_OGL_STENCIL_DEBUG
gl_ActiveTexture(GL_TEXTURE0 + 5); gl_BindTextureUnit(5, static_cast<GSTextureOGL*>(m_date.t)->GetID());
glBindTexture(GL_TEXTURE_2D, static_cast<GSTextureOGL*>(m_date.t)->GetID());
// Get back to the expected active texture unit
gl_ActiveTexture(GL_TEXTURE0 + 3);
#endif #endif
BindDateTexture(); BindDateTexture();
@ -743,8 +733,7 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, static_cast<GSTextureOGL*>(st_ogl)->GetID(), 0); gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, static_cast<GSTextureOGL*>(st_ogl)->GetID(), 0);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
dt_ogl->EnableUnit(); gl_CopyTextureSubImage2D(dt_ogl->GetID(), GL_TEX_LEVEL_0, r.x, r.y, r.x, r.y, r.width(), r.height());
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.x, r.y, r.width(), r.height());
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} }
@ -841,7 +830,7 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
GLuint64 handle[2] = {static_cast<GSTextureOGL*>(st)->GetHandle(linear ? m_convert.ln : m_convert.pt) , 0}; GLuint64 handle[2] = {static_cast<GSTextureOGL*>(st)->GetHandle(linear ? m_convert.ln : m_convert.pt) , 0};
m_shader->PS_ressources(handle); m_shader->PS_ressources(handle);
} else { } else {
PSSetShaderResource(static_cast<GSTextureOGL*>(st)->GetID()); PSSetShaderResource(0, st);
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt); PSSetSamplerState(linear ? m_convert.ln : m_convert.pt);
} }
@ -1008,7 +997,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
GLuint64 handle[2] = {static_cast<GSTextureOGL*>(rt)->GetHandle(m_convert.pt) , 0}; GLuint64 handle[2] = {static_cast<GSTextureOGL*>(rt)->GetHandle(m_convert.pt) , 0};
m_shader->PS_ressources(handle); m_shader->PS_ressources(handle);
} else { } else {
PSSetShaderResource(static_cast<GSTextureOGL*>(rt)->GetID()); PSSetShaderResource(0, rt);
PSSetSamplerState(m_convert.pt); PSSetSamplerState(m_convert.pt);
} }
@ -1051,34 +1040,18 @@ void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
m_va->SetTopology(topology); m_va->SetTopology(topology);
} }
void GSDeviceOGL::PSSetShaderResource(GLuint sr) void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
{ {
if (GLState::tex_unit[0] != sr) { GLuint id = static_cast<GSTextureOGL*>(sr)->GetID();
GLState::tex_unit[0] = sr; if (GLState::tex_unit[i] != id) {
gl_BindTextureUnit(i, id);
gl_ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sr);
// Get back to the expected active texture unit
gl_ActiveTexture(GL_TEXTURE0 + 3);
} }
} }
void GSDeviceOGL::PSSetShaderResources(GLuint tex[2]) void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
{ {
if (GLState::tex_unit[0] != tex[0] || GLState::tex_unit[1] != tex[1]) { PSSetShaderResource(0, sr0);
GLState::tex_unit[0] = tex[0]; PSSetShaderResource(1, sr1);
GLState::tex_unit[1] = tex[1];
gl_ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex[0]);
gl_ActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, tex[1]);
// Get back to the expected active texture unit
gl_ActiveTexture(GL_TEXTURE0 + 3);
}
} }
void GSDeviceOGL::PSSetSamplerState(GLuint ss) void GSDeviceOGL::PSSetSamplerState(GLuint ss)

View File

@ -629,8 +629,8 @@ class GSDeviceOGL : public GSDevice
void IASetVertexBuffer(const void* vertices, size_t count); void IASetVertexBuffer(const void* vertices, size_t count);
void IASetIndexBuffer(const void* index, size_t count); void IASetIndexBuffer(const void* index, size_t count);
void PSSetShaderResource(GLuint sr); void PSSetShaderResource(int i, GSTexture* sr);
void PSSetShaderResources(GLuint tex[2]); void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetSamplerState(GLuint ss); void PSSetSamplerState(GLuint ss);
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref); void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);

View File

@ -474,11 +474,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupSampler(ps_ssel); dev->SetupSampler(ps_ssel);
if (tex->m_palette) { if (tex->m_palette) {
GLuint textures[2] = {static_cast<GSTextureOGL*>(tex->m_texture)->GetID(), static_cast<GSTextureOGL*>(tex->m_palette)->GetID()}; dev->PSSetShaderResources(tex->m_texture, tex->m_palette);
dev->PSSetShaderResources(textures);
} else if (tex->m_texture) { } else if (tex->m_texture) {
// Only main texture dev->PSSetShaderResource(0, tex->m_texture);
dev->PSSetShaderResource(static_cast<GSTextureOGL*>(tex->m_texture)->GetID());
} }
} }
} }

View File

@ -225,7 +225,7 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
case GSTexture::Texture: case GSTexture::Texture:
case GSTexture::RenderTarget: case GSTexture::RenderTarget:
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
glGenTextures(1, &m_texture_id); gl_CreateTextures(GL_TEXTURE_2D, 1, &m_texture_id);
break; break;
case GSTexture::Backbuffer: case GSTexture::Backbuffer:
break; break;
@ -249,8 +249,7 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
case GSTexture::RenderTarget: case GSTexture::RenderTarget:
case GSTexture::Texture: case GSTexture::Texture:
EnableUnit(); gl_TextureStorage2D(m_texture_id, 1+GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y);
gl_TexStorage2D(GL_TEXTURE_2D, 1, m_format, m_size.x, m_size.y);
break; break;
default: break; default: break;
} }
@ -264,8 +263,6 @@ GSTextureOGL::~GSTextureOGL()
GLState::rt = 0; GLState::rt = 0;
if (m_texture_id == GLState::ds) if (m_texture_id == GLState::ds)
GLState::ds = 0; GLState::ds = 0;
if (m_texture_id == GLState::tex)
GLState::tex = 0;
if (m_texture_id == GLState::tex_unit[0]) if (m_texture_id == GLState::tex_unit[0])
GLState::tex_unit[0] = 0; GLState::tex_unit[0] = 0;
if (m_texture_id == GLState::tex_unit[1]) if (m_texture_id == GLState::tex_unit[1])
@ -279,8 +276,6 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{ {
ASSERT(m_type != GSTexture::DepthStencil && m_type != GSTexture::Offscreen); ASSERT(m_type != GSTexture::DepthStencil && m_type != GSTexture::Offscreen);
EnableUnit();
// Note: reduce noise for gl retracers // Note: reduce noise for gl retracers
// It might introduce bug after an emulator pause so always set it in standard mode // It might introduce bug after an emulator pause so always set it in standard mode
if (GLLoader::in_replayer) { if (GLLoader::in_replayer) {
@ -317,7 +312,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
} else { } else {
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch >> m_int_shift); glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch >> m_int_shift);
} }
glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.width(), r.height(), m_int_format, m_int_type, (const void*)PboPool::Offset()); gl_TextureSubImage2D(m_texture_id, GL_TEX_LEVEL_0, r.x, r.y, r.width(), r.height(), m_int_format, m_int_type, (const void*)PboPool::Offset());
// Normally only affect TexSubImage call. (i.e. only the previous line) // Normally only affect TexSubImage call. (i.e. only the previous line)
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@ -356,19 +351,9 @@ GLuint64 GSTextureOGL::GetHandle(GLuint sampler_id)
return m_handles[sampler_id]; return m_handles[sampler_id];
} }
void GSTextureOGL::EnableUnit()
{
/* Not a real texture */
ASSERT(!IsBackbuffer());
if (GLState::tex != m_texture_id) {
GLState::tex = m_texture_id;
glBindTexture(GL_TEXTURE_2D, m_texture_id);
}
}
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r) bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
{ {
// LOTS OF CRAP CODE!!!! PLEASE FIX ME !!!
if (m_type != GSTexture::Offscreen) return false; if (m_type != GSTexture::Offscreen) return false;
// The function allow to modify the texture from the CPU // The function allow to modify the texture from the CPU
@ -380,7 +365,6 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
// Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER // Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER
// Bind the texture to the read framebuffer to avoid any disturbance // Bind the texture to the read framebuffer to avoid any disturbance
EnableUnit();
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read); gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0); gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -565,7 +549,8 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
{ {
// Collect the texture data // Collect the texture data
uint32 pitch = 4 * m_size.x; uint32 pitch = 4 * m_size.x;
char* image = (char*)malloc(pitch * m_size.y); uint32 buf_size = pitch * m_size.y * 2;// Note *2 for security (depth/stencil)
char* image = (char*)malloc(buf_size);
bool status = true; bool status = true;
// FIXME instead of swapping manually B and R maybe you can request the driver to do it // FIXME instead of swapping manually B and R maybe you can request the driver to do it
@ -582,11 +567,8 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} else if(m_format == GL_R32I) { } else if(m_format == GL_R32I) {
gl_ActiveTexture(GL_TEXTURE0 + 6);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
#ifndef ENABLE_GLES #ifndef ENABLE_GLES
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_INT, image); gl_GetTextureImage(m_texture_id, 0, GL_RED_INTEGER, GL_INT, buf_size, image);
SaveRaw(fn, image, pitch); SaveRaw(fn, image, pitch);
#endif #endif
@ -596,9 +578,6 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
} else { } else {
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read); gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
gl_ActiveTexture(GL_TEXTURE0 + 6);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0); gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -623,10 +602,6 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
if (status) Save(fn, image, pitch); if (status) Save(fn, image, pitch);
free(image); free(image);
// Restore state
gl_ActiveTexture(GL_TEXTURE0 + 3);
glBindTexture(GL_TEXTURE_2D, GLState::tex);
return status; return status;
} }

View File

@ -69,8 +69,6 @@ class GSTextureOGL : public GSTexture
void Save(const string& fn, const void* image, uint32 pitch); void Save(const string& fn, const void* image, uint32 pitch);
void SaveRaw(const string& fn, const void* image, uint32 pitch); void SaveRaw(const string& fn, const void* image, uint32 pitch);
void EnableUnit();
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); } bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
bool IsDss() { return (m_type == GSTexture::DepthStencil); } bool IsDss() { return (m_type == GSTexture::DepthStencil); }