mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 14:15:47 -04:00
HostDisplay: Support screenshotting 16-bit display formats
This commit is contained in:
@ -155,8 +155,8 @@ void D3D11HostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y,
|
||||
}
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride)
|
||||
bool D3D11HostDisplay::DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, 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));
|
||||
@ -169,8 +169,17 @@ bool D3D11HostDisplay::DownloadTexture(const void* texture_handle, u32 x, u32 y,
|
||||
return false;
|
||||
|
||||
m_readback_staging_texture.CopyFromTexture(m_context.Get(), srv_resource.Get(), 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));
|
||||
|
||||
if (srv_desc.Format == DXGI_FORMAT_B5G6R5_UNORM || srv_desc.Format == DXGI_FORMAT_B5G5R5A1_UNORM)
|
||||
{
|
||||
return m_readback_staging_texture.ReadPixels<u16>(m_context.Get(), 0, 0, width, height,
|
||||
out_data_stride / sizeof(u16), static_cast<u16*>(out_data));
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_readback_staging_texture.ReadPixels<u32>(m_context.Get(), 0, 0, width, height,
|
||||
out_data_stride / sizeof(u32), static_cast<u32*>(out_data));
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr std::array<DXGI_FORMAT, static_cast<u32>(HostDisplayPixelFormat::Count)>
|
||||
|
@ -55,8 +55,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;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
|
@ -83,46 +83,6 @@ std::unique_ptr<HostDisplayTexture> OpenGLHostDisplay::CreateTexture(u32 width,
|
||||
return OpenGLHostDisplayTexture::Create(width, height, initial_data, initial_data_stride);
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height,
|
||||
const void* texture_data, u32 texture_data_stride)
|
||||
{
|
||||
OpenGLHostDisplayTexture* tex = static_cast<OpenGLHostDisplayTexture*>(texture);
|
||||
Assert((texture_data_stride % sizeof(u32)) == 0);
|
||||
|
||||
GLint old_texture_binding = 0, old_alignment = 0, old_row_length = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture_binding);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_alignment);
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &old_row_length);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex->GetGLID());
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture_data_stride / sizeof(u32));
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length);
|
||||
glBindTexture(GL_TEXTURE_2D, old_texture_binding);
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::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;
|
||||
}
|
||||
|
||||
static constexpr std::array<std::tuple<GLenum, GLenum, GLenum>, static_cast<u32>(HostDisplayPixelFormat::Count)>
|
||||
s_display_pixel_format_mapping = {{
|
||||
{}, // Unknown
|
||||
@ -132,6 +92,65 @@ static constexpr std::array<std::tuple<GLenum, GLenum, GLenum>, static_cast<u32>
|
||||
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV} // RGBA5551
|
||||
}};
|
||||
|
||||
void OpenGLHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height,
|
||||
const void* texture_data, u32 texture_data_stride)
|
||||
{
|
||||
OpenGLHostDisplayTexture* tex = static_cast<OpenGLHostDisplayTexture*>(texture);
|
||||
const auto [gl_internal_format, gl_format, gl_type] =
|
||||
s_display_pixel_format_mapping[static_cast<u32>(texture->GetFormat())];
|
||||
GLint alignment;
|
||||
if (texture_data_stride & 1)
|
||||
alignment = 1;
|
||||
else if (texture_data_stride & 2)
|
||||
alignment = 2;
|
||||
else
|
||||
alignment = 4;
|
||||
|
||||
GLint old_texture_binding = 0, old_alignment = 0, old_row_length = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture_binding);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_alignment);
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &old_row_length);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex->GetGLID());
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture_data_stride / GetDisplayPixelFormatSize(texture->GetFormat()));
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, texture_data);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length);
|
||||
glBindTexture(GL_TEXTURE_2D, old_texture_binding);
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y,
|
||||
u32 width, u32 height, void* out_data, u32 out_data_stride)
|
||||
{
|
||||
GLint alignment;
|
||||
if (out_data_stride & 1)
|
||||
alignment = 1;
|
||||
else if (out_data_stride & 2)
|
||||
alignment = 2;
|
||||
else
|
||||
alignment = 4;
|
||||
|
||||
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, alignment);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / GetDisplayPixelFormatSize(texture_format));
|
||||
|
||||
const GLuint texture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture_handle));
|
||||
const auto [gl_internal_format, gl_format, gl_type] =
|
||||
s_display_pixel_format_mapping[static_cast<u32>(texture_format)];
|
||||
|
||||
GL::Texture::GetTextureSubImage(texture, 0, x, y, 0, width, height, 1, gl_format, gl_type, height * out_data_stride,
|
||||
out_data);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, old_alignment);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, old_row_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const
|
||||
{
|
||||
return (std::get<0>(s_display_pixel_format_mapping[static_cast<u32>(format)]) != static_cast<GLenum>(0));
|
||||
|
@ -55,8 +55,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;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
|
@ -230,14 +230,13 @@ void VulkanHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y,
|
||||
staging_texture->CopyToTexture(0, 0, vk_texture->GetTexture(), x, y, 0, 0, width, height);
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::DownloadTexture(const void* texture_handle, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride)
|
||||
bool VulkanHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y,
|
||||
u32 width, u32 height, void* out_data, u32 out_data_stride)
|
||||
{
|
||||
Vulkan::Texture* texture = static_cast<Vulkan::Texture*>(const_cast<void*>(texture_handle));
|
||||
|
||||
if ((m_readback_staging_texture.GetWidth() < width || m_readback_staging_texture.GetHeight() < height) &&
|
||||
!m_readback_staging_texture.Create(Vulkan::StagingBuffer::Type::Readback, VK_FORMAT_R8G8B8A8_UNORM, width,
|
||||
height))
|
||||
!m_readback_staging_texture.Create(Vulkan::StagingBuffer::Type::Readback, texture->GetFormat(), width, height))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -52,8 +52,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;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
|
Reference in New Issue
Block a user