GSdx-ogl: LINUX only

* Use the new map interface/separate texture coordinate inside shader
* support new format on texture

Note: it is quite instable with various crashes and GL error but at least it compiles now :p 


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5094 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2012-02-11 10:22:02 +00:00
parent 4a00648d9f
commit 92f2ab38ae
12 changed files with 180 additions and 152 deletions

View File

@ -246,7 +246,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
case 2: dev = new GSDeviceSDL(); break; case 2: dev = new GSDeviceSDL(); break;
#endif #endif
case 3: dev = new GSDeviceNull(); break; case 3: dev = new GSDeviceNull(); break;
case 5: dev = new GSDeviceOGL(); break; case 4: dev = new GSDeviceOGL(); break;
} }
if(dev == NULL) if(dev == NULL)
@ -429,11 +429,15 @@ EXPORT_C GSreadFIFO(uint8* mem)
#ifdef _LINUX #ifdef _LINUX
// FIXME: double check which thread call this function // FIXME: double check which thread call this function
// See fifo2 issue below // See fifo2 issue below
if (theApp.GetConfig("renderer", 0) == 12) { if (theApp.GetConfig("renderer", 0) / 3 == 4) {
fprintf(stderr, "Disable FIFO1 on opengl\n"); fprintf(stderr, "Disable FIFO1 on opengl\n");
} }
#endif #endif
s_gs->m_wnd.AttachContext();
s_gs->ReadFIFO(mem, 1); s_gs->ReadFIFO(mem, 1);
s_gs->m_wnd.DetachContext();
} }
EXPORT_C GSreadFIFO2(uint8* mem, uint32 size) EXPORT_C GSreadFIFO2(uint8* mem, uint32 size)
@ -441,14 +445,18 @@ EXPORT_C GSreadFIFO2(uint8* mem, uint32 size)
#ifdef _LINUX #ifdef _LINUX
// FIXME called from EE core thread not MTGS which cause // FIXME called from EE core thread not MTGS which cause
// invalidate data for opengl // invalidate data for opengl
if (theApp.GetConfig("renderer", 0) == 12) { if (theApp.GetConfig("renderer", 0) / 3 == 4) {
#ifdef OGL_DEBUG #ifdef OGL_DEBUG
fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size); fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size);
#endif #endif
//return; //return;
} }
#endif #endif
s_gs->m_wnd.AttachContext();
s_gs->ReadFIFO(mem, size); s_gs->ReadFIFO(mem, size);
s_gs->m_wnd.DetachContext();
} }
EXPORT_C GSgifTransfer(const uint8* mem, uint32 size) EXPORT_C GSgifTransfer(const uint8* mem, uint32 size)

View File

@ -536,6 +536,7 @@ void GSDeviceOGL::DebugOutput()
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
CheckDebugLog();
} }
void GSDeviceOGL::DrawPrimitive() void GSDeviceOGL::DrawPrimitive()
@ -566,6 +567,20 @@ void GSDeviceOGL::DrawIndexedPrimitive()
#endif #endif
} }
void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
{
ASSERT(offset + count <= m_index.count);
#ifdef OGL_DEBUG
DebugInput();
#endif
m_state.vb->DrawIndexedPrimitive(offset, count);
#ifdef OGL_DEBUG
DebugOutput();
g_draw_count++;
#endif
}
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{ {
GLuint fbo_old = m_state.fbo; GLuint fbo_old = m_state.fbo;
@ -578,9 +593,15 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
// glClearColor(c.x, c.y, c.z, c.w); // glClearColor(c.x, c.y, c.z, c.w);
// glClear(GL_COLOR_BUFFER_BIT); // glClear(GL_COLOR_BUFFER_BIT);
} else { } else {
// FIXME I need to clarify this FBO attachment stuff // FIXME1 I need to clarify this FBO attachment stuff
// I would like to avoid FBO for a basic clean operation // I would like to avoid FBO for a basic clean operation
OMSetFBO(m_fbo); OMSetFBO(m_fbo);
// FIXME2:
// it would be better to attach the texture to another slot (like 3)
// but it crash for an unknow reason
// The following error appears "glClearBufferfv failed because the currently set GL_DRAW_FRAMEBUFFER binding has incomplete status"
// Maybe glDrawBuffer must be updated but it does not solve the crash...
// FIXME3: I still have another crash on GOW...
static_cast<GSTextureOGL*>(t)->Attach(GL_COLOR_ATTACHMENT0); static_cast<GSTextureOGL*>(t)->Attach(GL_COLOR_ATTACHMENT0);
glClearBufferfv(GL_COLOR, 0, c.v); glClearBufferfv(GL_COLOR, 0, c.v);
} }
@ -970,6 +991,8 @@ void GSDeviceOGL::SetUniformBuffer(GSUniformBufferOGL* cb)
void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb) void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb)
{ {
if (vb == NULL) vb = m_vb;
if (m_state.vb != vb) { if (m_state.vb != vb) {
m_state.vb = vb; m_state.vb = vb;
vb->bind(); vb->bind();
@ -981,6 +1004,16 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count)
m_state.vb->UploadVB(vertices, count); m_state.vb->UploadVB(vertices, count);
} }
bool GSDeviceOGL::IAMapVertexBuffer(void** vertex, size_t stride, size_t count)
{
return m_state.vb->MapVB(vertex, count);
}
void GSDeviceOGL::IAUnmapVertexBuffer()
{
m_state.vb->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_state.vb->UploadIB(index, count);
@ -1073,6 +1106,8 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo)
if (m_state.fbo != fbo) { if (m_state.fbo != fbo) {
m_state.fbo = fbo; m_state.fbo = fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// FIXME DEBUG
//if (fbo) fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
} }
} }
@ -1277,6 +1312,7 @@ void GSDeviceOGL::CheckDebugLog()
void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message) void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message)
{ {
char debType[20], debSev[5]; char debType[20], debSev[5];
static int sev_counter = 0;
if(type == GL_DEBUG_TYPE_ERROR_ARB) if(type == GL_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error"); strcpy(debType, "Error");
@ -1293,23 +1329,26 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
else else
strcpy(debType, "UNKNOWN"); strcpy(debType, "UNKNOWN");
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) {
strcpy(debSev, "High"); strcpy(debSev, "High");
sev_counter++;
}
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB) else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
strcpy(debSev, "Med"); strcpy(debSev, "Med");
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB) else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
strcpy(debSev, "Low"); strcpy(debSev, "Low");
#ifdef LOUD_DEBUGGING #ifdef LOUD_DEBUGGING
fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType,id,debSev,message); fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message);
#endif #endif
FILE* f = fopen("Debug.txt","a"); FILE* f = fopen("Debug.txt","a");
if(f) if(f)
{ {
fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType,id,debSev,message); fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message);
fclose(f); fclose(f);
} }
//if (sev_counter > 2) assert(0);
} }
// (A - B) * C + D // (A - B) * C + D

View File

@ -323,11 +323,22 @@ class GSVertexBufferStateOGL {
void upload(const void* src, uint32 count) 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 #ifdef OGL_DEBUG
GLint b_size = -1; GLint b_size = -1;
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
if (b_size <= 0) return; if (b_size <= 0) return false;
#endif #endif
m_count = count; m_count = count;
@ -338,7 +349,7 @@ class GSVertexBufferStateOGL {
// Current GPU buffer is really too small need to allocate a new one // Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) { if (m_count > m_limit) {
allocate(std::max<int>(count * 3 / 2, m_default_size)); allocate(std::max<int>(m_count * 3 / 2, m_default_size));
} else if (m_count > (m_limit - m_start) ) { } else if (m_count > (m_limit - m_start) ) {
// Not enough left free room. Just go back at the beginning // Not enough left free room. Just go back at the beginning
@ -354,17 +365,19 @@ class GSVertexBufferStateOGL {
} }
// Upload the data to the buffer // Upload the data to the buffer
uint8* dst = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); *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 #ifdef OGL_DEBUG
if (dst == NULL) { if (*pointer == NULL) {
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
return; return false;
} }
#endif #endif
memcpy(dst, src, m_stride*m_count); return true;
glUnmapBuffer(m_target);
} }
void Unmap() { glUnmapBuffer(m_target); }
void EndScene() void EndScene()
{ {
m_start += m_count; m_start += m_count;
@ -381,6 +394,11 @@ class GSVertexBufferStateOGL {
glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), 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; } size_t GetStart() { return m_start; }
void debug() void debug()
@ -416,52 +434,6 @@ public:
m_vb->bind(); m_vb->bind();
} }
#if 0
void upload(const void* src, uint32 count)
{
#ifdef OGL_DEBUG
GLint b_size = -1;
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
if (b_size <= 0) return;
#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>(count * 3 / 2, 60000));
} 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
uint8* dst = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
#ifdef OGL_DEBUG
if (dst == NULL) {
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
return;
}
#endif
memcpy(dst, src, m_stride*m_count);
glUnmapBuffer(m_target);
}
#endif
void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr) void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr)
{ {
for (int i = 0; i < layout_nbr; i++) { for (int i = 0; i < layout_nbr; i++) {
@ -490,17 +462,17 @@ public:
void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); } 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 SetTopology(GLenum topology) { m_topology = topology; }
void UploadVB(const void* vertices, size_t count) void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); }
{
m_vb->upload(vertices, count);
}
void UploadIB(const void* index, size_t count) void UploadIB(const void* index, size_t count) { m_ib->upload(index, 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() ~GSVertexBufferStateOGL()
{ {
@ -878,6 +850,7 @@ class GSDeviceOGL : public GSDevice
void DrawPrimitive(); void DrawPrimitive();
void DrawIndexedPrimitive(); void DrawIndexedPrimitive();
void DrawIndexedPrimitive(int offset, int count);
void ClearRenderTarget(GSTexture* t, const GSVector4& c); void ClearRenderTarget(GSTexture* t, const GSVector4& c);
void ClearRenderTarget(GSTexture* t, uint32 c); void ClearRenderTarget(GSTexture* t, uint32 c);
@ -906,8 +879,10 @@ class GSDeviceOGL : public GSDevice
void IASetPrimitiveTopology(GLenum topology); void IASetPrimitiveTopology(GLenum topology);
void IASetVertexBuffer(const void* vertices, size_t count); void IASetVertexBuffer(const void* vertices, size_t count);
bool IAMapVertexBuffer(void** vertex, size_t stride, size_t count);
void IAUnmapVertexBuffer();
void IASetIndexBuffer(const void* index, size_t count); void IASetIndexBuffer(const void* index, size_t count);
void IASetVertexState(GSVertexBufferStateOGL* vb); void IASetVertexState(GSVertexBufferStateOGL* vb = NULL);
void SetUniformBuffer(GSUniformBufferOGL* cb); void SetUniformBuffer(GSUniformBufferOGL* cb);

View File

@ -76,8 +76,8 @@ GtkWidget* CreateRenderComboBox()
case 8 : renderer_box_position = 1; break; case 8 : renderer_box_position = 1; break;
case 10: renderer_box_position = 2; break; case 10: renderer_box_position = 2; break;
case 11: renderer_box_position = 3; break; case 11: renderer_box_position = 3; break;
case 15: renderer_box_position = 4; break; case 12: renderer_box_position = 4; break;
case 16: renderer_box_position = 5; break; case 13: renderer_box_position = 5; break;
} }
gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position); gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position);
return render_combo_box; return render_combo_box;
@ -375,8 +375,8 @@ bool RunLinuxDialog()
case 1: theApp.SetConfig("renderer", 8); break; case 1: theApp.SetConfig("renderer", 8); break;
case 2: theApp.SetConfig("renderer", 10); break; case 2: theApp.SetConfig("renderer", 10); break;
case 3: theApp.SetConfig("renderer", 11); break; case 3: theApp.SetConfig("renderer", 11); break;
case 4: theApp.SetConfig("renderer", 15); break; case 4: theApp.SetConfig("renderer", 12); break;
case 5: theApp.SetConfig("renderer", 16); break; case 5: theApp.SetConfig("renderer", 13); break;
} }
} }

View File

@ -24,15 +24,12 @@
GSRendererOGL::GSRendererOGL() GSRendererOGL::GSRendererOGL()
: GSRendererHW(new GSVertexTraceDX11(this), sizeof(GSVertexHW11), new GSTextureCacheOGL(this)) : GSRendererHW(new GSTextureCacheOGL(this))
, m_topology(0)
{ {
m_logz = !!theApp.GetConfig("logz", 0); m_logz = !!theApp.GetConfig("logz", 0);
m_fba = !!theApp.GetConfig("fba", 1); m_fba = !!theApp.GetConfig("fba", 1);
UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0); UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0);
m_pixelcenter = GSVector2(-0.5f, -0.5f); m_pixelcenter = GSVector2(-0.5f, -0.5f);
InitConvertVertex(GSRendererOGL);
} }
bool GSRendererOGL::CreateDevice(GSDevice* dev) bool GSRendererOGL::CreateDevice(GSDevice* dev)
@ -43,44 +40,47 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
return true; return true;
} }
template<uint32 prim, uint32 tme, uint32 fst> void GSRendererOGL::SetupIA()
void GSRendererOGL::ConvertVertex(size_t dst_index, size_t src_index)
{ {
GSVertex* s = (GSVertex*)((GSVertexHW11*)m_vertex.buff + src_index); GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
GSVertexHW11* d = (GSVertexHW11*)m_vertex.buff + dst_index;
GSVector4i v0 = ((GSVector4i*)s)[0]; void* ptr = NULL;
GSVector4i v1 = ((GSVector4i*)s)[1];
if(tme && fst) dev->IASetVertexState();
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))
{ {
// TODO: modify VertexTrace and the shaders to read uv from v1.u16[0], v1.u16[1], then this step is not needed GSVector4i::storent(ptr, m_vertex.buff, sizeof(GSVertex) * m_vertex.next);
v0 = GSVector4i::cast(GSVector4(v1.uph16()).xyzw(GSVector4::cast(v0))); // uv => st dev->IAUnmapVertexBuffer();
} }
((GSVector4i*)d)[0] = v0; dev->IASetIndexBuffer(m_index.buff, m_index.tail);
((GSVector4i*)d)[1] = v1;
}
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) GLenum t;
{
switch(m_vt->m_primclass) switch(m_vt.m_primclass)
{ {
case GS_POINT_CLASS: case GS_POINT_CLASS:
m_topology = GL_POINTS; t = GL_POINTS;
break; break;
case GS_LINE_CLASS: case GS_LINE_CLASS:
case GS_SPRITE_CLASS: case GS_SPRITE_CLASS:
m_topology = GL_LINES; t = GL_LINES;
break; break;
case GS_TRIANGLE_CLASS: case GS_TRIANGLE_CLASS:
m_topology = GL_TRIANGLES; t = GL_TRIANGLES;
break; break;
default: default:
__assume(0); __assume(0);
} }
dev->IASetPrimitiveTopology(t);
}
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
{
GSDrawingEnvironment& env = m_env; GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context; GSDrawingContext* context = m_context;
@ -103,7 +103,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GSVector4 s = GSVector4(rtscale.x / rtsize.x, rtscale.y / rtsize.y); GSVector4 s = GSVector4(rtscale.x / rtsize.x, rtscale.y / rtsize.y);
GSVector4 o = GSVector4(-1.0f, 1.0f); GSVector4 o = GSVector4(-1.0f, 1.0f);
GSVector4 src = ((m_vt->m_min.p.xyxy(m_vt->m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
GSVector4 dst = src * 2.0f + o.xxxx(); GSVector4 dst = src * 2.0f + o.xxxx();
GSVertexPT1 vertices[] = GSVertexPT1 vertices[] =
@ -163,7 +163,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if(!IsOpaque()) if(!IsOpaque())
{ {
om_bsel.abe = PRIM->ABE || PRIM->AA1 && m_vt->m_primclass == GS_LINE_CLASS; om_bsel.abe = PRIM->ABE || PRIM->AA1 && m_vt.m_primclass == GS_LINE_CLASS;
om_bsel.a = context->ALPHA.A; om_bsel.a = context->ALPHA.A;
om_bsel.b = context->ALPHA.B; om_bsel.b = context->ALPHA.B;
@ -207,11 +207,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
{ {
if(context->ZBUF.PSM == PSM_PSMZ24) if(context->ZBUF.PSM == PSM_PSMZ24)
{ {
if(m_vt->m_max.p.z > 0xffffff) if(m_vt.m_max.p.z > 0xffffff)
{ {
ASSERT(m_vt->m_min.p.z > 0xffffff); ASSERT(m_vt.m_min.p.z > 0xffffff);
// Fixme :Following conditional fixes some dialog frame in Wild Arms 3, but may not be what was intended. // Fixme :Following conditional fixes some dialog frame in Wild Arms 3, but may not be what was intended.
if (m_vt->m_min.p.z > 0xffffff) if (m_vt.m_min.p.z > 0xffffff)
{ {
vs_sel.bppz = 1; vs_sel.bppz = 1;
om_dssel.ztst = ZTST_ALWAYS; om_dssel.ztst = ZTST_ALWAYS;
@ -220,11 +220,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
} }
else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S)
{ {
if(m_vt->m_max.p.z > 0xffff) if(m_vt.m_max.p.z > 0xffff)
{ {
ASSERT(m_vt->m_min.p.z > 0xffff); // sfex capcom logo ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo
// Fixme : Same as above, I guess. // Fixme : Same as above, I guess.
if (m_vt->m_min.p.z > 0xffff) if (m_vt.m_min.p.z > 0xffff)
{ {
vs_sel.bppz = 2; vs_sel.bppz = 2;
om_dssel.ztst = ZTST_ALWAYS; om_dssel.ztst = ZTST_ALWAYS;
@ -268,7 +268,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GSDeviceOGL::GSSelector gs_sel; GSDeviceOGL::GSSelector gs_sel;
gs_sel.iip = PRIM->IIP; gs_sel.iip = PRIM->IIP;
gs_sel.prim = m_vt->m_primclass; gs_sel.prim = m_vt.m_primclass;
// ps // ps
@ -288,7 +288,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
} }
} }
if (env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST) if(env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
{ {
ps_sel.colclip = 1; ps_sel.colclip = 1;
} }
@ -336,7 +336,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
ps_sel.aem = env.TEXA.AEM; ps_sel.aem = env.TEXA.AEM;
ps_sel.tfx = context->TEX0.TFX; ps_sel.tfx = context->TEX0.TFX;
ps_sel.tcc = context->TEX0.TCC; ps_sel.tcc = context->TEX0.TCC;
ps_sel.ltf = m_filter == 2 ? m_vt->IsLinear() : m_filter; ps_sel.ltf = m_filter == 2 ? m_vt.IsLinear() : m_filter;
ps_sel.rt = tex->m_target; ps_sel.rt = tex->m_target;
int w = tex->m_texture->GetWidth(); int w = tex->m_texture->GetWidth();
@ -385,8 +385,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
uint8 afix = context->ALPHA.FIX; uint8 afix = context->ALPHA.FIX;
SetupIA();
dev->SetupOM(om_dssel, om_bsel, afix); dev->SetupOM(om_dssel, om_bsel, afix);
dev->SetupIA(m_vertex.buff, m_vertex.next, m_index.buff, m_index.tail, m_topology);
dev->SetupVS(vs_sel, &vs_cb); dev->SetupVS(vs_sel, &vs_cb);
dev->SetupGS(gs_sel); dev->SetupGS(gs_sel);
dev->SetupPS(ps_sel, &ps_cb, ps_ssel); dev->SetupPS(ps_sel, &ps_cb, ps_ssel);

View File

@ -40,22 +40,12 @@ class GSRendererOGL : public GSRendererHW
bool UserHacks_AlphaHack; bool UserHacks_AlphaHack;
protected: protected:
GLenum m_topology; void SetupIA();
template<uint32 prim, uint32 tme, uint32 fst>
void ConvertVertex(size_t dst_index, size_t src_index);
int GetPosX(const void* vertex) const {return (int)((const GSVertexHW11*)vertex)->p.x;}
int GetPosY(const void* vertex) const {return (int)((const GSVertexHW11*)vertex)->p.y;}
uint32 GetColor(const void* vertex) const {return ((const GSVertexHW11*)vertex)->c0;}
void SetColor(void* vertex, uint32 c) const {((GSVertexHW11*)vertex)->c0 = c;}
public: public:
GSRendererOGL(); GSRendererOGL();
virtual ~GSRendererOGL() {}; virtual ~GSRendererOGL() {};
template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
bool CreateDevice(GSDevice* dev); bool CreateDevice(GSDevice* dev);
void UpdateFBA(GSTexture* rt) {} void UpdateFBA(GSTexture* rt) {}

View File

@ -62,6 +62,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy(); GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
GLuint format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? GL_R16UI : GL_RGBA8; GLuint format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? GL_R16UI : GL_RGBA8;
//if (format == GL_R16UI) fprintf(stderr, "Format 16 bits integer\n");
#if 0 #if 0
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
#endif #endif

View File

@ -28,7 +28,7 @@
class GSTextureCacheOGL : public GSTextureCache class GSTextureCacheOGL : public GSTextureCache
{ {
protected: protected:
int Get8bitFormat() {/* TODO return DXGI_FORMAT_A8_UNORM;*/} int Get8bitFormat() { return GL_R8; /* TODO return DXGI_FORMAT_A8_UNORM;*/}
void Read(Target* t, const GSVector4i& r); void Read(Target* t, const GSVector4i& r);

View File

@ -61,26 +61,19 @@ void GSDeviceOGL::CreateTextureFX()
//float4 c : COLOR0; //float4 c : COLOR0;
//float4 f : COLOR1; //float4 f : COLOR1;
GSInputLayoutOGL vert_format[6] = GSInputLayoutOGL vert_format[] =
{ {
// FIXME // FIXME
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(0) } , {0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(0) } ,
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(8) } , {1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(8) } ,
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(12) } , {2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(12) } ,
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(16) } , {3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(16) } ,
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(20) } , {4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(20) } ,
// note: there is a 32 bits pad // note: there is a 32 bits pad
{5 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(28) } , {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(GSVertexHW11), vert_format, countof(vert_format)); m_vb = new GSVertexBufferStateOGL(sizeof(GSVertex), vert_format, countof(vert_format));
}
void GSDeviceOGL::SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim)
{
IASetVertexState(m_vb);
IASetVertexBuffer(vertex, vertex_count);
IASetIndexBuffer(index, index_count);
IASetPrimitiveTopology(prim);
} }
void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb) void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)

View File

@ -103,11 +103,16 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
// In worst case the HW renderer seems to use 3 texture unit // In worst case the HW renderer seems to use 3 texture unit
// For the moment SW renderer only use 1 so don't bother // For the moment SW renderer only use 1 so don't bother
EnableUnit(2); EnableUnit(2);
if (m_format == GL_RGBA8) { if (m_format == GL_RGBA8)
glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
} else if (m_format == GL_R16UI)
else glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
else if (m_format == GL_R8)
glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
assert(0); // TODO Later assert(0); // TODO Later
}
break; break;
case GSTexture::Offscreen: case GSTexture::Offscreen:
if (m_type == GL_RGBA8) m_pbo_size = m_size.x * m_size.y * 4; if (m_type == GL_RGBA8) m_pbo_size = m_size.x * m_size.y * 4;
@ -130,7 +135,10 @@ GSTextureOGL::~GSTextureOGL()
void GSTextureOGL::Attach(GLenum attachment) void GSTextureOGL::Attach(GLenum attachment)
{ {
//fprintf(stderr, "format %d,%x\n", m_type, m_format);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
// FIXME DEBUG
//fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
} }
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
@ -142,18 +150,22 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
EnableUnit(2); EnableUnit(2);
if (m_format != GL_RGBA8) {
fprintf(stderr, "wrong pixel format\n");
assert(0);
}
// pitch could be different of width*element_size // pitch could be different of width*element_size
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2); glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
// FIXME : it crash on colin mcrae rally 3 (others game too) when the size is 16 // FIXME : it crash on colin mcrae rally 3 (others game too) when the size is 16
//fprintf(stderr, "Texture %dx%d with a pitch of %d\n", m_size.x, m_size.y, pitch >>2); //fprintf(stderr, "Texture %dx%d with a pitch of %d\n", m_size.x, m_size.y, pitch >>2);
//fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height()); //fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data); if (m_format == GL_RGBA8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
else if (m_format == GL_R16UI)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED_INTEGER, GL_R16UI, data);
else if (m_format == GL_R8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED, GL_R8, data);
else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
assert(0);
}
#if 0 #if 0
//if (m_size.x != 16) //if (m_size.x != 16)
if (r.width() > 16 && r.height() > 16) if (r.width() > 16 && r.height() > 16)
@ -216,12 +228,16 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
// FIXME It might be possible to only map a subrange of the texture based on r object // FIXME It might be possible to only map a subrange of the texture based on r object
// Load the PBO // Load the PBO
if (m_format == GL_R16UI) if (m_format == GL_RGBA8)
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_SHORT, 0);
else if (m_format == GL_RGBA8)
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, 0); glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, 0);
else else if (m_format == GL_R16UI)
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0);
else if (m_format == GL_R8)
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_BYTE, 0);
else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
assert(0); assert(0);
}
// Give access from the CPU // Give access from the CPU
uint32 map_flags = GL_MAP_READ_BIT; uint32 map_flags = GL_MAP_READ_BIT;

View File

@ -182,6 +182,8 @@ public:
void Lock() {pthread_mutex_lock(&m_mutex);} void Lock() {pthread_mutex_lock(&m_mutex);}
bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;} bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;}
void Unlock() {pthread_mutex_unlock(&m_mutex);} void Unlock() {pthread_mutex_unlock(&m_mutex);}
operator pthread_mutex_t* () {return &m_mutex;}
}; };
class GSEvent : public IGSEvent class GSEvent : public IGSEvent

View File

@ -48,12 +48,13 @@ struct vertex
}; };
#ifdef VERTEX_SHADER #ifdef VERTEX_SHADER
layout(location = 0) in vec2 i_t; layout(location = 0) in vec2 i_st;
layout(location = 1) in vec4 i_c; layout(location = 1) in vec4 i_c;
layout(location = 2) in float i_q; layout(location = 2) in float i_q;
layout(location = 3) in uvec2 i_p; layout(location = 3) in uvec2 i_p;
layout(location = 4) in uint i_z; layout(location = 4) in uint i_z;
layout(location = 5) in vec4 i_f; layout(location = 5) in uvec2 i_uv;
layout(location = 6) in vec4 i_f;
layout(location = 0) out vertex VSout; layout(location = 0) out vertex VSout;
@ -101,12 +102,14 @@ void vs_main()
{ {
if(VS_FST != 0) if(VS_FST != 0)
{ {
VSout.t.xy = i_t * TextureScale; //VSout.t.xy = i_t * TextureScale;
VSout.t.xy = i_uv * TextureScale;
VSout.t.w = 1.0f; VSout.t.w = 1.0f;
} }
else else
{ {
VSout.t.xy = i_t; //VSout.t.xy = i_t;
VSout.t.xy = i_st;
VSout.t.w = i_q; VSout.t.w = i_q;
} }
} }