Merge pull request #6216 from stenzek/headless-frame-dumping

OGL: Fix headless frame dumping
This commit is contained in:
Markus Wick 2017-11-26 11:36:10 +01:00 committed by GitHub
commit 96e094e127
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 44 deletions

View File

@ -54,6 +54,7 @@ GLuint FramebufferManager::CreateTexture(GLenum texture_type, GLenum internal_fo
GLenum pixel_format, GLenum data_type) GLenum pixel_format, GLenum data_type)
{ {
GLuint texture; GLuint texture;
glActiveTexture(GL_TEXTURE9);
glGenTextures(1, &texture); glGenTextures(1, &texture);
glBindTexture(texture_type, texture); glBindTexture(texture_type, texture);
if (texture_type == GL_TEXTURE_2D_ARRAY) if (texture_type == GL_TEXTURE_2D_ARRAY)

View File

@ -12,6 +12,7 @@
#include "Core/Config/GraphicsSettings.h" #include "Core/Config/GraphicsSettings.h"
#include "VideoBackends/OGL/FramebufferManager.h" #include "VideoBackends/OGL/FramebufferManager.h"
#include "VideoBackends/OGL/OGLTexture.h"
#include "VideoBackends/OGL/ProgramShaderCache.h" #include "VideoBackends/OGL/ProgramShaderCache.h"
#include "VideoBackends/OGL/SamplerCache.h" #include "VideoBackends/OGL/SamplerCache.h"
@ -121,6 +122,7 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
glBindTexture(GL_TEXTURE_2D_ARRAY, src_texture); glBindTexture(GL_TEXTURE_2D_ARRAY, src_texture);
g_sampler_cache->BindLinearSampler(9); g_sampler_cache->BindLinearSampler(9);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
OGLTexture::SetStage();
} }
void OpenGLPostProcessing::ApplyShader() void OpenGLPostProcessing::ApplyShader()

View File

@ -1349,17 +1349,54 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
// Flip top and bottom for some reason; TODO: Fix the code to suck less? // Flip top and bottom for some reason; TODO: Fix the code to suck less?
std::swap(flipped_trc.top, flipped_trc.bottom); std::swap(flipped_trc.top, flipped_trc.bottom);
// Copy the framebuffer to screen. // Do our OSD callbacks
glBindFramebuffer(GL_FRAMEBUFFER, 0); OSD::DoCallbacks(OSD::CallbackType::OnFrame);
BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(),
xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
// Finish up the current frame, print some stats // Skip screen rendering when running in headless mode.
if (!IsHeadless())
{
// Copy the framebuffer to screen.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(),
xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
// Finish up the current frame, print some stats
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Reset viewport for drawing text
glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight());
DrawDebugText();
OSD::DrawMessages();
// Copy the rendered frame to the real window.
GLInterface->Swap();
}
else
{
// Since we're not swapping in headless mode, ensure all commands are sent to the GPU.
// Otherwise the driver could batch several frames togehter.
glFlush();
}
#ifdef ANDROID
// Handle surface changes on Android.
if (m_surface_needs_change.IsSet())
{
GLInterface->UpdateHandle(m_new_surface_handle);
GLInterface->UpdateSurface();
m_surface_handle = m_new_surface_handle;
m_new_surface_handle = nullptr;
m_surface_needs_change.Clear();
m_surface_changed.Set();
}
#endif
// Update the render window position and the backbuffer size
SetWindowSize(xfb_texture->GetConfig().width, xfb_texture->GetConfig().height); SetWindowSize(xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
GLInterface->Update();
GLInterface->Update(); // just updates the render window position and the backbuffer size // Was the size changed since the last frame?
bool window_resized = false; bool window_resized = false;
int window_width = static_cast<int>(std::max(GLInterface->GetBackBufferWidth(), 1u)); int window_width = static_cast<int>(std::max(GLInterface->GetBackBufferWidth(), 1u));
int window_height = static_cast<int>(std::max(GLInterface->GetBackBufferHeight(), 1u)); int window_height = static_cast<int>(std::max(GLInterface->GetBackBufferHeight(), 1u));
@ -1404,36 +1441,12 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height); BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height);
} }
// ---------------------------------------------------------------------
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Reset viewport for drawing text
glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight());
DrawDebugText();
// Do our OSD callbacks
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
OSD::DrawMessages();
#ifdef ANDROID
if (m_surface_needs_change.IsSet())
{
GLInterface->UpdateHandle(m_new_surface_handle);
GLInterface->UpdateSurface();
m_new_surface_handle = nullptr;
m_surface_needs_change.Clear();
m_surface_changed.Set();
}
#endif
// Copy the rendered frame to the real window
GLInterface->Swap();
// Clear framebuffer // Clear framebuffer
glClearColor(0, 0, 0, 0); if (!IsHeadless())
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); {
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if (s_vsync != g_ActiveConfig.IsVSync()) if (s_vsync != g_ActiveConfig.IsVSync())
{ {

View File

@ -45,9 +45,11 @@ void SWRenderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_regi
{ {
OSD::DoCallbacks(OSD::CallbackType::OnFrame); OSD::DoCallbacks(OSD::CallbackType::OnFrame);
DrawDebugText(); if (!IsHeadless())
{
SWOGLWindow::s_instance->ShowImage(texture, xfb_region); DrawDebugText();
SWOGLWindow::s_instance->ShowImage(texture, xfb_region);
}
UpdateActiveConfig(); UpdateActiveConfig();
} }

View File

@ -600,7 +600,6 @@ void Renderer::DrawScreen(VKTexture* xfb_texture, const EFBRectangle& xfb_region
VK_SUBPASS_CONTENTS_INLINE); VK_SUBPASS_CONTENTS_INLINE);
// Draw // Draw
TargetRectangle source_rc = xfb_texture->GetConfig().GetRect();
BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), xfb_region, BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), xfb_region,
xfb_texture->GetRawTexIdentifier()); xfb_texture->GetRawTexIdentifier());
@ -702,6 +701,7 @@ void Renderer::CheckForSurfaceChange()
// Notify calling thread. // Notify calling thread.
m_surface_needs_change.Clear(); m_surface_needs_change.Clear();
m_surface_handle = m_new_surface_handle;
m_new_surface_handle = nullptr; m_new_surface_handle = nullptr;
m_surface_changed.Set(); m_surface_changed.Set();
} }

View File

@ -14,7 +14,7 @@
#if defined(VK_USE_PLATFORM_WIN32_KHR) #if defined(VK_USE_PLATFORM_WIN32_KHR)
#include <Windows.h> #include <Windows.h>
#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) || \ #elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) || \
defined(VK_USE_PLATFORM_ANDROID_KHR) defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(USE_HEADLESS)
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
@ -98,7 +98,7 @@ void UnloadVulkanLibrary()
} }
#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) || \ #elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) || \
defined(VK_USE_PLATFORM_ANDROID_KHR) defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(USE_HEADLESS)
static void* vulkan_module; static void* vulkan_module;
static std::atomic_int vulkan_module_ref_count = {0}; static std::atomic_int vulkan_module_ref_count = {0};

View File

@ -94,6 +94,7 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
if (SConfig::GetInstance().bWii) if (SConfig::GetInstance().bWii)
m_aspect_wide = Config::Get(Config::SYSCONF_WIDESCREEN); m_aspect_wide = Config::Get(Config::SYSCONF_WIDESCREEN);
m_surface_handle = Host_GetRenderHandle();
m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits; m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits;
} }
@ -400,6 +401,11 @@ float Renderer::CalculateDrawAspectRatio() const
} }
} }
bool Renderer::IsHeadless() const
{
return !m_surface_handle;
}
std::tuple<float, float> Renderer::ScaleToDisplayAspectRatio(const int width, std::tuple<float, float> Renderer::ScaleToDisplayAspectRatio(const int width,
const int height) const const int height) const
{ {
@ -711,7 +717,7 @@ void Renderer::DoDumpFrame()
void Renderer::UpdateFrameDumpTexture() void Renderer::UpdateFrameDumpTexture()
{ {
int target_width, target_height; int target_width, target_height;
if (!g_ActiveConfig.bInternalResolutionFrameDumps) if (!g_ActiveConfig.bInternalResolutionFrameDumps && !IsHeadless())
{ {
auto target_rect = GetTargetRectangle(); auto target_rect = GetTargetRectangle();
target_width = target_rect.GetWidth(); target_width = target_rect.GetWidth();

View File

@ -94,6 +94,7 @@ public:
const TargetRectangle& GetTargetRectangle() const { return m_target_rectangle; } const TargetRectangle& GetTargetRectangle() const { return m_target_rectangle; }
float CalculateDrawAspectRatio() const; float CalculateDrawAspectRatio() const;
bool IsHeadless() const;
std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const; std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const;
void UpdateDrawRectangle(); void UpdateDrawRectangle();
@ -176,9 +177,10 @@ protected:
static const float GX_MAX_DEPTH; static const float GX_MAX_DEPTH;
void* m_surface_handle = nullptr;
void* m_new_surface_handle = nullptr;
Common::Flag m_surface_needs_change; Common::Flag m_surface_needs_change;
Common::Event m_surface_changed; Common::Event m_surface_changed;
void* m_new_surface_handle = nullptr;
u32 m_last_host_config_bits = 0; u32 m_last_host_config_bits = 0;