AbstractTexture: Implement Save using new common methods

This commit is contained in:
Stenzek 2017-10-30 22:00:15 +10:00
parent 56afebeb44
commit c2cc128f1b
3 changed files with 28 additions and 11 deletions

View File

@ -97,7 +97,4 @@ private:
std::map<std::pair<u32, u32>, TextureDecodingProgramInfo> m_texture_decoding_program_info; std::map<std::pair<u32, u32>, TextureDecodingProgramInfo> m_texture_decoding_program_info;
std::array<GLuint, TextureConversionShader::BUFFER_FORMAT_COUNT> m_texture_decoding_buffer_views; std::array<GLuint, TextureConversionShader::BUFFER_FORMAT_COUNT> m_texture_decoding_buffer_views;
}; };
bool SaveTexture(const std::string& filename, u32 textarget, u32 tex, int virtual_width,
int virtual_height, unsigned int level);
} }

View File

@ -6,8 +6,10 @@
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/AbstractTexture.h" #include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/ImageWrite.h" #include "VideoCommon/ImageWrite.h"
#include "VideoCommon/RenderBase.h"
AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c) 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 // 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 // framebuffer, and saving that). TextureCache does not call Save for custom textures
// anyway, so this is fine for now. // 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);
if (!result.has_value()) // 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; return false;
}
auto raw_data = result.value(); // Copy to the readback texture's buffer.
return TextureToPng(raw_data.data, raw_data.stride, filename, raw_data.width, raw_data.height); 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;
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() std::optional<AbstractTexture::RawTextureInfo> AbstractTexture::Map()

View File

@ -17,8 +17,8 @@ class AbstractTexture
public: public:
explicit AbstractTexture(const TextureConfig& c); explicit AbstractTexture(const TextureConfig& c);
virtual ~AbstractTexture(); virtual ~AbstractTexture();
virtual void Bind(unsigned int stage) = 0; virtual void Bind(unsigned int stage) = 0;
bool Save(const std::string& filename, unsigned int level);
struct RawTextureInfo struct RawTextureInfo
{ {
@ -43,6 +43,8 @@ public:
virtual void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, virtual void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
size_t buffer_size) = 0; size_t buffer_size) = 0;
bool Save(const std::string& filename, unsigned int level);
static bool IsCompressedFormat(AbstractTextureFormat format); static bool IsCompressedFormat(AbstractTextureFormat format);
static size_t CalculateStrideForFormat(AbstractTextureFormat format, u32 row_length); static size_t CalculateStrideForFormat(AbstractTextureFormat format, u32 row_length);
static size_t GetTexelSizeForFormat(AbstractTextureFormat format); static size_t GetTexelSizeForFormat(AbstractTextureFormat format);