gsdx tc: implement a read function of Source texture

It will be used in the following commit
This commit is contained in:
Gregory Hainaut 2016-03-19 11:28:15 +01:00
parent d922225e69
commit 2ca624c8c6
7 changed files with 77 additions and 5 deletions

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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; }

View File

@ -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);
}
}

View File

@ -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; }

View File

@ -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);
}
}

View File

@ -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);