mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-27 02:10:34 +00:00
Get rid of an unused codepath (gl rendering is now always threaded)
This commit is contained in:
parent
ce16547854
commit
8ee426ff74
@ -35,7 +35,8 @@
|
||||
#include "Windows/GPU/WindowsGLContext.h"
|
||||
|
||||
void WindowsGLContext::SwapBuffers() {
|
||||
renderManager_->Swap();
|
||||
// We no longer call RenderManager::Swap here, it's handled by the render thread, which
|
||||
// we're not on here.
|
||||
|
||||
// Used during fullscreen switching to prevent rendering.
|
||||
if (pauseRequested) {
|
||||
|
1
Windows/MainThread.h
Normal file
1
Windows/MainThread.h
Normal file
@ -0,0 +1 @@
|
||||
#pragma once
|
@ -45,11 +45,6 @@ GLRenderManager::GLRenderManager() {
|
||||
for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) {
|
||||
|
||||
}
|
||||
|
||||
if (!useThread_) {
|
||||
// The main thread is also the render thread.
|
||||
ThreadStart();
|
||||
}
|
||||
}
|
||||
|
||||
GLRenderManager::~GLRenderManager() {
|
||||
@ -58,12 +53,7 @@ GLRenderManager::~GLRenderManager() {
|
||||
}
|
||||
// Was anything deleted during shutdown?
|
||||
deleter_.Perform();
|
||||
// _assert_(deleter_.IsEmpty());
|
||||
|
||||
if (!useThread_) {
|
||||
// The main thread is also the render thread.
|
||||
ThreadEnd();
|
||||
}
|
||||
_assert_(deleter_.IsEmpty());
|
||||
}
|
||||
|
||||
void GLRenderManager::ThreadStart() {
|
||||
@ -143,7 +133,7 @@ bool GLRenderManager::ThreadFrame() {
|
||||
void GLRenderManager::StopThread() {
|
||||
// Since we don't control the thread directly, this will only pause the thread.
|
||||
|
||||
if (useThread_ && run_) {
|
||||
if (run_) {
|
||||
run_ = false;
|
||||
for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) {
|
||||
auto &frameData = frameData_[i];
|
||||
@ -170,6 +160,7 @@ void GLRenderManager::StopThread() {
|
||||
// when we restart...
|
||||
for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) {
|
||||
auto &frameData = frameData_[i];
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
if (frameData.readyForRun || frameData.steps.size() != 0) {
|
||||
Crash();
|
||||
}
|
||||
@ -181,7 +172,6 @@ void GLRenderManager::StopThread() {
|
||||
frameData.steps.clear();
|
||||
frameData.initSteps.clear();
|
||||
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
while (!frameData.readyForFence) {
|
||||
VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (stop)", i);
|
||||
frameData.push_condVar.wait(lock);
|
||||
@ -330,7 +320,7 @@ void GLRenderManager::BeginFrame() {
|
||||
FrameData &frameData = frameData_[curFrame];
|
||||
|
||||
// Make sure the very last command buffer from the frame before the previous has been fully executed.
|
||||
if (useThread_) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
while (!frameData.readyForFence) {
|
||||
VLOG("PUSH: Waiting for frame[%d].readyForFence = 1", curFrame);
|
||||
@ -342,10 +332,7 @@ void GLRenderManager::BeginFrame() {
|
||||
|
||||
VLOG("PUSH: Fencing %d", curFrame);
|
||||
|
||||
|
||||
// vkWaitForFences(device, 1, &frameData.fence, true, UINT64_MAX);
|
||||
// vkResetFences(device, 1, &frameData.fence);
|
||||
// glFenceSync(...)
|
||||
// glFenceSync(&frameData.fence...)
|
||||
|
||||
// Must be after the fence - this performs deletes.
|
||||
VLOG("PUSH: BeginFrame %d", curFrame);
|
||||
@ -363,14 +350,7 @@ void GLRenderManager::Finish() {
|
||||
curRenderStep_ = nullptr;
|
||||
int curFrame = GetCurFrame();
|
||||
FrameData &frameData = frameData_[curFrame];
|
||||
if (!useThread_) {
|
||||
frameData.steps = std::move(steps_);
|
||||
steps_.clear();
|
||||
frameData.initSteps = std::move(initSteps_);
|
||||
initSteps_.clear();
|
||||
frameData.type = GLRRunType::END;
|
||||
Run(curFrame);
|
||||
} else {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData.pull_mutex);
|
||||
VLOG("PUSH: Frame[%d].readyForRun = true", curFrame);
|
||||
frameData.steps = std::move(steps_);
|
||||
@ -398,6 +378,7 @@ void GLRenderManager::BeginSubmitFrame(int frame) {
|
||||
}
|
||||
}
|
||||
|
||||
// Render thread
|
||||
void GLRenderManager::Submit(int frame, bool triggerFence) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
|
||||
@ -409,7 +390,7 @@ void GLRenderManager::Submit(int frame, bool triggerFence) {
|
||||
// ideally we'd like to wait a frame or two.
|
||||
frameData.deleter.Perform();
|
||||
|
||||
if (useThread_ && triggerFence) {
|
||||
if (triggerFence) {
|
||||
VLOG("PULL: Frame %d.readyForFence = true", frame);
|
||||
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
@ -420,6 +401,7 @@ void GLRenderManager::Submit(int frame, bool triggerFence) {
|
||||
}
|
||||
}
|
||||
|
||||
// Render thread
|
||||
void GLRenderManager::EndSubmitFrame(int frame) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
frameData.hasBegun = false;
|
||||
@ -435,6 +417,7 @@ void GLRenderManager::EndSubmitFrame(int frame) {
|
||||
}
|
||||
}
|
||||
|
||||
// Render thread
|
||||
void GLRenderManager::Run(int frame) {
|
||||
BeginSubmitFrame(frame);
|
||||
|
||||
@ -472,14 +455,7 @@ void GLRenderManager::FlushSync() {
|
||||
// TODO: Reset curRenderStep_?
|
||||
int curFrame = curFrame_;
|
||||
FrameData &frameData = frameData_[curFrame];
|
||||
if (!useThread_) {
|
||||
frameData.initSteps = std::move(initSteps_);
|
||||
initSteps_.clear();
|
||||
frameData.steps = std::move(steps_);
|
||||
steps_.clear();
|
||||
frameData.type = GLRRunType::SYNC;
|
||||
Run(curFrame);
|
||||
} else {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData.pull_mutex);
|
||||
VLOG("PUSH: Frame[%d].readyForRun = true (sync)", curFrame);
|
||||
frameData.initSteps = std::move(initSteps_);
|
||||
@ -491,8 +467,7 @@ void GLRenderManager::FlushSync() {
|
||||
frameData.type = GLRRunType::SYNC;
|
||||
frameData.pull_condVar.notify_all();
|
||||
}
|
||||
|
||||
if (useThread_) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
// Wait for the flush to be hit, since we're syncing.
|
||||
while (!frameData.readyForFence) {
|
||||
@ -504,19 +479,20 @@ void GLRenderManager::FlushSync() {
|
||||
}
|
||||
}
|
||||
|
||||
// Render thread
|
||||
void GLRenderManager::EndSyncFrame(int frame) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
Submit(frame, false);
|
||||
|
||||
// This is brutal! Should probably wait for a fence instead, not that it'll matter much since we'll
|
||||
// still stall everything.
|
||||
glFinish();
|
||||
// glFinish is not actually necessary here, and won't be until we start using
|
||||
// glBufferStorage. Then we need to use fences.
|
||||
// glFinish();
|
||||
|
||||
// At this point we can resume filling the command buffers for the current frame since
|
||||
// we know the device is idle - and thus all previously enqueued command buffers have been processed.
|
||||
// No need to switch to the next frame number.
|
||||
|
||||
if (useThread_) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
frameData.readyForFence = true;
|
||||
frameData.readyForSubmit = true;
|
||||
@ -533,11 +509,6 @@ void GLRenderManager::Wipe() {
|
||||
}
|
||||
|
||||
void GLRenderManager::WaitUntilQueueIdle() {
|
||||
if (!useThread_) {
|
||||
// Must be idle, nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
// Just wait for all frames to be ready.
|
||||
for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) {
|
||||
FrameData &frameData = frameData_[i];
|
||||
@ -563,16 +534,15 @@ GLPushBuffer::~GLPushBuffer() {
|
||||
void GLPushBuffer::Map() {
|
||||
assert(!writePtr_);
|
||||
// TODO: Even a good old glMapBuffer could actually work well here.
|
||||
// VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
|
||||
writePtr_ = buffers_[buf_].deviceMemory;
|
||||
assert(writePtr_);
|
||||
}
|
||||
|
||||
void GLPushBuffer::Unmap() {
|
||||
assert(writePtr_);
|
||||
// Here we should simply upload everything to the buffers.
|
||||
// Might be worth trying with size_ instead of offset_, so the driver can replace the whole buffer.
|
||||
// At least if it's close.
|
||||
// Here we simply upload the data to the last buffer.
|
||||
// Might be worth trying with size_ instead of offset_, so the driver can replace
|
||||
// the whole buffer. At least if it's close.
|
||||
render_->BufferSubdata(buffers_[buf_].buffer, 0, offset_, buffers_[buf_].deviceMemory, false);
|
||||
writePtr_ = nullptr;
|
||||
}
|
||||
|
@ -663,12 +663,6 @@ public:
|
||||
swapFunction_ = swapFunction;
|
||||
}
|
||||
|
||||
void Swap() {
|
||||
if (!useThread_ && swapFunction_) {
|
||||
swapFunction_();
|
||||
}
|
||||
}
|
||||
|
||||
void StopThread();
|
||||
|
||||
bool SawOutOfMemory() {
|
||||
@ -738,8 +732,6 @@ private:
|
||||
|
||||
GLDeleter deleter_;
|
||||
|
||||
bool useThread_ = true;
|
||||
|
||||
int curFrame_ = 0;
|
||||
|
||||
std::function<void()> swapFunction_;
|
||||
@ -748,10 +740,11 @@ private:
|
||||
int targetHeight_ = 0;
|
||||
};
|
||||
|
||||
|
||||
// Similar to VulkanPushBuffer but uses really stupid tactics - collect all the data in RAM then do a big
|
||||
// memcpy/buffer upload at the end. This can however be optimized with glBufferStorage on chips that support that
|
||||
// for massive boosts.
|
||||
// Similar to VulkanPushBuffer but is currently less efficient - it collects all the data in
|
||||
// RAM then does a big memcpy/buffer upload at the end of the frame. This is at least a lot
|
||||
// faster than the hundreds of buffer uploads or memory array buffers we used before.
|
||||
// On modern GL we could avoid the copy using glBufferStorage but not sure it's worth the
|
||||
// trouble.
|
||||
class GLPushBuffer {
|
||||
public:
|
||||
struct BufInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user