From 21a96af8265f266dbb9b8882c96462c043ac500b Mon Sep 17 00:00:00 2001 From: rachytski Date: Sun, 12 Aug 2012 18:58:20 +0300 Subject: [PATCH] using system-memory buffer and glBufferSubData if glMapBuffer fails. it happens on FIMG-3DSE GPU and possibly on Vivante Corporation GPU's. --- yg/buffer_object.cpp | 30 +++++++++++++++++++++++------- yg/buffer_object.hpp | 1 + yg/resource_manager.cpp | 11 ++--------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/yg/buffer_object.cpp b/yg/buffer_object.cpp index 50c60a4645..b795c90eb6 100644 --- a/yg/buffer_object.cpp +++ b/yg/buffer_object.cpp @@ -13,14 +13,22 @@ namespace yg namespace gl { BufferObject::BufferObject(unsigned target) - : m_target(target), m_size(0), m_gpuData(0), m_isLocked(false) + : m_target(target), + m_size(0), + m_gpuData(0), + m_isLocked(false), + m_isUsingMapBuffer(false) { if (g_isBufferObjectsSupported) OGLCHECK(glGenBuffersFn(1, &m_id)); } BufferObject::BufferObject(size_t size, unsigned target) - : m_target(target), m_size(0), m_gpuData(0), m_isLocked(false) + : m_target(target), + m_size(0), + m_gpuData(0), + m_isLocked(false), + m_isUsingMapBuffer(false) { if (g_isBufferObjectsSupported) OGLCHECK(glGenBuffersFn(1, &m_id)); @@ -71,15 +79,17 @@ namespace yg if (g_isMapBufferSupported) { + m_isUsingMapBuffer = true; makeCurrent(); - /// orphaning the old copy of the buffer data. - /// this provides that the glMapBuffer will not wait. OGLCHECK(glBufferDataFn(m_target, m_size, 0, GL_DYNAMIC_DRAW)); m_gpuData = glMapBufferFn(m_target, GL_WRITE_ONLY_MWM); OGLCHECKAFTER; - return m_gpuData; + + if (m_gpuData != 0) + return m_gpuData; } + m_isUsingMapBuffer = false; if (!m_sharedBuffer) m_sharedBuffer = SharedBufferManager::instance().reserveSharedBuffer(m_size); @@ -98,10 +108,16 @@ namespace yg makeCurrent(); - if (g_isMapBufferSupported) - OGLCHECK(glUnmapBufferFn(m_target)); + if (g_isMapBufferSupported && m_isUsingMapBuffer) + { + if (glUnmapBufferFn(m_target) == GL_FALSE) + LOG(LWARNING, ("glUnmapBuffer returned GL_FALSE!")); + + OGLCHECKAFTER; + } else { + m_isUsingMapBuffer = false; OGLCHECK(glBufferSubDataFn(m_target, 0, m_size, m_gpuData)); SharedBufferManager::instance().freeSharedBuffer(m_size, m_sharedBuffer); m_sharedBuffer.reset(); diff --git a/yg/buffer_object.hpp b/yg/buffer_object.hpp index 1791758d7f..a8e7a70a8f 100644 --- a/yg/buffer_object.hpp +++ b/yg/buffer_object.hpp @@ -16,6 +16,7 @@ namespace yg unsigned int m_size; void * m_gpuData; bool m_isLocked; + bool m_isUsingMapBuffer; shared_ptr > m_sharedBuffer; public: diff --git a/yg/resource_manager.cpp b/yg/resource_manager.cpp index 593493a5b2..a2dd42ba8b 100644 --- a/yg/resource_manager.cpp +++ b/yg/resource_manager.cpp @@ -410,10 +410,7 @@ namespace m_texRtFormat = yg::Data8Bpp; if (isGPU("Samsung Electronics", "FIMG-3DSE", false)) - { m_texRtFormat = yg::Data8Bpp; - yg::gl::g_isMapBufferSupported = false; - } if (isGPU("Broadcom", "VideoCore IV HW", false)) m_texRtFormat = yg::Data8Bpp; @@ -426,16 +423,11 @@ namespace bool isAndroidDevice = GetPlatform().DeviceName() == "Android"; - /// on PowerVR chips in Android glFinish doesn't work, so we should use + /// on PowerVR chips on Android glFinish doesn't work, so we should use /// glReadPixels instead of glFinish to synchronize. if (isGPU("Imagination Technologies", "PowerVR", false) && isAndroidDevice) m_useReadPixelsToSynchronize = true; -/* /// filtering all devices from Vivante Corporation - /// to use vertex arrays - if (isGPU("Vivante Corporation", "", false)) - m_useVA = true;*/ - LOG(LINFO, ("selected", yg::formatName(m_texRtFormat), "format for tile textures")); if (m_useReadPixelsToSynchronize) @@ -585,6 +577,7 @@ namespace { if (p.isValid()) { + LOG(LINFO, ("initializing", p.m_poolName, "resource pool. vbSize=", p.m_vbSize, ", ibSize=", p.m_ibSize)); TStorageFactory storageFactory(p.m_vbSize, p.m_ibSize, m_params.m_useSingleThreadedOGL, p.m_poolName.c_str(), p.m_allocateOnDemand ? p.m_storagesCount : 0); if (m_params.m_useSingleThreadedOGL)