diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index 5c1aed1c44..c14fdca6de 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -129,18 +129,14 @@ protected: // TODO: virtual void Write(Source* s, const GSVector4i& r) = 0; // TODO: virtual void Write(Target* t, const GSVector4i& r) = 0; -#ifndef DISABLE_HW_TEXTURE_CACHE - virtual void Read(Target* t, const GSVector4i& r) = 0; -#endif virtual bool CanConvertDepth() { return m_can_convert_depth; } public: GSTextureCache(GSRenderer* r); virtual ~GSTextureCache(); -#ifdef DISABLE_HW_TEXTURE_CACHE virtual void Read(Target* t, const GSVector4i& r) = 0; -#endif + virtual void Read(Source* t, const GSVector4i& r) = 0; void RemoveAll(); void RemovePartial(); diff --git a/plugins/GSdx/GSTextureCache11.cpp b/plugins/GSdx/GSTextureCache11.cpp index 72c4251935..553c3c1f24 100644 --- a/plugins/GSdx/GSTextureCache11.cpp +++ b/plugins/GSdx/GSTextureCache11.cpp @@ -97,3 +97,27 @@ void GSTextureCache11::Read(Target* t, const GSVector4i& r) } } +void GSTextureCache11::Read(Source* t, const GSVector4i& r) +{ + // FIXME: copy was copyied from openGL. It is unlikely to work. + + const GIFRegTEX0& TEX0 = t->m_TEX0; + + if (GSTexture* offscreen = m_renderer->m_dev->CreateOffscreen(r.width(), r.height())) { + m_renderer->m_dev->CopyRect(t->m_texture, offscreen, r); + + GSTexture::GSMap m; + GSVector4i r_offscreen(0, 0, r.width(), r.height()); + + if (offscreen->Map(m, &r_offscreen)) { + GSOffset* off = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); + + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, off, r); + + offscreen->Unmap(); + } + + // FIXME invalidate data + m_renderer->m_dev->Recycle(offscreen); + } +} diff --git a/plugins/GSdx/GSTextureCache11.h b/plugins/GSdx/GSTextureCache11.h index d110dbe156..0c6f6264fa 100644 --- a/plugins/GSdx/GSTextureCache11.h +++ b/plugins/GSdx/GSTextureCache11.h @@ -30,6 +30,7 @@ protected: int Get8bitFormat() {return DXGI_FORMAT_A8_UNORM;} void Read(Target* t, const GSVector4i& r); + void Read(Source* t, const GSVector4i& r); virtual bool CanConvertDepth() { return false; } diff --git a/plugins/GSdx/GSTextureCache9.cpp b/plugins/GSdx/GSTextureCache9.cpp index 1820efc2ad..a94c154681 100644 --- a/plugins/GSdx/GSTextureCache9.cpp +++ b/plugins/GSdx/GSTextureCache9.cpp @@ -95,3 +95,27 @@ void GSTextureCache9::Read(Target* t, const GSVector4i& r) } } +void GSTextureCache9::Read(Source* t, const GSVector4i& r) +{ + // FIXME: copy was copyied from openGL. It is unlikely to work. + + const GIFRegTEX0& TEX0 = t->m_TEX0; + + if (GSTexture* offscreen = m_renderer->m_dev->CreateOffscreen(r.width(), r.height())) { + m_renderer->m_dev->CopyRect(t->m_texture, offscreen, r); + + GSTexture::GSMap m; + GSVector4i r_offscreen(0, 0, r.width(), r.height()); + + if (offscreen->Map(m, &r_offscreen)) { + GSOffset* off = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); + + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, off, r); + + offscreen->Unmap(); + } + + // FIXME invalidate data + m_renderer->m_dev->Recycle(offscreen); + } +} diff --git a/plugins/GSdx/GSTextureCache9.h b/plugins/GSdx/GSTextureCache9.h index 1fbf701860..43852cd9db 100644 --- a/plugins/GSdx/GSTextureCache9.h +++ b/plugins/GSdx/GSTextureCache9.h @@ -30,6 +30,7 @@ protected: int Get8bitFormat() {return D3DFMT_A8;} void Read(Target* t, const GSVector4i& r); + void Read(Source* t, const GSVector4i& r); virtual bool CanConvertDepth() { return false; } diff --git a/plugins/GSdx/GSTextureCacheOGL.cpp b/plugins/GSdx/GSTextureCacheOGL.cpp index ee89c6966d..975f99dd22 100644 --- a/plugins/GSdx/GSTextureCacheOGL.cpp +++ b/plugins/GSdx/GSTextureCacheOGL.cpp @@ -129,3 +129,28 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r) GL_POP(); } +void GSTextureCacheOGL::Read(Source* t, const GSVector4i& r) +{ + const GIFRegTEX0& TEX0 = t->m_TEX0; + + // FIXME Create a get function to avoid the useless copy + // Note: With openGL 4.5 you can use glGetTextureSubImage + + if (GSTexture* offscreen = m_renderer->m_dev->CreateOffscreen(r.width(), r.height())) { + m_renderer->m_dev->CopyRect(t->m_texture, offscreen, r); + + GSTexture::GSMap m; + GSVector4i r_offscreen(0, 0, r.width(), r.height()); + + if (offscreen->Map(m, &r_offscreen)) { + GSOffset* off = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); + + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, off, r); + + offscreen->Unmap(); + } + + // FIXME invalidate data + m_renderer->m_dev->Recycle(offscreen); + } +} diff --git a/plugins/GSdx/GSTextureCacheOGL.h b/plugins/GSdx/GSTextureCacheOGL.h index f3f1216ae0..0dca5716cc 100644 --- a/plugins/GSdx/GSTextureCacheOGL.h +++ b/plugins/GSdx/GSTextureCacheOGL.h @@ -31,6 +31,7 @@ protected: int Get8bitFormat() { return GL_R8;} void Read(Target* t, const GSVector4i& r); + void Read(Source* t, const GSVector4i& r); public: GSTextureCacheOGL(GSRenderer* r);