diff options
| author | Stenzek <stenzek@gmail.com> | 2017-10-30 22:00:15 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2017-11-22 18:47:04 +1000 |
| commit | c2cc128f1b6be695a4facd3c0fd697a24c3df17a (patch) | |
| tree | f1785f3044c609d6739b8b10a97c8243802336fb /Source/Core/VideoCommon/AbstractTexture.cpp | |
| parent | 56afebeb44f1ace990d9383e9b840fdc27610029 (diff) | |
AbstractTexture: Implement Save using new common methods
Diffstat (limited to 'Source/Core/VideoCommon/AbstractTexture.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/AbstractTexture.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/Source/Core/VideoCommon/AbstractTexture.cpp b/Source/Core/VideoCommon/AbstractTexture.cpp index 7e09be5344..109bb52897 100644 --- a/Source/Core/VideoCommon/AbstractTexture.cpp +++ b/Source/Core/VideoCommon/AbstractTexture.cpp @@ -6,8 +6,10 @@ #include "Common/Assert.h" #include "Common/MsgHandler.h" +#include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractTexture.h" #include "VideoCommon/ImageWrite.h" +#include "VideoCommon/RenderBase.h" AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c) { @@ -20,17 +22,33 @@ bool AbstractTexture::Save(const std::string& filename, unsigned int level) // We can't dump compressed textures currently (it would mean drawing them to a RGBA8 // framebuffer, and saving that). TextureCache does not call Save for custom textures // anyway, so this is fine for now. - _assert_(m_config.format == AbstractTextureFormat::RGBA8); + _assert_(!IsCompressedFormat(m_config.format)); + _assert_(level < m_config.levels); - auto result = level == 0 ? Map() : Map(level); + // Determine dimensions of image we want to save. + u32 level_width = std::max(1u, m_config.width >> level); + u32 level_height = std::max(1u, m_config.height >> level); + + // Use a temporary staging texture for the download. Certainly not optimal, + // but this is not a frequently-executed code path.. + TextureConfig readback_texture_config(level_width, level_height, 1, 1, + AbstractTextureFormat::RGBA8, false); + auto readback_texture = + g_renderer->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config); + if (!readback_texture) + return false; - if (!result.has_value()) - { + // Copy to the readback texture's buffer. + readback_texture->CopyFromTexture(this, 0, level); + readback_texture->Flush(); + + // Map it so we can encode it to the file. + if (!readback_texture->Map()) return false; - } - auto raw_data = result.value(); - return TextureToPng(raw_data.data, raw_data.stride, filename, raw_data.width, raw_data.height); + return TextureToPng(reinterpret_cast<const u8*>(readback_texture->GetMappedPointer()), + static_cast<int>(readback_texture->GetMappedStride()), filename, level_width, + level_height); } std::optional<AbstractTexture::RawTextureInfo> AbstractTexture::Map() |
