diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index 2e750fd0fb..12a4c2fc6c 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -28,6 +28,9 @@ extern uint64 g_real_texture_upload_byte; #endif +// FIXME find the optimal number of PBO +#define PBO_POOL_SIZE 8 + // FIXME OGL4: investigate, only 1 unpack buffer always bound namespace PboPool { @@ -37,8 +40,9 @@ namespace PboPool { uint32 m_current_pbo = 0; uint32 m_size; bool m_texture_storage; + uint8* m_gpu_texture; + GLsync m_fence[PBO_POOL_SIZE]; const uint32 m_pbo_size = 4*1024*1024; - uint8* m_gpu_texture; // Option for buffer storage // XXX: actually does I really need coherent and barrier??? @@ -66,6 +70,7 @@ namespace PboPool { if (m_texture_storage) { gl_BufferStorage(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, create_flags); m_map[m_current_pbo] = (char*)gl_MapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags); + m_fence[m_current_pbo] = 0; } else { gl_BufferData(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, GL_STREAM_COPY); m_map[m_current_pbo] = NULL; @@ -88,7 +93,8 @@ namespace PboPool { if (m_texture_storage) { if (m_offset[m_current_pbo] + m_size >= m_pbo_size) { - NextPbo(); + //NextPbo(); // For test purpose + NextPboWithSync(); } // Note: texsubimage will access currently bound buffer @@ -117,14 +123,6 @@ namespace PboPool { return map; } - // Used to unmap the buffer when context was detached. - void UnmapAll() { - for (size_t i = 0; i < countof(m_pool); i++) { - m_map[i] = NULL; - m_offset[m_current_pbo] = 0; - } - } - void Unmap() { if (m_texture_storage) { gl_FlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size); @@ -138,8 +136,18 @@ namespace PboPool { } void Destroy() { - if (m_texture_storage) - UnmapAll(); + if (m_texture_storage) { + for (size_t i = 0; i < countof(m_pool); i++) { + m_map[i] = NULL; + m_offset[i] = 0; + gl_DeleteSync(m_fence[i]); + + // Don't know if we must do it + gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[0]); + gl_UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + } + gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } gl_DeleteBuffers(countof(m_pool), m_pool); _aligned_free(m_gpu_texture); @@ -155,6 +163,26 @@ namespace PboPool { m_offset[m_current_pbo] = 0; } + void NextPboWithSync() { + m_fence[m_current_pbo] = gl_FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + NextPbo(); + if (m_fence[m_current_pbo]) { +#ifdef ENABLE_OGL_DEBUG_FENCE + GLenum status = gl_ClientWaitSync(m_fence[m_current_pbo], GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); +#else + gl_ClientWaitSync(m_fence[m_current_pbo], GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); +#endif + gl_DeleteSync(m_fence[m_current_pbo]); + m_fence[m_current_pbo] = 0; + +#ifdef ENABLE_OGL_DEBUG_FENCE + if (status != GL_ALREADY_SIGNALED) { + fprintf(stderr, "GL_PIXEL_UNPACK_BUFFER: Sync Sync! Buffer too small\n"); + } +#endif + } + } + void UnbindPbo() { gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h index ab5786b07a..ef1b6bede8 100644 --- a/plugins/GSdx/GSTextureOGL.h +++ b/plugins/GSdx/GSTextureOGL.h @@ -23,18 +23,14 @@ #include "GSTexture.h" -// FIXME find the optimal number of PBO -#define PBO_POOL_SIZE 8 - namespace PboPool { void BindPbo(); void UnbindPbo(); void NextPbo(); + void NextPboWithSync(); char* Map(uint32 size); - void MapAll(); void Unmap(); - void UnmapAll(); uint32 Offset(); void EndTransfer(); diff --git a/plugins/GSdx/GSVertexArrayOGL.h b/plugins/GSdx/GSVertexArrayOGL.h index 1a8b3e9b05..0cc305c15d 100644 --- a/plugins/GSdx/GSVertexArrayOGL.h +++ b/plugins/GSdx/GSVertexArrayOGL.h @@ -89,6 +89,7 @@ class GSBufferOGL { for (size_t i = 0; i < 5; i++) { gl_DeleteSync(m_fence[i]); } + // Don't know if we must do it bind(); gl_UnmapBuffer(m_target); }