Simpler way to deal with the GL deleter

This commit is contained in:
Henrik Rydgård 2018-01-30 13:32:10 +01:00
parent bd2c875c9a
commit 3a988400a7
4 changed files with 60 additions and 23 deletions

View File

@ -424,9 +424,52 @@ void GLQueueRunner::RunSteps(const std::vector<GLRStep *> &steps) {
}
void GLQueueRunner::LogSteps(const std::vector<GLRStep *> &steps) {
for (int i = 0; i < steps.size(); i++) {
const GLRStep &step = *steps[i];
switch (step.stepType) {
case GLRStepType::RENDER:
LogRenderPass(step);
break;
case GLRStepType::COPY:
LogCopy(step);
break;
case GLRStepType::BLIT:
LogBlit(step);
break;
case GLRStepType::READBACK:
LogReadback(step);
break;
case GLRStepType::READBACK_IMAGE:
LogReadbackImage(step);
break;
default:
Crash();
break;
}
delete steps[i];
}
}
// TODO: Improve these.
void GLQueueRunner::LogRenderPass(const GLRStep &pass) {
ILOG("RenderPass (%d commands)", (int)pass.commands.size());
}
void GLQueueRunner::LogCopy(const GLRStep &pass) {
ILOG("Copy");
}
void GLQueueRunner::LogBlit(const GLRStep &pass) {
ILOG("Blit");
}
void GLQueueRunner::LogReadback(const GLRStep &pass) {
ILOG("Readback");
}
void GLQueueRunner::LogReadbackImage(const GLRStep &pass) {
ILOG("ReadbackImage");
}
void GLQueueRunner::PerformBlit(const GLRStep &step) {
// Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing
@ -990,7 +1033,7 @@ void GLQueueRunner::PerformReadback(const GLRStep &pass) {
const GLuint format = GL_RGBA;
const GLuint type = GL_UNSIGNED_BYTE;
const int srcAlignment = 4;
int dstAlignment = DataFormatSizeInBytes(pass.readback.dstFormat);
int dstAlignment = (int)DataFormatSizeInBytes(pass.readback.dstFormat);
int pixelStride = pass.readback.srcRect.w;
// Apply the correct alignment.

View File

@ -355,8 +355,6 @@ private:
void LogReadback(const GLRStep &pass);
void LogReadbackImage(const GLRStep &pass);
void ResizeReadbackBuffer(size_t requiredSize);
void fbo_ext_create(const GLRInitStep &step);
void fbo_bind_fb_target(bool read, GLuint name);
GLenum fbo_get_fb_target(bool read, GLuint **cached);

View File

@ -13,7 +13,6 @@
#endif
void GLDeleter::Perform() {
deleterMutex_.lock();
for (auto shader : shaders) {
delete shader;
}
@ -38,7 +37,6 @@ void GLDeleter::Perform() {
delete framebuffer;
}
framebuffers.clear();
deleterMutex_.unlock();
}
GLRenderManager::GLRenderManager() {
@ -357,8 +355,6 @@ void GLRenderManager::Finish() {
frameData.pull_condVar.notify_all();
}
frameData_[curFrame_].deleter.Take(deleter_);
curFrame_++;
if (curFrame_ >= MAX_INFLIGHT_FRAMES)
curFrame_ = 0;
@ -380,10 +376,6 @@ void GLRenderManager::Submit(int frame, bool triggerFence) {
// When !triggerFence, we notify after syncing with Vulkan.
// Putting deletes here is safe but only because OpenGL has its own delete handling..
// ideally we'd like to wait a frame or two.
frameData.deleter.Perform();
if (useThread_ && triggerFence) {
VLOG("PULL: Frame %d.readyForFence = true", frame);
@ -414,6 +406,10 @@ void GLRenderManager::Run(int frame) {
BeginSubmitFrame(frame);
FrameData &frameData = frameData_[frame];
// Delete stuff from the last round.
frameData.deleter_prev.Perform();
auto &stepsOnThread = frameData_[frame].steps;
auto &initStepsOnThread = frameData_[frame].initSteps;
// queueRunner_.LogSteps(stepsOnThread);
@ -424,6 +420,7 @@ void GLRenderManager::Run(int frame) {
switch (frameData.type) {
case GLRRunType::END:
frameData.deleter_prev.Take(frameData.deleter);
EndSubmitFrame(frame);
break;

View File

@ -148,12 +148,12 @@ enum class GLRRunType {
SYNC,
};
// Synchronize this externally if needed, no mutex anymore.
class GLDeleter {
public:
void Perform();
void Take(GLDeleter &other) {
deleterMutex_.lock();
_assert_msg_(G3D, shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty(), "Deleter already has stuff");
shaders = std::move(other.shaders);
programs = std::move(other.programs);
@ -167,7 +167,6 @@ public:
other.textures.clear();
other.inputLayouts.clear();
other.framebuffers.clear();
deleterMutex_.unlock();
}
std::vector<GLRShader *> shaders;
@ -176,7 +175,6 @@ public:
std::vector<GLRTexture *> textures;
std::vector<GLRInputLayout *> inputLayouts;
std::vector<GLRFramebuffer *> framebuffers;
std::mutex deleterMutex_;
};
class GLRInputLayout {
@ -291,22 +289,22 @@ public:
}
void DeleteShader(GLRShader *shader) {
deleter_.shaders.push_back(shader);
frameData_[curFrame_].deleter.shaders.push_back(shader);
}
void DeleteProgram(GLRProgram *program) {
deleter_.programs.push_back(program);
frameData_[curFrame_].deleter.programs.push_back(program);
}
void DeleteBuffer(GLRBuffer *buffer) {
deleter_.buffers.push_back(buffer);
frameData_[curFrame_].deleter.buffers.push_back(buffer);
}
void DeleteTexture(GLRTexture *texture) {
deleter_.textures.push_back(texture);
frameData_[curFrame_].deleter.textures.push_back(texture);
}
void DeleteInputLayout(GLRInputLayout *inputLayout) {
deleter_.inputLayouts.push_back(inputLayout);
frameData_[curFrame_].deleter.inputLayouts.push_back(inputLayout);
}
void DeleteFramebuffer(GLRFramebuffer *framebuffer) {
deleter_.framebuffers.push_back(framebuffer);
frameData_[curFrame_].deleter.framebuffers.push_back(framebuffer);
}
void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil);
@ -696,7 +694,10 @@ private:
bool hasBegun = false;
uint32_t curSwapchainImage = -1;
std::mutex deleter_mutex;
GLDeleter deleter;
GLDeleter deleter_prev;
std::set<GLPushBuffer *> activePushBuffers;
};
@ -721,8 +722,6 @@ private:
bool nextFrame = false;
bool firstFrame = true;
GLDeleter deleter_;
bool useThread_ = true;
int curFrame_ = 0;