From 1b8e3edb86e569ed14159e18cf1ca3dd82582b66 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 4 Mar 2018 10:00:45 -0800 Subject: [PATCH] GLES: Buffer handling cleanup. Trying to fix the mystery issues on some devices. --- ext/native/thin3d/GLRenderManager.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index efab8bf3f..504bc9f2c 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -538,11 +538,12 @@ void GLPushBuffer::Map() { assert(!writePtr_); auto &info = buffers_[buf_]; writePtr_ = info.deviceMemory ? info.deviceMemory : info.localMemory; + info.flushOffset = 0; // Force alignment. This is needed for PushAligned() to work as expected. while ((intptr_t)writePtr_ & 15) { writePtr_++; + info.flushOffset++; } - info.flushOffset = 0; assert(writePtr_); } @@ -564,8 +565,10 @@ void GLPushBuffer::Flush() { buffers_[buf_].flushOffset = offset_; if (!buffers_[buf_].deviceMemory && writePtr_) { auto &info = buffers_[buf_]; - glBindBuffer(target_, info.buffer->buffer); - glBufferSubData(target_, 0, info.flushOffset, info.localMemory); + if (info.flushOffset != 0) { + glBindBuffer(target_, info.buffer->buffer); + glBufferSubData(target_, 0, info.flushOffset, info.localMemory); + } // Here we will submit all the draw calls, with the already known buffer and offsets. // Might as well reset the write pointer here and start over the current buffer. @@ -660,6 +663,7 @@ size_t GLPushBuffer::GetTotalSize() const { } void GLPushBuffer::MapDevice() { + bool mapChanged = false; for (auto &info : buffers_) { if (!info.buffer->buffer) { // Can't map - no device buffer associated yet. @@ -669,16 +673,18 @@ void GLPushBuffer::MapDevice() { assert(!info.deviceMemory); // TODO: Can we use GL_WRITE_ONLY? info.deviceMemory = (uint8_t *)info.buffer->Map(GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); + mapChanged = mapChanged || info.deviceMemory != nullptr; if (!info.deviceMemory && !info.localMemory) { // Somehow it failed, let's dodge crashing. info.localMemory = new uint8_t[info.buffer->size_]; + mapChanged = true; } assert(info.localMemory || info.deviceMemory); } - if (writePtr_) { + if (writePtr_ && mapChanged) { // This can happen during a sync. Remap. writePtr_ = nullptr; Map();