diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index 387375cc85..a002e3e519 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -105,7 +105,7 @@ void SWOGLWindow::ShowImage(const AbstractTexture* image, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(sw_image->GetConfig().width), static_cast(sw_image->GetConfig().height), 0, GL_RGBA, GL_UNSIGNED_BYTE, - sw_image->GetData()); + sw_image->GetData(0, 0)); glUseProgram(m_image_program); diff --git a/Source/Core/VideoBackends/Software/SWTexture.cpp b/Source/Core/VideoBackends/Software/SWTexture.cpp index 082c26371e..6805ff0eb8 100644 --- a/Source/Core/VideoBackends/Software/SWTexture.cpp +++ b/Source/Core/VideoBackends/Software/SWTexture.cpp @@ -25,17 +25,17 @@ struct Pixel #pragma pack(pop) 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 dst_y) + u32 width, u32 height, u32 src_level, const TextureConfig& dst_config, + u8* dst_ptr, u32 dst_x, u32 dst_y, u32 dst_level) { - size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format); - size_t src_stride = src_config.GetStride(); - size_t src_offset = + const size_t texel_size = AbstractTexture::GetTexelSizeForFormat(src_config.format); + const size_t src_stride = src_config.GetMipStride(src_level); + const size_t src_offset = static_cast(src_y) * src_stride + static_cast(src_x) * texel_size; - size_t dst_stride = dst_config.GetStride(); - size_t dst_offset = + const size_t dst_stride = dst_config.GetMipStride(dst_level); + const size_t dst_offset = static_cast(dst_y) * dst_stride + static_cast(dst_x) * texel_size; - size_t copy_len = static_cast(width) * texel_size; + const size_t copy_len = static_cast(width) * texel_size; src_ptr += src_offset; dst_ptr += dst_offset; @@ -56,15 +56,24 @@ void SWRenderer::ScaleTexture(AbstractFramebuffer* dst_framebuffer, const SWTexture* software_source_texture = static_cast(src_texture); SWTexture* software_dest_texture = static_cast(dst_framebuffer->GetColorAttachment()); - CopyRegion(reinterpret_cast(software_source_texture->GetData()), src_rect, + CopyRegion(reinterpret_cast(software_source_texture->GetData(0, 0)), src_rect, src_texture->GetWidth(), src_texture->GetHeight(), - reinterpret_cast(software_dest_texture->GetData()), dst_rect, + reinterpret_cast(software_dest_texture->GetData(0, 0)), dst_rect, dst_framebuffer->GetWidth(), dst_framebuffer->GetHeight()); } 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, @@ -72,10 +81,10 @@ void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src, u32 src_level, const MathUtil::Rectangle& dst_rect, u32 dst_layer, u32 dst_level) { - ASSERT(src_level == 0 && src_layer == 0 && dst_layer == 0 && dst_level == 0); - CopyTextureData(src->GetConfig(), static_cast(src)->m_data.data(), - src_rect.left, src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config, - m_data.data(), dst_rect.left, dst_rect.top); + CopyTextureData(src->GetConfig(), + static_cast(src)->GetData(src_layer, src_level), src_rect.left, + src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config, + GetData(dst_layer, dst_level), dst_rect.left, dst_rect.top, dst_level); } void SWTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle& rect, 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, 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) @@ -112,10 +129,10 @@ void SWStagingTexture::CopyFromTexture(const AbstractTexture* src, const MathUtil::Rectangle& src_rect, u32 src_layer, u32 src_level, const MathUtil::Rectangle& dst_rect) { - ASSERT(src_level == 0 && src_layer == 0); - CopyTextureData(src->GetConfig(), static_cast(src)->GetData(), src_rect.left, - src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), m_config, m_data.data(), - dst_rect.left, dst_rect.top); + CopyTextureData(src->GetConfig(), + static_cast(src)->GetData(src_layer, src_level), src_rect.left, + src_rect.top, src_rect.GetWidth(), src_rect.GetHeight(), src_level, m_config, + m_data.data(), dst_rect.left, dst_rect.top, 0); m_needs_flush = true; } @@ -123,10 +140,10 @@ void SWStagingTexture::CopyToTexture(const MathUtil::Rectangle& src_rect, A const MathUtil::Rectangle& dst_rect, u32 dst_layer, 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(), - src_rect.GetHeight(), dst->GetConfig(), static_cast(dst)->GetData(), - dst_rect.left, dst_rect.top); + src_rect.GetHeight(), 0, dst->GetConfig(), + static_cast(dst)->GetData(dst_layer, dst_level), dst_rect.left, + dst_rect.top, dst_level); m_needs_flush = true; } diff --git a/Source/Core/VideoBackends/Software/SWTexture.h b/Source/Core/VideoBackends/Software/SWTexture.h index bc3fcfbbf7..e3b90eb978 100644 --- a/Source/Core/VideoBackends/Software/SWTexture.h +++ b/Source/Core/VideoBackends/Software/SWTexture.h @@ -29,11 +29,11 @@ public: void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer, size_t buffer_size) override; - const u8* GetData() const; - u8* GetData(); + const u8* GetData(u32 layer, u32 level) const; + u8* GetData(u32 layer, u32 level); private: - std::vector m_data; + std::vector>> m_data; }; class SWStagingTexture final : public AbstractStagingTexture