Fix terrible drawing glitches when we do sync readbacks.

This commit is contained in:
Henrik Rydgård 2017-12-27 12:44:46 +01:00
parent 542f9f9ef1
commit af8e825578
4 changed files with 37 additions and 1 deletions

View file

@ -157,6 +157,9 @@ void DrawEngineGLES::InitDeviceObjects() {
for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) {
frameData_[i].pushVertex = new GLPushBuffer(render_, GL_ARRAY_BUFFER, 1024 * 1024);
frameData_[i].pushIndex = new GLPushBuffer(render_, GL_ELEMENT_ARRAY_BUFFER, 256 * 1024);
render_->RegisterPushBuffer(i, frameData_[i].pushVertex);
render_->RegisterPushBuffer(i, frameData_[i].pushIndex);
}
int vertexSize = sizeof(TransformedVertex);
@ -170,6 +173,8 @@ void DrawEngineGLES::InitDeviceObjects() {
void DrawEngineGLES::DestroyDeviceObjects() {
for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) {
render_->UnregisterPushBuffer(i, frameData_[i].pushVertex);
render_->UnregisterPushBuffer(i, frameData_[i].pushIndex);
frameData_[i].pushVertex->Destroy();
frameData_[i].pushIndex->Destroy();
delete frameData_[i].pushVertex;

View file

@ -379,6 +379,11 @@ void GLRenderManager::Run(int frame) {
}
void GLRenderManager::FlushSync() {
// Need to flush any pushbuffers to VRAM before submitting draw calls.
for (auto iter : frameData_[curFrame_].activePushBuffers) {
iter->Flush();
}
// TODO: Reset curRenderStep_?
int curFrame = curFrame_;
FrameData &frameData = frameData_[curFrame];
@ -465,6 +470,14 @@ void GLPushBuffer::Unmap() {
writePtr_ = nullptr;
}
void GLPushBuffer::Flush() {
render_->BufferSubdata(buffers_[buf_].buffer, 0, offset_, buffers_[buf_].deviceMemory, false);
// 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.
writePtr_ = buffers_[buf_].deviceMemory;
offset_ = 0;
}
bool GLPushBuffer::AddBuffer() {
BufInfo info;
info.deviceMemory = new uint8_t[size_];
@ -527,4 +540,4 @@ size_t GLPushBuffer::GetTotalSize() const {
sum += size_ * (buffers_.size() - 1);
sum += offset_;
return sum;
}
}

View file

@ -3,6 +3,7 @@
#include <thread>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <mutex>
#include <condition_variable>
@ -14,6 +15,7 @@
#include "GLQueueRunner.h"
class GLRInputLayout;
class GLPushBuffer;
class GLRFramebuffer {
public:
@ -596,6 +598,17 @@ public:
queueRunner_.Resize(width, height);
}
// When using legacy functionality for push buffers (glBufferData), we need to flush them
// before actually making the glDraw* calls. It's best if the render manager handles that.
void RegisterPushBuffer(int frame, GLPushBuffer *buffer) {
frameData_[frame].activePushBuffers.insert(buffer);
}
void UnregisterPushBuffer(int frame, GLPushBuffer *buffer) {
auto iter = frameData_[frame].activePushBuffers.find(buffer);
_assert_(iter != frameData_[frame].activePushBuffers.end());
frameData_[frame].activePushBuffers.erase(iter);
}
private:
void BeginSubmitFrame(int frame);
void EndSubmitFrame(int frame);
@ -629,6 +642,7 @@ private:
uint32_t curSwapchainImage = -1;
GLDeleter deleter;
std::set<GLPushBuffer *> activePushBuffers;
};
FrameData frameData_[MAX_INFLIGHT_FRAMES];
@ -749,6 +763,8 @@ public:
size_t GetTotalSize() const;
void Flush();
private:
bool AddBuffer();
void NextBuffer(size_t minSize);

View file

@ -526,11 +526,13 @@ OpenGLContext::OpenGLContext() {
}
for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) {
frameData_[i].push = new GLPushBuffer(&renderManager_, GL_ARRAY_BUFFER, 64 * 1024);
renderManager_.RegisterPushBuffer(i, frameData_[i].push);
}
}
OpenGLContext::~OpenGLContext() {
for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) {
renderManager_.UnregisterPushBuffer(i, frameData_[i].push);
frameData_[i].push->Destroy();
delete frameData_[i].push;
}