mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-13 15:59:23 +01:00
Merge pull request #6216 from stenzek/headless-frame-dumping
OGL: Fix headless frame dumping
This commit is contained in:
commit
96e094e127
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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())
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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};
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user