HostDisplay: Add texture dumping/saving support

This commit is contained in:
Connor McLaughlin
2020-03-16 00:03:49 +10:00
parent b4153266a0
commit 2bb992a702
10 changed files with 256 additions and 3 deletions

View File

@@ -141,6 +141,24 @@ void D3D11DisplayWidget::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y
}
}
bool D3D11DisplayWidget::DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height,
void* out_data, u32 out_data_stride)
{
ID3D11ShaderResourceView* srv =
const_cast<ID3D11ShaderResourceView*>(static_cast<const ID3D11ShaderResourceView*>(texture_handle));
ID3D11Resource* srv_resource;
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
srv->GetResource(&srv_resource);
srv->GetDesc(&srv_desc);
if (!m_readback_staging_texture.EnsureSize(m_context.Get(), width, height, srv_desc.Format, false))
return false;
m_readback_staging_texture.CopyFromTexture(m_context.Get(), srv_resource, 0, x, y, 0, 0, width, height);
return m_readback_staging_texture.ReadPixels<u32>(m_context.Get(), 0, 0, width, height, out_data_stride / sizeof(u32),
static_cast<u32*>(out_data));
}
void D3D11DisplayWidget::SetVSync(bool enabled)
{
m_vsync = enabled;

View File

@@ -1,4 +1,5 @@
#pragma once
#include "common/d3d11/staging_texture.h"
#include "common/d3d11/stream_buffer.h"
#include "common/d3d11/texture.h"
#include "common/windows_headers.h"
@@ -39,6 +40,8 @@ public:
u32 initial_data_stride, bool dynamic) override;
void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* texture_data,
u32 texture_data_stride) override;
bool DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, void* out_data,
u32 out_data_stride) override;
void SetVSync(bool enabled) override;
@@ -74,6 +77,7 @@ private:
D3D11::Texture m_display_pixels_texture;
D3D11::StreamBuffer m_display_uniform_buffer;
D3D11::AutoStagingTexture m_readback_staging_texture;
bool m_allow_tearing_supported = false;
bool m_vsync = false;

View File

@@ -164,6 +164,24 @@ void OpenGLDisplayWidget::UpdateTexture(HostDisplayTexture* texture, u32 x, u32
glBindTexture(GL_TEXTURE_2D, old_texture_binding);
}
bool OpenGLDisplayWidget::DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height,
void* out_data, u32 out_data_stride)
{
GLint old_alignment = 0, old_row_length = 0;
glGetIntegerv(GL_PACK_ALIGNMENT, &old_alignment);
glGetIntegerv(GL_PACK_ROW_LENGTH, &old_row_length);
glPixelStorei(GL_PACK_ALIGNMENT, sizeof(u32));
glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / sizeof(u32));
const GLuint texture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture_handle));
GL::Texture::GetTextureSubImage(texture, 0, x, y, 0, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE,
height * out_data_stride, out_data);
glPixelStorei(GL_PACK_ALIGNMENT, old_alignment);
glPixelStorei(GL_PACK_ROW_LENGTH, old_row_length);
return true;
}
void OpenGLDisplayWidget::SetVSync(bool enabled)
{
// Window framebuffer has to be bound to call SetSwapInterval.

View File

@@ -44,6 +44,8 @@ public:
u32 initial_data_stride, bool dynamic) override;
void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* texture_data,
u32 texture_data_stride) override;
bool DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, void* out_data,
u32 out_data_stride) override;
void SetVSync(bool enabled) override;