HostDisplay: Add texture dumping/saving support
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user