diff options
| author | 2020-09-19 17:15:02 -0300 | |
|---|---|---|
| committer | 2020-09-20 16:29:41 -0300 | |
| commit | 7003090187e02c8625f4eb7a024ac97f9b0159aa (patch) | |
| tree | b38f399967df79eb7c0dc711508cd54b7c9bf62e /src/video_core | |
| parent | Merge pull request #4643 from FearlessTobi/decrease-pad-update-interval (diff) | |
| download | yuzu-7003090187e02c8625f4eb7a024ac97f9b0159aa.tar.gz yuzu-7003090187e02c8625f4eb7a024ac97f9b0159aa.tar.xz yuzu-7003090187e02c8625f4eb7a024ac97f9b0159aa.zip | |
renderer_opengl: Remove emulated mailbox presentation
Emulated mailbox presentation was causing performance issues on
Nvidia's OpenGL driver. Remove it.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_base.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 288 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 1 |
5 files changed, 22 insertions, 293 deletions
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 649074acd..5c650808b 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -46,11 +46,6 @@ public: | |||
| 46 | /// Finalize rendering the guest frame and draw into the presentation texture | 46 | /// Finalize rendering the guest frame and draw into the presentation texture |
| 47 | virtual void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) = 0; | 47 | virtual void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) = 0; |
| 48 | 48 | ||
| 49 | /// Draws the latest frame to the window waiting timeout_ms for a frame to arrive (Renderer | ||
| 50 | /// specific implementation) | ||
| 51 | /// Returns true if a frame was drawn | ||
| 52 | virtual bool TryPresent(int timeout_ms) = 0; | ||
| 53 | |||
| 54 | // Getter/setter functions: | 49 | // Getter/setter functions: |
| 55 | // ------------------------ | 50 | // ------------------------ |
| 56 | 51 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a4c5b8f74..2ccca1993 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -32,20 +32,6 @@ namespace OpenGL { | |||
| 32 | 32 | ||
| 33 | namespace { | 33 | namespace { |
| 34 | 34 | ||
| 35 | constexpr std::size_t SWAP_CHAIN_SIZE = 3; | ||
| 36 | |||
| 37 | struct Frame { | ||
| 38 | u32 width{}; /// Width of the frame (to detect resize) | ||
| 39 | u32 height{}; /// Height of the frame | ||
| 40 | bool color_reloaded{}; /// Texture attachment was recreated (ie: resized) | ||
| 41 | OpenGL::OGLRenderbuffer color{}; /// Buffer shared between the render/present FBO | ||
| 42 | OpenGL::OGLFramebuffer render{}; /// FBO created on the render thread | ||
| 43 | OpenGL::OGLFramebuffer present{}; /// FBO created on the present thread | ||
| 44 | GLsync render_fence{}; /// Fence created on the render thread | ||
| 45 | GLsync present_fence{}; /// Fence created on the presentation thread | ||
| 46 | bool is_srgb{}; /// Framebuffer is sRGB or RGB | ||
| 47 | }; | ||
| 48 | |||
| 49 | constexpr GLint PositionLocation = 0; | 35 | constexpr GLint PositionLocation = 0; |
| 50 | constexpr GLint TexCoordLocation = 1; | 36 | constexpr GLint TexCoordLocation = 1; |
| 51 | constexpr GLint ModelViewMatrixLocation = 0; | 37 | constexpr GLint ModelViewMatrixLocation = 0; |
| @@ -58,24 +44,6 @@ struct ScreenRectVertex { | |||
| 58 | std::array<GLfloat, 2> tex_coord; | 44 | std::array<GLfloat, 2> tex_coord; |
| 59 | }; | 45 | }; |
| 60 | 46 | ||
| 61 | /// Returns true if any debug tool is attached | ||
| 62 | bool HasDebugTool() { | ||
| 63 | const bool nsight = std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED"); | ||
| 64 | if (nsight) { | ||
| 65 | return true; | ||
| 66 | } | ||
| 67 | |||
| 68 | GLint num_extensions; | ||
| 69 | glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); | ||
| 70 | for (GLuint index = 0; index < static_cast<GLuint>(num_extensions); ++index) { | ||
| 71 | const auto name = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index)); | ||
| 72 | if (!std::strcmp(name, "GL_EXT_debug_tool")) { | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | return false; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | 47 | /** |
| 80 | * Defines a 1:1 pixel ortographic projection matrix with (0,0) on the top-left | 48 | * Defines a 1:1 pixel ortographic projection matrix with (0,0) on the top-left |
| 81 | * corner and (width, height) on the lower-bottom. | 49 | * corner and (width, height) on the lower-bottom. |
| @@ -159,135 +127,15 @@ void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severit | |||
| 159 | 127 | ||
| 160 | } // Anonymous namespace | 128 | } // Anonymous namespace |
| 161 | 129 | ||
| 162 | /** | ||
| 163 | * For smooth Vsync rendering, we want to always present the latest frame that the core generates, | ||
| 164 | * but also make sure that rendering happens at the pace that the frontend dictates. This is a | ||
| 165 | * helper class that the renderer uses to sync frames between the render thread and the presentation | ||
| 166 | * thread | ||
| 167 | */ | ||
| 168 | class FrameMailbox { | ||
| 169 | public: | ||
| 170 | std::mutex swap_chain_lock; | ||
| 171 | std::condition_variable present_cv; | ||
| 172 | std::array<Frame, SWAP_CHAIN_SIZE> swap_chain{}; | ||
| 173 | std::queue<Frame*> free_queue; | ||
| 174 | std::deque<Frame*> present_queue; | ||
| 175 | Frame* previous_frame{}; | ||
| 176 | |||
| 177 | FrameMailbox() { | ||
| 178 | for (auto& frame : swap_chain) { | ||
| 179 | free_queue.push(&frame); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | ~FrameMailbox() { | ||
| 184 | // lock the mutex and clear out the present and free_queues and notify any people who are | ||
| 185 | // blocked to prevent deadlock on shutdown | ||
| 186 | std::scoped_lock lock{swap_chain_lock}; | ||
| 187 | std::queue<Frame*>().swap(free_queue); | ||
| 188 | present_queue.clear(); | ||
| 189 | present_cv.notify_all(); | ||
| 190 | } | ||
| 191 | |||
| 192 | void ReloadPresentFrame(Frame* frame, u32 height, u32 width) { | ||
| 193 | frame->present.Release(); | ||
| 194 | frame->present.Create(); | ||
| 195 | GLint previous_draw_fbo{}; | ||
| 196 | glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previous_draw_fbo); | ||
| 197 | glBindFramebuffer(GL_FRAMEBUFFER, frame->present.handle); | ||
| 198 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, | ||
| 199 | frame->color.handle); | ||
| 200 | if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||
| 201 | LOG_CRITICAL(Render_OpenGL, "Failed to recreate present FBO!"); | ||
| 202 | } | ||
| 203 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, previous_draw_fbo); | ||
| 204 | frame->color_reloaded = false; | ||
| 205 | } | ||
| 206 | |||
| 207 | void ReloadRenderFrame(Frame* frame, u32 width, u32 height) { | ||
| 208 | // Recreate the color texture attachment | ||
| 209 | frame->color.Release(); | ||
| 210 | frame->color.Create(); | ||
| 211 | const GLenum internal_format = frame->is_srgb ? GL_SRGB8 : GL_RGB8; | ||
| 212 | glNamedRenderbufferStorage(frame->color.handle, internal_format, width, height); | ||
| 213 | |||
| 214 | // Recreate the FBO for the render target | ||
| 215 | frame->render.Release(); | ||
| 216 | frame->render.Create(); | ||
| 217 | glBindFramebuffer(GL_FRAMEBUFFER, frame->render.handle); | ||
| 218 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, | ||
| 219 | frame->color.handle); | ||
| 220 | if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||
| 221 | LOG_CRITICAL(Render_OpenGL, "Failed to recreate render FBO!"); | ||
| 222 | } | ||
| 223 | |||
| 224 | frame->width = width; | ||
| 225 | frame->height = height; | ||
| 226 | frame->color_reloaded = true; | ||
| 227 | } | ||
| 228 | |||
| 229 | Frame* GetRenderFrame() { | ||
| 230 | std::unique_lock lock{swap_chain_lock}; | ||
| 231 | |||
| 232 | // If theres no free frames, we will reuse the oldest render frame | ||
| 233 | if (free_queue.empty()) { | ||
| 234 | auto frame = present_queue.back(); | ||
| 235 | present_queue.pop_back(); | ||
| 236 | return frame; | ||
| 237 | } | ||
| 238 | |||
| 239 | Frame* frame = free_queue.front(); | ||
| 240 | free_queue.pop(); | ||
| 241 | return frame; | ||
| 242 | } | ||
| 243 | |||
| 244 | void ReleaseRenderFrame(Frame* frame) { | ||
| 245 | std::unique_lock lock{swap_chain_lock}; | ||
| 246 | present_queue.push_front(frame); | ||
| 247 | present_cv.notify_one(); | ||
| 248 | } | ||
| 249 | |||
| 250 | Frame* TryGetPresentFrame(int timeout_ms) { | ||
| 251 | std::unique_lock lock{swap_chain_lock}; | ||
| 252 | // wait for new entries in the present_queue | ||
| 253 | present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), | ||
| 254 | [&] { return !present_queue.empty(); }); | ||
| 255 | if (present_queue.empty()) { | ||
| 256 | // timed out waiting for a frame to draw so return the previous frame | ||
| 257 | return previous_frame; | ||
| 258 | } | ||
| 259 | |||
| 260 | // free the previous frame and add it back to the free queue | ||
| 261 | if (previous_frame) { | ||
| 262 | free_queue.push(previous_frame); | ||
| 263 | } | ||
| 264 | |||
| 265 | // the newest entries are pushed to the front of the queue | ||
| 266 | Frame* frame = present_queue.front(); | ||
| 267 | present_queue.pop_front(); | ||
| 268 | // remove all old entries from the present queue and move them back to the free_queue | ||
| 269 | for (auto f : present_queue) { | ||
| 270 | free_queue.push(f); | ||
| 271 | } | ||
| 272 | present_queue.clear(); | ||
| 273 | previous_frame = frame; | ||
| 274 | return frame; | ||
| 275 | } | ||
| 276 | }; | ||
| 277 | |||
| 278 | RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, | 130 | RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, |
| 279 | Core::Frontend::EmuWindow& emu_window_, | 131 | Core::Frontend::EmuWindow& emu_window_, |
| 280 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, | 132 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, |
| 281 | std::unique_ptr<Core::Frontend::GraphicsContext> context) | 133 | std::unique_ptr<Core::Frontend::GraphicsContext> context) |
| 282 | : RendererBase{emu_window_, std::move(context)}, telemetry_session{telemetry_session_}, | 134 | : RendererBase{emu_window_, std::move(context)}, telemetry_session{telemetry_session_}, |
| 283 | emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, program_manager{device}, | 135 | emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, program_manager{device} {} |
| 284 | has_debug_tool{HasDebugTool()} {} | ||
| 285 | 136 | ||
| 286 | RendererOpenGL::~RendererOpenGL() = default; | 137 | RendererOpenGL::~RendererOpenGL() = default; |
| 287 | 138 | ||
| 288 | MICROPROFILE_DEFINE(OpenGL_RenderFrame, "OpenGL", "Render Frame", MP_RGB(128, 128, 64)); | ||
| 289 | MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128)); | ||
| 290 | |||
| 291 | void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | 139 | void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { |
| 292 | if (!framebuffer) { | 140 | if (!framebuffer) { |
| 293 | return; | 141 | return; |
| @@ -296,79 +144,34 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 296 | PrepareRendertarget(framebuffer); | 144 | PrepareRendertarget(framebuffer); |
| 297 | RenderScreenshot(); | 145 | RenderScreenshot(); |
| 298 | 146 | ||
| 299 | Frame* frame; | 147 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
| 300 | { | 148 | DrawScreen(emu_window.GetFramebufferLayout()); |
| 301 | MICROPROFILE_SCOPE(OpenGL_WaitPresent); | ||
| 302 | |||
| 303 | frame = frame_mailbox->GetRenderFrame(); | ||
| 304 | |||
| 305 | // Clean up sync objects before drawing | ||
| 306 | |||
| 307 | // INTEL driver workaround. We can't delete the previous render sync object until we are | ||
| 308 | // sure that the presentation is done | ||
| 309 | if (frame->present_fence) { | ||
| 310 | glClientWaitSync(frame->present_fence, 0, GL_TIMEOUT_IGNORED); | ||
| 311 | } | ||
| 312 | |||
| 313 | // delete the draw fence if the frame wasn't presented | ||
| 314 | if (frame->render_fence) { | ||
| 315 | glDeleteSync(frame->render_fence); | ||
| 316 | frame->render_fence = 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | // wait for the presentation to be done | ||
| 320 | if (frame->present_fence) { | ||
| 321 | glWaitSync(frame->present_fence, 0, GL_TIMEOUT_IGNORED); | ||
| 322 | glDeleteSync(frame->present_fence); | ||
| 323 | frame->present_fence = 0; | ||
| 324 | } | ||
| 325 | } | ||
| 326 | 149 | ||
| 327 | { | 150 | ++m_current_frame; |
| 328 | MICROPROFILE_SCOPE(OpenGL_RenderFrame); | ||
| 329 | const auto& layout = render_window.GetFramebufferLayout(); | ||
| 330 | 151 | ||
| 331 | // Recreate the frame if the size of the window has changed | 152 | rasterizer->TickFrame(); |
| 332 | if (layout.width != frame->width || layout.height != frame->height || | ||
| 333 | screen_info.display_srgb != frame->is_srgb) { | ||
| 334 | LOG_DEBUG(Render_OpenGL, "Reloading render frame"); | ||
| 335 | frame->is_srgb = screen_info.display_srgb; | ||
| 336 | frame_mailbox->ReloadRenderFrame(frame, layout.width, layout.height); | ||
| 337 | } | ||
| 338 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frame->render.handle); | ||
| 339 | DrawScreen(layout); | ||
| 340 | // Create a fence for the frontend to wait on and swap this frame to OffTex | ||
| 341 | frame->render_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | ||
| 342 | glFlush(); | ||
| 343 | frame_mailbox->ReleaseRenderFrame(frame); | ||
| 344 | m_current_frame++; | ||
| 345 | rasterizer->TickFrame(); | ||
| 346 | } | ||
| 347 | 153 | ||
| 348 | render_window.PollEvents(); | 154 | render_window.PollEvents(); |
| 349 | if (has_debug_tool) { | 155 | context->SwapBuffers(); |
| 350 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | ||
| 351 | Present(0); | ||
| 352 | context->SwapBuffers(); | ||
| 353 | } | ||
| 354 | } | 156 | } |
| 355 | 157 | ||
| 356 | void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { | 158 | void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { |
| 357 | if (framebuffer) { | 159 | if (!framebuffer) { |
| 358 | // If framebuffer is provided, reload it from memory to a texture | 160 | return; |
| 359 | if (screen_info.texture.width != static_cast<GLsizei>(framebuffer->width) || | 161 | } |
| 360 | screen_info.texture.height != static_cast<GLsizei>(framebuffer->height) || | 162 | // If framebuffer is provided, reload it from memory to a texture |
| 361 | screen_info.texture.pixel_format != framebuffer->pixel_format || | 163 | if (screen_info.texture.width != static_cast<GLsizei>(framebuffer->width) || |
| 362 | gl_framebuffer_data.empty()) { | 164 | screen_info.texture.height != static_cast<GLsizei>(framebuffer->height) || |
| 363 | // Reallocate texture if the framebuffer size has changed. | 165 | screen_info.texture.pixel_format != framebuffer->pixel_format || |
| 364 | // This is expected to not happen very often and hence should not be a | 166 | gl_framebuffer_data.empty()) { |
| 365 | // performance problem. | 167 | // Reallocate texture if the framebuffer size has changed. |
| 366 | ConfigureFramebufferTexture(screen_info.texture, *framebuffer); | 168 | // This is expected to not happen very often and hence should not be a |
| 367 | } | 169 | // performance problem. |
| 368 | 170 | ConfigureFramebufferTexture(screen_info.texture, *framebuffer); | |
| 369 | // Load the framebuffer from memory, draw it to the screen, and swap buffers | ||
| 370 | LoadFBToScreenInfo(*framebuffer); | ||
| 371 | } | 171 | } |
| 172 | |||
| 173 | // Load the framebuffer from memory, draw it to the screen, and swap buffers | ||
| 174 | LoadFBToScreenInfo(*framebuffer); | ||
| 372 | } | 175 | } |
| 373 | 176 | ||
| 374 | void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer) { | 177 | void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer) { |
| @@ -418,8 +221,6 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color | |||
| 418 | } | 221 | } |
| 419 | 222 | ||
| 420 | void RendererOpenGL::InitOpenGLObjects() { | 223 | void RendererOpenGL::InitOpenGLObjects() { |
| 421 | frame_mailbox = std::make_unique<FrameMailbox>(); | ||
| 422 | |||
| 423 | glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), | 224 | glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), |
| 424 | Settings::values.bg_blue.GetValue(), 0.0f); | 225 | Settings::values.bg_blue.GetValue(), 0.0f); |
| 425 | 226 | ||
| @@ -647,51 +448,6 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 647 | program_manager.RestoreGuestPipeline(); | 448 | program_manager.RestoreGuestPipeline(); |
| 648 | } | 449 | } |
| 649 | 450 | ||
| 650 | bool RendererOpenGL::TryPresent(int timeout_ms) { | ||
| 651 | if (has_debug_tool) { | ||
| 652 | LOG_DEBUG(Render_OpenGL, | ||
| 653 | "Skipping presentation because we are presenting on the main context"); | ||
| 654 | return false; | ||
| 655 | } | ||
| 656 | return Present(timeout_ms); | ||
| 657 | } | ||
| 658 | |||
| 659 | bool RendererOpenGL::Present(int timeout_ms) { | ||
| 660 | const auto& layout = render_window.GetFramebufferLayout(); | ||
| 661 | auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms); | ||
| 662 | if (!frame) { | ||
| 663 | LOG_DEBUG(Render_OpenGL, "TryGetPresentFrame returned no frame to present"); | ||
| 664 | return false; | ||
| 665 | } | ||
| 666 | |||
| 667 | // Clearing before a full overwrite of a fbo can signal to drivers that they can avoid a | ||
| 668 | // readback since we won't be doing any blending | ||
| 669 | glClear(GL_COLOR_BUFFER_BIT); | ||
| 670 | |||
| 671 | // Recreate the presentation FBO if the color attachment was changed | ||
| 672 | if (frame->color_reloaded) { | ||
| 673 | LOG_DEBUG(Render_OpenGL, "Reloading present frame"); | ||
| 674 | frame_mailbox->ReloadPresentFrame(frame, layout.width, layout.height); | ||
| 675 | } | ||
| 676 | glWaitSync(frame->render_fence, 0, GL_TIMEOUT_IGNORED); | ||
| 677 | // INTEL workaround. | ||
| 678 | // Normally we could just delete the draw fence here, but due to driver bugs, we can just delete | ||
| 679 | // it on the emulation thread without too much penalty | ||
| 680 | // glDeleteSync(frame.render_sync); | ||
| 681 | // frame.render_sync = 0; | ||
| 682 | |||
| 683 | glBindFramebuffer(GL_READ_FRAMEBUFFER, frame->present.handle); | ||
| 684 | glBlitFramebuffer(0, 0, frame->width, frame->height, 0, 0, layout.width, layout.height, | ||
| 685 | GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||
| 686 | |||
| 687 | // Insert fence for the main thread to block on | ||
| 688 | frame->present_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | ||
| 689 | glFlush(); | ||
| 690 | |||
| 691 | glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); | ||
| 692 | return true; | ||
| 693 | } | ||
| 694 | |||
| 695 | void RendererOpenGL::RenderScreenshot() { | 451 | void RendererOpenGL::RenderScreenshot() { |
| 696 | if (!renderer_settings.screenshot_requested) { | 452 | if (!renderer_settings.screenshot_requested) { |
| 697 | return; | 453 | return; |
| @@ -706,7 +462,7 @@ void RendererOpenGL::RenderScreenshot() { | |||
| 706 | screenshot_framebuffer.Create(); | 462 | screenshot_framebuffer.Create(); |
| 707 | glBindFramebuffer(GL_FRAMEBUFFER, screenshot_framebuffer.handle); | 463 | glBindFramebuffer(GL_FRAMEBUFFER, screenshot_framebuffer.handle); |
| 708 | 464 | ||
| 709 | Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout}; | 465 | const Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout}; |
| 710 | 466 | ||
| 711 | GLuint renderbuffer; | 467 | GLuint renderbuffer; |
| 712 | glGenRenderbuffers(1, &renderbuffer); | 468 | glGenRenderbuffers(1, &renderbuffer); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 5329577fb..9ef181f95 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -55,14 +55,6 @@ struct ScreenInfo { | |||
| 55 | TextureInfo texture; | 55 | TextureInfo texture; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | struct PresentationTexture { | ||
| 59 | u32 width = 0; | ||
| 60 | u32 height = 0; | ||
| 61 | OGLTexture texture; | ||
| 62 | }; | ||
| 63 | |||
| 64 | class FrameMailbox; | ||
| 65 | |||
| 66 | class RendererOpenGL final : public VideoCore::RendererBase { | 58 | class RendererOpenGL final : public VideoCore::RendererBase { |
| 67 | public: | 59 | public: |
| 68 | explicit RendererOpenGL(Core::TelemetrySession& telemetry_session, | 60 | explicit RendererOpenGL(Core::TelemetrySession& telemetry_session, |
| @@ -74,7 +66,6 @@ public: | |||
| 74 | bool Init() override; | 66 | bool Init() override; |
| 75 | void ShutDown() override; | 67 | void ShutDown() override; |
| 76 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; | 68 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; |
| 77 | bool TryPresent(int timeout_ms) override; | ||
| 78 | 69 | ||
| 79 | private: | 70 | private: |
| 80 | /// Initializes the OpenGL state and creates persistent objects. | 71 | /// Initializes the OpenGL state and creates persistent objects. |
| @@ -102,8 +93,6 @@ private: | |||
| 102 | 93 | ||
| 103 | void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer); | 94 | void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer); |
| 104 | 95 | ||
| 105 | bool Present(int timeout_ms); | ||
| 106 | |||
| 107 | Core::TelemetrySession& telemetry_session; | 96 | Core::TelemetrySession& telemetry_session; |
| 108 | Core::Frontend::EmuWindow& emu_window; | 97 | Core::Frontend::EmuWindow& emu_window; |
| 109 | Core::Memory::Memory& cpu_memory; | 98 | Core::Memory::Memory& cpu_memory; |
| @@ -134,11 +123,6 @@ private: | |||
| 134 | /// Used for transforming the framebuffer orientation | 123 | /// Used for transforming the framebuffer orientation |
| 135 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags{}; | 124 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags{}; |
| 136 | Common::Rectangle<int> framebuffer_crop_rect; | 125 | Common::Rectangle<int> framebuffer_crop_rect; |
| 137 | |||
| 138 | /// Frame presentation mailbox | ||
| 139 | std::unique_ptr<FrameMailbox> frame_mailbox; | ||
| 140 | |||
| 141 | bool has_debug_tool = false; | ||
| 142 | }; | 126 | }; |
| 143 | 127 | ||
| 144 | } // namespace OpenGL | 128 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 0e4583986..d38e797a4 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -283,11 +283,6 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 283 | render_window.PollEvents(); | 283 | render_window.PollEvents(); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | bool RendererVulkan::TryPresent(int /*timeout_ms*/) { | ||
| 287 | // TODO (bunnei): ImplementMe | ||
| 288 | return true; | ||
| 289 | } | ||
| 290 | |||
| 291 | bool RendererVulkan::Init() { | 286 | bool RendererVulkan::Init() { |
| 292 | library = OpenVulkanLibrary(); | 287 | library = OpenVulkanLibrary(); |
| 293 | instance = CreateInstance(library, dld, render_window.GetWindowInfo().type, | 288 | instance = CreateInstance(library, dld, render_window.GetWindowInfo().type, |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index ddff77942..5085310d0 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -55,7 +55,6 @@ public: | |||
| 55 | bool Init() override; | 55 | bool Init() override; |
| 56 | void ShutDown() override; | 56 | void ShutDown() override; |
| 57 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; | 57 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; |
| 58 | bool TryPresent(int timeout_ms) override; | ||
| 59 | 58 | ||
| 60 | static std::vector<std::string> EnumerateDevices(); | 59 | static std::vector<std::string> EnumerateDevices(); |
| 61 | 60 | ||