TextureCache: Support compressed textures and pass pitch/size to upload

This also removes an extra copy of the image for custom textures.
This commit is contained in:
Stenzek
2017-04-16 19:45:22 +10:00
parent bc8a96d713
commit f4b848949c
13 changed files with 51 additions and 36 deletions

View File

@ -750,8 +750,6 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
}
expandedWidth = level.width;
expandedHeight = level.height;
CheckTempSize(level.data_size);
memcpy(temp, level.data.get(), level.data_size);
}
}
@ -774,6 +772,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
config.width = width;
config.height = height;
config.levels = texLevels;
config.format = hires_tex ? hires_tex->GetFormat() : HostTextureFormat::RGBA8;
TCacheEntryBase* entry = AllocateTexture(config);
GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true);
@ -784,17 +783,20 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
const u8* tlut = &texMem[tlutaddr];
if (hires_tex)
{
entry->Load(temp, width, height, expandedWidth, 0);
const auto& level = hires_tex->m_levels[0];
entry->Load(0, level.width, level.height, level.row_length, level.data.get(), level.data_size);
}
else if (decode_on_gpu)
if (!hires_tex && decode_on_gpu)
{
u32 row_stride = bytes_per_block * (expandedWidth / bsw);
g_texture_cache->DecodeTextureOnGPU(
entry, 0, src_data, texture_size, static_cast<TextureFormat>(texformat), width, height,
expandedWidth, expandedHeight, row_stride, tlut, static_cast<TlutFormat>(tlutfmt));
}
else
else if (!hires_tex)
{
size_t decoded_texture_size = expandedWidth * sizeof(u32) * expandedHeight;
CheckTempSize(decoded_texture_size);
if (!(texformat == GX_TF_RGBA8 && from_tmem))
{
TexDecoder_Decode(temp, src_data, expandedWidth, expandedHeight, texformat, tlut,
@ -807,7 +809,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
TexDecoder_DecodeRGBA8FromTmem(temp, src_data, src_data_gb, expandedWidth, expandedHeight);
}
entry->Load(temp, width, height, expandedWidth, 0);
entry->Load(0, width, height, expandedWidth, temp, decoded_texture_size);
}
iter = textures_by_address.emplace(address, entry);
@ -837,9 +839,8 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
for (u32 level_index = 1; level_index != texLevels; ++level_index)
{
const auto& level = hires_tex->m_levels[level_index];
CheckTempSize(level.data_size);
memcpy(temp, level.data.get(), level.data_size);
entry->Load(temp, level.width, level.height, level.width, level_index);
entry->Load(level_index, level.width, level.height, level.row_length, level.data.get(),
level.data_size);
}
}
else
@ -877,9 +878,11 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
}
else
{
// No need to call CheckTempSize here, as mips will always be smaller than the base level.
size_t decoded_mip_size = expanded_mip_width * sizeof(u32) * expanded_mip_height;
TexDecoder_Decode(temp, mip_src_data, expanded_mip_width, expanded_mip_height, texformat,
tlut, (TlutFormat)tlutfmt);
entry->Load(temp, mip_width, mip_height, expanded_mip_width, level);
entry->Load(level, mip_width, mip_height, expanded_mip_width, temp, decoded_mip_size);
}
mip_src_data += mip_size;

View File

@ -27,16 +27,16 @@ public:
bool operator==(const TCacheEntryConfig& o) const
{
return std::tie(width, height, levels, layers, rendertarget) ==
std::tie(o.width, o.height, o.levels, o.layers, o.rendertarget);
return std::tie(width, height, levels, layers, format, rendertarget) ==
std::tie(o.width, o.height, o.levels, o.layers, o.format, o.rendertarget);
}
struct Hasher : std::hash<u64>
{
size_t operator()(const TCacheEntryConfig& c) const
{
u64 id = (u64)c.rendertarget << 63 | (u64)c.layers << 48 | (u64)c.levels << 32 |
(u64)c.height << 16 | (u64)c.width;
u64 id = (u64)c.rendertarget << 63 | (u64)c.format << 50 | (u64)c.layers << 48 |
(u64)c.levels << 32 | (u64)c.height << 16 | (u64)c.width;
return std::hash<u64>::operator()(id);
}
};
@ -45,6 +45,7 @@ public:
u32 height = 0;
u32 levels = 1;
u32 layers = 1;
HostTextureFormat format = HostTextureFormat::RGBA8;
bool rendertarget = false;
};
@ -129,7 +130,8 @@ public:
const MathUtil::Rectangle<int>& srcrect,
const MathUtil::Rectangle<int>& dstrect) = 0;
virtual void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) = 0;
virtual void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
size_t buffer_size) = 0;
virtual void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
unsigned int cbufid, const float* colmat) = 0;