diff --git a/plugins/GSdx/Renderers/Common/GSTexture.cpp b/plugins/GSdx/Renderers/Common/GSTexture.cpp index 6f7ffb7aeb..bc9aa85586 100644 --- a/plugins/GSdx/Renderers/Common/GSTexture.cpp +++ b/plugins/GSdx/Renderers/Common/GSTexture.cpp @@ -25,11 +25,66 @@ GSTexture::GSTexture() : m_scale(1, 1) , m_size(0, 0) + , m_committed_size(0, 0) + , m_gpu_page_size(0, 0) , m_type(0) , m_format(0) + , m_sparse(false) , last_frame_used(0) , LikelyOffset(false) , OffsetHack_modx(0.0f) , OffsetHack_mody(0.0f) { } + +void GSTexture::CommitRegion(const GSVector2i& region) +{ + if (!m_sparse) + return; + + GSVector2i aligned_region = RoundUpPage(region); + aligned_region.x = std::max(m_committed_size.x, aligned_region.x); + aligned_region.y = std::max(m_committed_size.y, aligned_region.y); + if (aligned_region != m_committed_size) + CommitPages(aligned_region, true); +} + +void GSTexture::Commit() +{ + if (!m_sparse) + return; + + if (m_committed_size != m_size) + CommitPages(m_size, true); +} + +void GSTexture::Uncommit() +{ + if (!m_sparse) + return; + + GSVector2i zero = GSVector2i(0, 0); + + if (m_committed_size != zero) + CommitPages(m_committed_size, false); +} + +void GSTexture::SetGpuPageSize(const GSVector2i& page_size) +{ + ASSERT(std::bitset<32>(page_size.x + 1).count() == 1); + ASSERT(std::bitset<32>(page_size.y + 1).count() == 1); + + m_gpu_page_size = page_size; +} + +GSVector2i GSTexture::RoundUpPage(GSVector2i v) +{ + v.x = std::min(m_size.x, v.x); + v.y = std::min(m_size.y, v.y); + v.x += m_gpu_page_size.x; + v.y += m_gpu_page_size.y; + v.x &= ~m_gpu_page_size.x; + v.y &= ~m_gpu_page_size.y; + + return v; +} diff --git a/plugins/GSdx/Renderers/Common/GSTexture.h b/plugins/GSdx/Renderers/Common/GSTexture.h index ed4dd87805..fe705a66a1 100644 --- a/plugins/GSdx/Renderers/Common/GSTexture.h +++ b/plugins/GSdx/Renderers/Common/GSTexture.h @@ -28,8 +28,11 @@ class GSTexture protected: GSVector2 m_scale; GSVector2i m_size; + GSVector2i m_committed_size; + GSVector2i m_gpu_page_size; int m_type; int m_format; + bool m_sparse; public: struct GSMap {uint8* bits; int pitch;}; @@ -59,6 +62,14 @@ public: int GetType() const {return m_type;} int GetFormat() const {return m_format;} + virtual void CommitPages(const GSVector2i& region, bool commit) {}; + void CommitRegion(const GSVector2i& region); + void Commit(); + void Uncommit(); + GSVector2i GetCommittedSize() const { return m_committed_size; } + void SetGpuPageSize(const GSVector2i& page_size); + GSVector2i RoundUpPage(GSVector2i v); + // frame number (arbitrary base) the texture was recycled on // different purpose than texture cache ages, do not attempt to merge unsigned last_frame_used; diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index 500b1adee9..d7d0c480d9 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -117,6 +117,7 @@ typedef int64 sint64; #include #include #include +#include #include