summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp20
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp65
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h10
4 files changed, 54 insertions, 44 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index e3d31c3eb..046ee55a5 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -327,8 +327,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,
std::size_t end) {
- context->MakeCurrent();
- SCOPE_EXIT({ return context->DoneCurrent(); });
+ const auto scope = context->Acquire();
for (std::size_t i = begin; i < end; ++i) {
if (stop_loading) {
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 8aa4a7ac9..c7d24cf14 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2114,6 +2114,10 @@ private:
template <const std::string_view& opname, Type type>
Expression Atomic(Operation operation) {
+ if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) {
+ UNIMPLEMENTED_MSG("Unimplemented Min & Max for atomic operations");
+ return {};
+ }
return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(),
Visit(operation[1]).As(type)),
type};
@@ -2307,6 +2311,8 @@ private:
~Func() = delete;
static constexpr std::string_view Add = "Add";
+ static constexpr std::string_view Min = "Min";
+ static constexpr std::string_view Max = "Max";
static constexpr std::string_view And = "And";
static constexpr std::string_view Or = "Or";
static constexpr std::string_view Xor = "Xor";
@@ -2457,7 +2463,21 @@ private:
&GLSLDecompiler::AtomicImage<Func::Xor>,
&GLSLDecompiler::AtomicImage<Func::Exchange>,
+ &GLSLDecompiler::Atomic<Func::Exchange, Type::Uint>,
&GLSLDecompiler::Atomic<Func::Add, Type::Uint>,
+ &GLSLDecompiler::Atomic<Func::Min, Type::Uint>,
+ &GLSLDecompiler::Atomic<Func::Max, Type::Uint>,
+ &GLSLDecompiler::Atomic<Func::And, Type::Uint>,
+ &GLSLDecompiler::Atomic<Func::Or, Type::Uint>,
+ &GLSLDecompiler::Atomic<Func::Xor, Type::Uint>,
+
+ &GLSLDecompiler::Atomic<Func::Exchange, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::Add, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::Min, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::Max, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::And, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::Or, Type::Int>,
+ &GLSLDecompiler::Atomic<Func::Xor, Type::Int>,
&GLSLDecompiler::Branch,
&GLSLDecompiler::BranchIndirect,
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index fca5e3ec0..f1a28cc21 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -30,8 +30,6 @@ namespace OpenGL {
namespace {
-// If the size of this is too small, it ends up creating a soft cap on FPS as the renderer will have
-// to wait on available presentation frames.
constexpr std::size_t SWAP_CHAIN_SIZE = 3;
struct Frame {
@@ -214,7 +212,7 @@ public:
std::deque<Frame*> present_queue;
Frame* previous_frame{};
- FrameMailbox() : has_debug_tool{HasDebugTool()} {
+ FrameMailbox() {
for (auto& frame : swap_chain) {
free_queue.push(&frame);
}
@@ -285,13 +283,9 @@ public:
std::unique_lock lock{swap_chain_lock};
present_queue.push_front(frame);
present_cv.notify_one();
-
- DebugNotifyNextFrame();
}
Frame* TryGetPresentFrame(int timeout_ms) {
- DebugWaitForNextFrame();
-
std::unique_lock lock{swap_chain_lock};
// wait for new entries in the present_queue
present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms),
@@ -317,38 +311,12 @@ public:
previous_frame = frame;
return frame;
}
-
-private:
- std::mutex debug_synch_mutex;
- std::condition_variable debug_synch_condition;
- std::atomic_int frame_for_debug{};
- const bool has_debug_tool; // When true, using a GPU debugger, so keep frames in lock-step
-
- /// Signal that a new frame is available (called from GPU thread)
- void DebugNotifyNextFrame() {
- if (!has_debug_tool) {
- return;
- }
- frame_for_debug++;
- std::lock_guard lock{debug_synch_mutex};
- debug_synch_condition.notify_one();
- }
-
- /// Wait for a new frame to be available (called from presentation thread)
- void DebugWaitForNextFrame() {
- if (!has_debug_tool) {
- return;
- }
- const int last_frame = frame_for_debug;
- std::unique_lock lock{debug_synch_mutex};
- debug_synch_condition.wait(lock,
- [this, last_frame] { return frame_for_debug > last_frame; });
- }
};
-RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system)
+RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
+ Core::Frontend::GraphicsContext& context)
: VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system},
- frame_mailbox{std::make_unique<FrameMailbox>()} {}
+ frame_mailbox{}, context{context}, has_debug_tool{HasDebugTool()} {}
RendererOpenGL::~RendererOpenGL() = default;
@@ -356,8 +324,6 @@ MICROPROFILE_DEFINE(OpenGL_RenderFrame, "OpenGL", "Render Frame", MP_RGB(128, 12
MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128));
void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
- render_window.PollEvents();
-
if (!framebuffer) {
return;
}
@@ -413,6 +379,13 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
m_current_frame++;
rasterizer->TickFrame();
}
+
+ render_window.PollEvents();
+ if (has_debug_tool) {
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ Present(0);
+ context.SwapBuffers();
+ }
}
void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) {
@@ -480,6 +453,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
}
void RendererOpenGL::InitOpenGLObjects() {
+ frame_mailbox = std::make_unique<FrameMailbox>();
+
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
0.0f);
@@ -692,12 +667,21 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
-void RendererOpenGL::TryPresent(int timeout_ms) {
+bool RendererOpenGL::TryPresent(int timeout_ms) {
+ if (has_debug_tool) {
+ LOG_DEBUG(Render_OpenGL,
+ "Skipping presentation because we are presenting on the main context");
+ return false;
+ }
+ return Present(timeout_ms);
+}
+
+bool RendererOpenGL::Present(int timeout_ms) {
const auto& layout = render_window.GetFramebufferLayout();
auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms);
if (!frame) {
LOG_DEBUG(Render_OpenGL, "TryGetPresentFrame returned no frame to present");
- return;
+ return false;
}
// Clearing before a full overwrite of a fbo can signal to drivers that they can avoid a
@@ -725,6 +709,7 @@ void RendererOpenGL::TryPresent(int timeout_ms) {
glFlush();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ return true;
}
void RendererOpenGL::RenderScreenshot() {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 33073ce5b..50b647661 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -55,13 +55,14 @@ class FrameMailbox;
class RendererOpenGL final : public VideoCore::RendererBase {
public:
- explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system);
+ explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
+ Core::Frontend::GraphicsContext& context);
~RendererOpenGL() override;
bool Init() override;
void ShutDown() override;
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
- void TryPresent(int timeout_ms) override;
+ bool TryPresent(int timeout_ms) override;
private:
/// Initializes the OpenGL state and creates persistent objects.
@@ -89,8 +90,11 @@ private:
void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer);
+ bool Present(int timeout_ms);
+
Core::Frontend::EmuWindow& emu_window;
Core::System& system;
+ Core::Frontend::GraphicsContext& context;
StateTracker state_tracker{system};
@@ -115,6 +119,8 @@ private:
/// Frame presentation mailbox
std::unique_ptr<FrameMailbox> frame_mailbox;
+
+ bool has_debug_tool = false;
};
} // namespace OpenGL