diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 582556ae8e..8c448348fc 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -246,7 +246,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1) case 2: dev = new GSDeviceSDL(); break; #endif case 3: dev = new GSDeviceNull(); break; - case 5: dev = new GSDeviceOGL(); break; + case 4: dev = new GSDeviceOGL(); break; } if(dev == NULL) @@ -429,11 +429,15 @@ EXPORT_C GSreadFIFO(uint8* mem) #ifdef _LINUX // FIXME: double check which thread call this function // See fifo2 issue below - if (theApp.GetConfig("renderer", 0) == 12) { + if (theApp.GetConfig("renderer", 0) / 3 == 4) { fprintf(stderr, "Disable FIFO1 on opengl\n"); } #endif + s_gs->m_wnd.AttachContext(); + s_gs->ReadFIFO(mem, 1); + + s_gs->m_wnd.DetachContext(); } EXPORT_C GSreadFIFO2(uint8* mem, uint32 size) @@ -441,14 +445,18 @@ EXPORT_C GSreadFIFO2(uint8* mem, uint32 size) #ifdef _LINUX // FIXME called from EE core thread not MTGS which cause // invalidate data for opengl - if (theApp.GetConfig("renderer", 0) == 12) { + if (theApp.GetConfig("renderer", 0) / 3 == 4) { #ifdef OGL_DEBUG fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size); #endif //return; } #endif + s_gs->m_wnd.AttachContext(); + s_gs->ReadFIFO(mem, size); + + s_gs->m_wnd.DetachContext(); } EXPORT_C GSgifTransfer(const uint8* mem, uint32 size) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 2d7ef96c53..63a5078d41 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -536,6 +536,7 @@ void GSDeviceOGL::DebugOutput() fprintf(stderr, "\n"); } + CheckDebugLog(); } void GSDeviceOGL::DrawPrimitive() @@ -566,6 +567,20 @@ void GSDeviceOGL::DrawIndexedPrimitive() #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) { 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); // glClear(GL_COLOR_BUFFER_BIT); } 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 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(t)->Attach(GL_COLOR_ATTACHMENT0); glClearBufferfv(GL_COLOR, 0, c.v); } @@ -970,6 +991,8 @@ void GSDeviceOGL::SetUniformBuffer(GSUniformBufferOGL* cb) void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb) { + if (vb == NULL) vb = m_vb; + if (m_state.vb != vb) { m_state.vb = vb; vb->bind(); @@ -981,6 +1004,16 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t 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) { m_state.vb->UploadIB(index, count); @@ -1073,6 +1106,8 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo) if (m_state.fbo != fbo) { m_state.fbo = 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) { char debType[20], debSev[5]; + static int sev_counter = 0; if(type == GL_DEBUG_TYPE_ERROR_ARB) strcpy(debType, "Error"); @@ -1293,23 +1329,26 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi else strcpy(debType, "UNKNOWN"); - if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) + if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) { strcpy(debSev, "High"); + sev_counter++; + } else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB) strcpy(debSev, "Med"); else if(severity == GL_DEBUG_SEVERITY_LOW_ARB) strcpy(debSev, "Low"); #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 FILE* f = fopen("Debug.txt","a"); 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); } + //if (sev_counter > 2) assert(0); } // (A - B) * C + D diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 21121f7403..fc574a5229 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -323,11 +323,22 @@ class GSVertexBufferStateOGL { 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; + if (b_size <= 0) return false; #endif m_count = count; @@ -338,7 +349,7 @@ class GSVertexBufferStateOGL { // Current GPU buffer is really too small need to allocate a new one if (m_count > m_limit) { - allocate(std::max(count * 3 / 2, m_default_size)); + allocate(std::max(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 @@ -354,17 +365,19 @@ class GSVertexBufferStateOGL { } // 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 - if (dst == NULL) { + if (*pointer == NULL) { fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); - return; + return false; } #endif - memcpy(dst, src, m_stride*m_count); - glUnmapBuffer(m_target); + return true; } + void Unmap() { glUnmapBuffer(m_target); } + void EndScene() { m_start += m_count; @@ -381,6 +394,11 @@ class GSVertexBufferStateOGL { 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() @@ -416,52 +434,6 @@ public: 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(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) { 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(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 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); - } + 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() { @@ -878,6 +850,7 @@ class GSDeviceOGL : public GSDevice void DrawPrimitive(); void DrawIndexedPrimitive(); + void DrawIndexedPrimitive(int offset, int count); void ClearRenderTarget(GSTexture* t, const GSVector4& c); void ClearRenderTarget(GSTexture* t, uint32 c); @@ -906,8 +879,10 @@ class GSDeviceOGL : public GSDevice void IASetPrimitiveTopology(GLenum topology); 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 IASetVertexState(GSVertexBufferStateOGL* vb); + void IASetVertexState(GSVertexBufferStateOGL* vb = NULL); void SetUniformBuffer(GSUniformBufferOGL* cb); diff --git a/plugins/GSdx/GSLinuxDialog.cpp b/plugins/GSdx/GSLinuxDialog.cpp index 97b4a2648c..4a0ccd57ab 100644 --- a/plugins/GSdx/GSLinuxDialog.cpp +++ b/plugins/GSdx/GSLinuxDialog.cpp @@ -76,8 +76,8 @@ GtkWidget* CreateRenderComboBox() case 8 : renderer_box_position = 1; break; case 10: renderer_box_position = 2; break; case 11: renderer_box_position = 3; break; - case 15: renderer_box_position = 4; break; - case 16: renderer_box_position = 5; break; + case 12: renderer_box_position = 4; break; + case 13: renderer_box_position = 5; break; } gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position); return render_combo_box; @@ -375,8 +375,8 @@ bool RunLinuxDialog() case 1: theApp.SetConfig("renderer", 8); break; case 2: theApp.SetConfig("renderer", 10); break; case 3: theApp.SetConfig("renderer", 11); break; - case 4: theApp.SetConfig("renderer", 15); break; - case 5: theApp.SetConfig("renderer", 16); break; + case 4: theApp.SetConfig("renderer", 12); break; + case 5: theApp.SetConfig("renderer", 13); break; } } diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 1a86704ff2..418aceba61 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -24,15 +24,12 @@ GSRendererOGL::GSRendererOGL() - : GSRendererHW(new GSVertexTraceDX11(this), sizeof(GSVertexHW11), new GSTextureCacheOGL(this)) - , m_topology(0) + : GSRendererHW(new GSTextureCacheOGL(this)) { m_logz = !!theApp.GetConfig("logz", 0); m_fba = !!theApp.GetConfig("fba", 1); UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0); m_pixelcenter = GSVector2(-0.5f, -0.5f); - - InitConvertVertex(GSRendererOGL); } bool GSRendererOGL::CreateDevice(GSDevice* dev) @@ -43,44 +40,47 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev) return true; } -template -void GSRendererOGL::ConvertVertex(size_t dst_index, size_t src_index) +void GSRendererOGL::SetupIA() { - GSVertex* s = (GSVertex*)((GSVertexHW11*)m_vertex.buff + src_index); - GSVertexHW11* d = (GSVertexHW11*)m_vertex.buff + dst_index; + GSDeviceOGL* dev = (GSDeviceOGL*)m_dev; - GSVector4i v0 = ((GSVector4i*)s)[0]; - GSVector4i v1 = ((GSVector4i*)s)[1]; + void* ptr = NULL; - 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; - ((GSVector4i*)d)[1] = v1; -} + dev->IASetIndexBuffer(m_index.buff, m_index.tail); -void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) -{ - switch(m_vt->m_primclass) + GLenum t; + + switch(m_vt.m_primclass) { case GS_POINT_CLASS: - m_topology = GL_POINTS; + t = GL_POINTS; break; case GS_LINE_CLASS: case GS_SPRITE_CLASS: - m_topology = GL_LINES; + t = GL_LINES; break; case GS_TRIANGLE_CLASS: - m_topology = GL_TRIANGLES; + t = GL_TRIANGLES; break; default: __assume(0); } + dev->IASetPrimitiveTopology(t); +} + + +void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +{ GSDrawingEnvironment& env = m_env; 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 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(); GSVertexPT1 vertices[] = @@ -163,7 +163,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour 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.b = context->ALPHA.B; @@ -207,11 +207,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour { 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. - if (m_vt->m_min.p.z > 0xffffff) + if (m_vt.m_min.p.z > 0xffffff) { vs_sel.bppz = 1; 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) { - 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. - if (m_vt->m_min.p.z > 0xffff) + if (m_vt.m_min.p.z > 0xffff) { vs_sel.bppz = 2; om_dssel.ztst = ZTST_ALWAYS; @@ -268,7 +268,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour GSDeviceOGL::GSSelector gs_sel; gs_sel.iip = PRIM->IIP; - gs_sel.prim = m_vt->m_primclass; + gs_sel.prim = m_vt.m_primclass; // 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; } @@ -336,7 +336,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour ps_sel.aem = env.TEXA.AEM; ps_sel.tfx = context->TEX0.TFX; 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; int w = tex->m_texture->GetWidth(); @@ -385,8 +385,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour uint8 afix = context->ALPHA.FIX; + SetupIA(); + 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->SetupGS(gs_sel); dev->SetupPS(ps_sel, &ps_cb, ps_ssel); diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 62736d5c04..7cef97af87 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -40,22 +40,12 @@ class GSRendererOGL : public GSRendererHW bool UserHacks_AlphaHack; protected: - GLenum m_topology; - - template - 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;} + void SetupIA(); public: GSRendererOGL(); virtual ~GSRendererOGL() {}; - template void VertexKick(bool skip); - bool CreateDevice(GSDevice* dev); void UpdateFBA(GSTexture* rt) {} diff --git a/plugins/GSdx/GSTextureCacheOGL.cpp b/plugins/GSdx/GSTextureCacheOGL.cpp index b248d1dcf1..74eba438a0 100644 --- a/plugins/GSdx/GSTextureCacheOGL.cpp +++ b/plugins/GSdx/GSTextureCacheOGL.cpp @@ -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(); 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 DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM; #endif diff --git a/plugins/GSdx/GSTextureCacheOGL.h b/plugins/GSdx/GSTextureCacheOGL.h index 11bf6210ad..f86554c84a 100644 --- a/plugins/GSdx/GSTextureCacheOGL.h +++ b/plugins/GSdx/GSTextureCacheOGL.h @@ -28,7 +28,7 @@ class GSTextureCacheOGL : public GSTextureCache { 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); diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index 5616a72078..ba194377db 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -61,26 +61,19 @@ void GSDeviceOGL::CreateTextureFX() //float4 c : COLOR0; //float4 f : COLOR1; - GSInputLayoutOGL vert_format[6] = + GSInputLayoutOGL vert_format[] = { // FIXME - {0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(0) } , - {1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(8) } , - {2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(12) } , - {3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(16) } , - {4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(20) } , + {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) } , // 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)); -} - -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); + m_vb = new GSVertexBufferStateOGL(sizeof(GSVertex), vert_format, countof(vert_format)); } void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb) diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index d26c1d3f0d..2590bbc3be 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -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 // For the moment SW renderer only use 1 so don't bother 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); - } - else + else if (m_format == GL_R16UI) + 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 + } break; case GSTexture::Offscreen: 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) { + //fprintf(stderr, "format %d,%x\n", m_type, m_format); 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) @@ -142,18 +150,22 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) EnableUnit(2); - if (m_format != GL_RGBA8) { - fprintf(stderr, "wrong pixel format\n"); - assert(0); - } - // pitch could be different of width*element_size glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2); // 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, "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 (m_size.x != 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 // Load the PBO - if (m_format == GL_R16UI) - glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_SHORT, 0); - else if (m_format == GL_RGBA8) + if (m_format == GL_RGBA8) 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); + } // Give access from the CPU uint32 map_flags = GL_MAP_READ_BIT; diff --git a/plugins/GSdx/GSThread.h b/plugins/GSdx/GSThread.h index 4a9e7223dc..160bd541cd 100644 --- a/plugins/GSdx/GSThread.h +++ b/plugins/GSdx/GSThread.h @@ -182,6 +182,8 @@ public: void Lock() {pthread_mutex_lock(&m_mutex);} bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;} void Unlock() {pthread_mutex_unlock(&m_mutex);} + + operator pthread_mutex_t* () {return &m_mutex;} }; class GSEvent : public IGSEvent diff --git a/plugins/GSdx/res/tfx.glsl b/plugins/GSdx/res/tfx.glsl index 892af3178e..c45dcd9063 100644 --- a/plugins/GSdx/res/tfx.glsl +++ b/plugins/GSdx/res/tfx.glsl @@ -48,12 +48,13 @@ struct vertex }; #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 = 2) in float i_q; layout(location = 3) in uvec2 i_p; 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; @@ -101,12 +102,14 @@ void vs_main() { 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; } else { - VSout.t.xy = i_t; + //VSout.t.xy = i_t; + VSout.t.xy = i_st; VSout.t.w = i_q; } }