When possible with image viewer, manually unpack unsupported formats

* This is similar to the remapping the replay proxy does, and should support
  most non-compressed formats.
This commit is contained in:
baldurk
2020-05-18 13:21:55 +01:00
parent f622ac36d6
commit cf039acadc
3 changed files with 125 additions and 3 deletions
+90 -1
View File
@@ -24,6 +24,7 @@
#include "common/dds_readwrite.h"
#include "core/core.h"
#include "maths/formatpacking.h"
#include "replay/replay_driver.h"
#include "serialise/rdcfile.h"
#include "stb/stb_image.h"
@@ -175,7 +176,20 @@ public:
void GetTextureData(ResourceId tex, const Subresource &sub, const GetTextureDataParams &params,
bytebuf &data)
{
m_Proxy->GetTextureData(m_TextureID, sub, params, data);
if(tex != m_TextureID && tex != m_CustomTexID)
tex = m_TextureID;
if(tex == m_TextureID && !m_RealTexData.empty() && params.remap == RemapTexture::NoRemap)
{
RDCASSERT(sub.sample == 0);
uint32_t idx = sub.slice * m_TexDetails.mips + sub.mip;
RDCASSERT(idx < m_RealTexData.size(), idx, m_RealTexData.size(), m_TexDetails.mips, sub.slice,
sub.mip);
data = m_RealTexData[idx];
return;
}
m_Proxy->GetTextureData(tex, sub, params, data);
}
// handle a couple of operations ourselves to return a simple fake log
@@ -319,6 +333,10 @@ private:
rdcarray<ResourceDescription> m_Resources;
SDFile m_File;
TextureDescription m_TexDetails;
// if we remapped the texture for display, this contains the real data to return from
// GetTextureData()
rdcarray<bytebuf> m_RealTexData;
};
ReplayStatus IMG_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
@@ -747,7 +765,78 @@ void ImageViewer::RefreshFile()
if(m_TextureID == ResourceId())
{
if(m_Proxy->IsTextureSupported(texDetails))
{
m_TextureID = m_Proxy->CreateProxyTexture(texDetails);
}
else
{
if(dds)
{
// see if we can convert this format on the CPU for proxying
bool convertSupported = false;
ConvertComponents(texDetails.format, NULL, &convertSupported);
if(convertSupported)
{
uint32_t srcStride = texDetails.format.ElementSize();
if(texDetails.format.type == ResourceFormatType::D16S8)
srcStride = 4;
else if(texDetails.format.type == ResourceFormatType::D32S8)
srcStride = 8;
m_RealTexData.resize(texDetails.arraysize * texDetails.mips);
for(uint32_t i = 0; i < texDetails.arraysize * texDetails.mips; i++)
{
const uint32_t mip = i % texDetails.mips;
const uint32_t mipwidth = RDCMAX(1U, texDetails.width >> mip);
const uint32_t mipheight = RDCMAX(1U, texDetails.height >> mip);
const uint32_t mipdepth = RDCMAX(1U, texDetails.depth >> mip);
byte *old = read_data.subdata[i];
m_RealTexData[i].assign(old, read_data.subsizes[i]);
read_data.subsizes[i] = sizeof(FloatVector) * mipwidth * mipheight * mipdepth;
byte *converted = new byte[read_data.subsizes[i]];
byte *src = old;
FloatVector *dst = (FloatVector *)converted;
for(uint32_t z = 0; z < mipdepth; z++)
{
for(uint32_t y = 0; y < mipheight; y++)
{
for(uint32_t x = 0; x < mipwidth; x++)
{
*dst = ConvertComponents(texDetails.format, src);
dst++;
src += srcStride;
}
}
}
read_data.subdata[i] = converted;
delete[] old;
}
TextureDescription remapped = texDetails;
remapped.format = rgba32_float;
m_TextureID = m_Proxy->CreateProxyTexture(remapped);
}
else
{
RDCLOG("Format %s not supported for local display and can't be converted manually.",
texDetails.format.Name().c_str());
}
}
else
{
RDCERR("Standard format %s expected to be supported for local display but can't.",
texDetails.format.Name().c_str());
}
}
}
if(m_TextureID == ResourceId())
+34 -1
View File
@@ -279,10 +279,18 @@ float ConvertLinearToSRGB(float linear)
return 1.055f * powf(linear, 1.0f / 2.4f) - 0.055f;
}
FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data, bool *success)
{
FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f);
const uint64_t dummy = 0;
if(!data)
data = (const byte *)&dummy;
// assume success, we'll set it to false if we hit an error
if(success)
*success = true;
if(fmt.type == ResourceFormatType::R10G10B10A2)
{
Vec4f v;
@@ -419,6 +427,11 @@ FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
{
*comp = float(*i64);
}
else
{
if(success)
*success = false;
}
}
else if(fmt.compByteWidth == 4)
{
@@ -437,6 +450,11 @@ FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
{
*comp = float(*i32);
}
else
{
if(success)
*success = false;
}
}
else if(fmt.compByteWidth == 3 && compType == CompType::Depth)
{
@@ -483,6 +501,11 @@ FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
*comp = f;
}
else
{
if(success)
*success = false;
}
}
else if(fmt.compByteWidth == 1)
{
@@ -516,6 +539,11 @@ FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
*comp = f;
}
else
{
if(success)
*success = false;
}
}
else
{
@@ -540,6 +568,11 @@ FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data)
if(fmt.BGRAOrder())
std::swap(ret.x, ret.z);
}
else
{
if(success)
*success = false;
}
return ret;
}
+1 -1
View File
@@ -110,4 +110,4 @@ float ConvertLinearToSRGB(float linear);
typedef uint8_t byte;
struct ResourceFormat;
FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data);
FloatVector ConvertComponents(const ResourceFormat &fmt, const byte *data, bool *success = NULL);