mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-06 03:40:12 +00:00
Software: Fix mipmaps and uneven strides in SWTexture
I think this is only used for texture dumping, but this resolves some failed assertions and glitchy results.
This commit is contained in:
parent
56fce3ba8a
commit
b90d23158f
@ -105,7 +105,7 @@ void SWOGLWindow::ShowImage(const AbstractTexture* image,
|
|||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(sw_image->GetConfig().width),
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(sw_image->GetConfig().width),
|
||||||
static_cast<GLsizei>(sw_image->GetConfig().height), 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
static_cast<GLsizei>(sw_image->GetConfig().height), 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
sw_image->GetData());
|
sw_image->GetData(0, 0));
|
||||||
|
|
||||||
glUseProgram(m_image_program);
|
glUseProgram(m_image_program);
|
||||||
|
|
||||||
|
@ -25,17 +25,17 @@ struct Pixel
|
|||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void CopyTextureData(const TextureConfig& src_config, const u8* src_ptr, u32 src_x, u32 src_y,
|
void CopyTextureData(const TextureConfig& src_config, const u8* src_ptr, u32 src_x, u32 src_y,
|
||||||
u32 width, u32 height, const TextureConfig& dst_config, u8* dst_ptr, u32 dst_x,
|
u32 width, u32 height, u32 src_level, const TextureConfig& dst_config,
|
||||||
u32 dst_y)
|
u8* dst_ptr, u32 dst_x, u32 dst_y, u32 dst_level)
|
||||||
{
|
{
|
||||||
size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format);
|
const size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format);
|
||||||
size_t src_stride = src_config.GetStride();
|
const size_t src_stride = src_config.GetMipStride(src_level);
|
||||||
size_t src_offset =
|
const size_t src_offset =
|
||||||
static_cast<size_t>(src_y) * src_stride + static_cast<size_t>(src_x) * texel_size;
|
static_cast<size_t>(src_y) * src_stride + static_cast<size_t>(src_x) * texel_size;
|
||||||
size_t dst_stride = dst_config.GetStride();
|
const size_t dst_stride = dst_config.GetMipStride(dst_level);
|
||||||
size_t dst_offset =
|
const size_t dst_offset =
|
||||||
static_cast<size_t>(dst_y) * dst_stride + static_cast<size_t>(dst_x) * texel_size;
|
static_cast<size_t>(dst_y) * dst_stride + static_cast<size_t>(dst_x) * texel_size;
|
||||||
size_t copy_len = static_cast<size_t>(width) * texel_size;
|
const size_t copy_len = static_cast<size_t>(width) * texel_size;
|
||||||
|
|
||||||
src_ptr += src_offset;
|
src_ptr += src_offset;
|
||||||
dst_ptr += dst_offset;
|
dst_ptr += dst_offset;
|
||||||
@ -56,15 +56,24 @@ void SWRenderer::ScaleTexture(AbstractFramebuffer* dst_framebuffer,
|
|||||||
const SWTexture* software_source_texture = static_cast<const SWTexture*>(src_texture);
|
const SWTexture* software_source_texture = static_cast<const SWTexture*>(src_texture);
|
||||||
SWTexture* software_dest_texture = static_cast<SWTexture*>(dst_framebuffer->GetColorAttachment());
|
SWTexture* software_dest_texture = static_cast<SWTexture*>(dst_framebuffer->GetColorAttachment());
|
||||||
|
|
||||||
CopyRegion(reinterpret_cast<const Pixel*>(software_source_texture->GetData()), src_rect,
|
CopyRegion(reinterpret_cast<const Pixel*>(software_source_texture->GetData(0, 0)), src_rect,
|
||||||
src_texture->GetWidth(), src_texture->GetHeight(),
|
src_texture->GetWidth(), src_texture->GetHeight(),
|
||||||
reinterpret_cast<Pixel*>(software_dest_texture->GetData()), dst_rect,
|
reinterpret_cast<Pixel*>(software_dest_texture->GetData(0, 0)), dst_rect,
|
||||||
dst_framebuffer->GetWidth(), dst_framebuffer->GetHeight());
|
dst_framebuffer->GetWidth(), dst_framebuffer->GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
SWTexture::SWTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config)
|
SWTexture::SWTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config)
|
||||||
{
|
{
|
||||||
m_data.resize(tex_config.width * tex_config.height * 4);
|
m_data.resize(tex_config.layers);
|
||||||
|
for (u32 layer = 0; layer < tex_config.layers; layer++)
|
||||||
|
{
|
||||||
|
m_data[layer].resize(tex_config.levels);
|
||||||
|
for (u32 level = 0; level < tex_config.levels; level++)
|
||||||
|
{
|
||||||
|
m_data[layer][level].resize(std::max(tex_config.width >> level, 1u) *
|
||||||
|
std::max(tex_config.height >> level, 1u) * sizeof(Pixel));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src,
|
void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src,
|
||||||
@ -72,10 +81,10 @@ void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src,
|
|||||||
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,
|
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,
|
||||||
u32 dst_layer, u32 dst_level)
|
u32 dst_layer, u32 dst_level)
|
||||||
{
|
{
|
||||||
ASSERT(src_level == 0 && src_layer == 0 && dst_layer == 0 && dst_level == 0);
|
CopyTextureData(src->GetConfig(),
|
||||||
CopyTextureData(src->GetConfig(), static_cast<const SWTexture*>(src)->m_data.data(),
|
static_cast<const SWTexture*>(src)->GetData(src_layer, src_level), src_rect.left,
|
||||||
src_rect.left, src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config,
|
src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config,
|
||||||
m_data.data(), dst_rect.left, dst_rect.top);
|
GetData(dst_layer, dst_level), dst_rect.left, dst_rect.top, dst_level);
|
||||||
}
|
}
|
||||||
void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& rect,
|
void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& rect,
|
||||||
u32 layer, u32 level)
|
u32 layer, u32 level)
|
||||||
@ -85,17 +94,25 @@ void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::R
|
|||||||
void SWTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
void SWTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||||
size_t buffer_size)
|
size_t buffer_size)
|
||||||
{
|
{
|
||||||
m_data.assign(buffer, buffer + buffer_size);
|
for (u32 layer = 0; layer < m_config.layers; layer++)
|
||||||
|
{
|
||||||
|
u8* data = GetData(layer, level);
|
||||||
|
for (u32 y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
memcpy(&data[width * y * sizeof(Pixel)], &buffer[y * row_length * sizeof(Pixel)],
|
||||||
|
width * sizeof(Pixel));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* SWTexture::GetData() const
|
const u8* SWTexture::GetData(u32 layer, u32 level) const
|
||||||
{
|
{
|
||||||
return m_data.data();
|
return m_data[layer][level].data();
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* SWTexture::GetData()
|
u8* SWTexture::GetData(u32 layer, u32 level)
|
||||||
{
|
{
|
||||||
return m_data.data();
|
return m_data[layer][level].data();
|
||||||
}
|
}
|
||||||
|
|
||||||
SWStagingTexture::SWStagingTexture(StagingTextureType type, const TextureConfig& config)
|
SWStagingTexture::SWStagingTexture(StagingTextureType type, const TextureConfig& config)
|
||||||
@ -112,10 +129,10 @@ void SWStagingTexture::CopyFromTexture(const AbstractTexture* src,
|
|||||||
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
||||||
u32 src_level, const MathUtil::Rectangle<int>& dst_rect)
|
u32 src_level, const MathUtil::Rectangle<int>& dst_rect)
|
||||||
{
|
{
|
||||||
ASSERT(src_level == 0 && src_layer == 0);
|
CopyTextureData(src->GetConfig(),
|
||||||
CopyTextureData(src->GetConfig(), static_cast<const SWTexture*>(src)->GetData(), src_rect.left,
|
static_cast<const SWTexture*>(src)->GetData(src_layer, src_level), src_rect.left,
|
||||||
src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config, m_data.data(),
|
src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config,
|
||||||
dst_rect.left, dst_rect.top);
|
m_data.data(), dst_rect.left, dst_rect.top, 0);
|
||||||
m_needs_flush = true;
|
m_needs_flush = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +140,10 @@ void SWStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, A
|
|||||||
const MathUtil::Rectangle<int>& dst_rect, u32 dst_layer,
|
const MathUtil::Rectangle<int>& dst_rect, u32 dst_layer,
|
||||||
u32 dst_level)
|
u32 dst_level)
|
||||||
{
|
{
|
||||||
ASSERT(dst_level == 0 && dst_layer == 0);
|
|
||||||
CopyTextureData(m_config, m_data.data(), src_rect.left, src_rect.top, src_rect.GetWidth(),
|
CopyTextureData(m_config, m_data.data(), src_rect.left, src_rect.top, src_rect.GetWidth(),
|
||||||
src_rect.GetHeight(), dst->GetConfig(), static_cast<SWTexture*>(dst)->GetData(),
|
src_rect.GetHeight(), 0, dst->GetConfig(),
|
||||||
dst_rect.left, dst_rect.top);
|
static_cast<SWTexture*>(dst)->GetData(dst_layer, dst_level), dst_rect.left,
|
||||||
|
dst_rect.top, dst_level);
|
||||||
m_needs_flush = true;
|
m_needs_flush = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ public:
|
|||||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||||
size_t buffer_size) override;
|
size_t buffer_size) override;
|
||||||
|
|
||||||
const u8* GetData() const;
|
const u8* GetData(u32 layer, u32 level) const;
|
||||||
u8* GetData();
|
u8* GetData(u32 layer, u32 level);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<u8> m_data;
|
std::vector<std::vector<std::vector<u8>>> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SWStagingTexture final : public AbstractStagingTexture
|
class SWStagingTexture final : public AbstractStagingTexture
|
||||||
|
Loading…
x
Reference in New Issue
Block a user