mirror of https://github.com/PCSX2/pcsx2.git
GS: Make CopyRect() take a destination offset
This commit is contained in:
parent
b042aeacf5
commit
b344ee094f
|
@ -717,7 +717,7 @@ public:
|
|||
/// Must be called to free resources after calling `DownloadTexture` or `DownloadTextureConvert`
|
||||
virtual void DownloadTextureComplete() {}
|
||||
|
||||
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) {}
|
||||
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) {}
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) {}
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha) {}
|
||||
|
||||
|
|
|
@ -515,7 +515,7 @@ bool GSDevice11::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTextu
|
|||
m_download_tex.reset(static_cast<GSTexture11*>(CreateOffscreen(rect.width(), rect.height(), src->GetFormat())));
|
||||
if (!m_download_tex)
|
||||
return false;
|
||||
CopyRect(src, m_download_tex.get(), rect);
|
||||
CopyRect(src, m_download_tex.get(), rect, 0, 0);
|
||||
return m_download_tex->Map(out_map);
|
||||
}
|
||||
|
||||
|
@ -528,22 +528,11 @@ void GSDevice11::DownloadTextureComplete()
|
|||
}
|
||||
}
|
||||
|
||||
void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
{
|
||||
if (!sTex || !dTex)
|
||||
{
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
CopyRect(sTex, r, dTex, 0, 0);
|
||||
}
|
||||
|
||||
void GSDevice11::CopyRect(GSTexture* sTex, const GSVector4i& sRect, GSTexture* dTex, u32 destX, u32 destY)
|
||||
void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
D3D11_BOX box = {(UINT)sRect.left, (UINT)sRect.top, 0U, (UINT)sRect.right, (UINT)sRect.bottom, 1U};
|
||||
D3D11_BOX box = {(UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U};
|
||||
|
||||
// DX api isn't happy if we pass a box for depth copy
|
||||
// It complains that depth/multisample must be a full copy
|
||||
|
@ -565,12 +554,12 @@ void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i
|
|||
{
|
||||
// DX11 requires that you copy the entire depth buffer.
|
||||
*dest = CreateDepthStencil(w, h, src->GetFormat(), false);
|
||||
CopyRect(src, GSVector4i(0, 0, w, h), *dest, 0, 0);
|
||||
CopyRect(src, *dest, GSVector4i(0, 0, w, h), 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest = CreateRenderTarget(w, h, src->GetFormat(), false);
|
||||
CopyRect(src, rect, *dest, rect.left, rect.top);
|
||||
CopyRect(src, *dest, rect, rect.left, rect.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -251,8 +251,7 @@ public:
|
|||
|
||||
void CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect);
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r);
|
||||
void CopyRect(GSTexture* sTex, const GSVector4i& sRect, GSTexture* dTex, u32 destX, u32 destY);
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) final;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
|
||||
|
|
|
@ -401,19 +401,7 @@ void GSDevice12::DownloadTextureComplete()
|
|||
UnmapStagingBuffer();
|
||||
}
|
||||
|
||||
void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
{
|
||||
if (!sTex || !dTex)
|
||||
{
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const GSVector4i dst_rc(r - r.xyxy());
|
||||
DoCopyRect(sTex, dTex, r, dst_rc);
|
||||
}
|
||||
|
||||
void GSDevice12::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, const GSVector4i& dst_rc)
|
||||
void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
|
@ -426,7 +414,7 @@ void GSDevice12::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
// source is cleared. if destination is a render target, we can carry the clear forward
|
||||
if (dTexVK->IsRenderTargetOrDepthStencil())
|
||||
{
|
||||
if (dtex_rc.eq(dst_rc))
|
||||
if (dtex_rc.eq(r))
|
||||
{
|
||||
// pass it forward if we're clearing the whole thing
|
||||
if (sTexVK->IsDepthStencil())
|
||||
|
@ -464,7 +452,7 @@ void GSDevice12::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
|
||||
// if the destination has been cleared, and we're not overwriting the whole thing, commit the clear first
|
||||
// (the area outside of where we're copying to)
|
||||
if (dTexVK->GetState() == GSTexture::State::Cleared && !dtex_rc.eq(dst_rc))
|
||||
if (dTexVK->GetState() == GSTexture::State::Cleared && !dtex_rc.eq(r))
|
||||
dTexVK->CommitClear();
|
||||
|
||||
EndRenderPass();
|
||||
|
@ -485,7 +473,7 @@ void GSDevice12::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
const D3D12_BOX srcbox{static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0u,
|
||||
static_cast<UINT>(r.right), static_cast<UINT>(r.bottom), 1u};
|
||||
g_d3d12_context->GetCommandList()->CopyTextureRegion(
|
||||
&dstloc, dst_rc.left, dst_rc.top, 0,
|
||||
&dstloc, destX, destY, 0,
|
||||
&srcloc, &srcbox);
|
||||
|
||||
dTexVK->SetState(GSTexture::State::Dirty);
|
||||
|
@ -2514,7 +2502,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
draw_rt_clone->SetState(GSTexture::State::Invalidated);
|
||||
DoCopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea);
|
||||
CopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(2, draw_rt_clone, true);
|
||||
}
|
||||
}
|
||||
|
@ -2532,7 +2520,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
copy_ds->SetState(GSTexture::State::Invalidated);
|
||||
DoCopyRect(config.ds, copy_ds, config.drawarea, config.drawarea);
|
||||
CopyRect(config.ds, copy_ds, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(0, copy_ds, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,8 +248,7 @@ public:
|
|||
GSTexture* DrawForReadback(GSTexture* src, const GSVector4& sRect, int w, int h, int format = 0, int ps_shader = 0);
|
||||
bool ReadbackTexture(GSTexture* src, const GSVector4i& rect, u32 level, GSTexture::GSMap* dst);
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) override;
|
||||
void DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, const GSVector4i& dst_rc);
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
|
|
|
@ -1571,7 +1571,7 @@ void GSRendererHW::Draw()
|
|||
g_gs_device->CreateSparseRenderTarget(new_w, new_h, tex->GetFormat()) :
|
||||
g_gs_device->CreateSparseDepthStencil(new_w, new_h, tex->GetFormat());
|
||||
const GSVector4i r{ 0, 0, w, h };
|
||||
g_gs_device->CopyRect(tex, t->m_texture, r);
|
||||
g_gs_device->CopyRect(tex, t->m_texture, r, 0, 0);
|
||||
g_gs_device->Recycle(tex);
|
||||
t->m_texture->SetScale(up_s);
|
||||
(is_rt ? rt_tex : ds_tex) = t->m_texture;
|
||||
|
@ -2017,11 +2017,11 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc
|
|||
const GSVector4i r_full(0, 0, tw, th);
|
||||
if (GSTexture* rt = g_gs_device->CreateRenderTarget(tw, th, GSTexture::Format::Color))
|
||||
{
|
||||
g_gs_device->CopyRect(tex->m_texture, rt, r_full);
|
||||
g_gs_device->CopyRect(tex->m_texture, rt, r_full, 0, 0);
|
||||
|
||||
g_gs_device->StretchRect(tex->m_texture, sRect, rt, dRect);
|
||||
|
||||
g_gs_device->CopyRect(rt, tex->m_texture, r_full);
|
||||
g_gs_device->CopyRect(rt, tex->m_texture, r_full, 0, 0);
|
||||
|
||||
g_gs_device->Recycle(rt);
|
||||
}
|
||||
|
|
|
@ -1188,7 +1188,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
GSTexture* dTex = g_gs_device->CreateTexture(w, h, false, GSTexture::Format::Color, true);
|
||||
|
||||
GSVector4i area(x, y, x + w, y + h);
|
||||
g_gs_device->CopyRect(sTex, dTex, area);
|
||||
g_gs_device->CopyRect(sTex, dTex, area, 0, 0);
|
||||
|
||||
// Keep a trace of origin of the texture
|
||||
src->m_texture = dTex;
|
||||
|
@ -1380,7 +1380,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
if (use_texture)
|
||||
{
|
||||
g_gs_device->CopyRect(sTex, dTex, sRect);
|
||||
g_gs_device->CopyRect(sTex, dTex, sRect, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -349,7 +349,7 @@ public:
|
|||
|
||||
bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) override;
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) override;
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, id<MTLRenderPipelineState> pipeline, bool linear, LoadAction load_action, void* frag_uniform, size_t frag_uniform_len);
|
||||
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
|
||||
/// Copy from a position in sTex to the same position in the currently active render encoder using the given fs pipeline and rect
|
||||
|
|
|
@ -941,7 +941,7 @@ bool GSDeviceMTL::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSText
|
|||
return true;
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
void GSDeviceMTL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{ @autoreleasepool {
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
|
@ -971,7 +971,7 @@ void GSDeviceMTL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
|||
toTexture:dT->GetTexture()
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:MTLOriginMake(0, 0, 0)];
|
||||
destinationOrigin:MTLOriginMake((int)destX, (int)destY, 0)];
|
||||
[encoder endEncoding];
|
||||
}}
|
||||
|
||||
|
|
|
@ -1145,7 +1145,7 @@ void GSDeviceOGL::BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2
|
|||
}
|
||||
|
||||
// Copy a sub part of a texture into another
|
||||
void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{
|
||||
ASSERT(sTex && dTex);
|
||||
if (!(sTex && dTex))
|
||||
|
@ -1167,7 +1167,7 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
|||
glCopyImageSubData(sid, GL_TEXTURE_2D,
|
||||
0, r.x, r.y, 0,
|
||||
did, GL_TEXTURE_2D,
|
||||
0, 0, 0, 0,
|
||||
0, destX, destY, 0,
|
||||
r.width(), r.height(), 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ public:
|
|||
|
||||
bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) final;
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) final;
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) final;
|
||||
|
||||
void PushDebugGroup(const char* fmt, ...) final;
|
||||
void PopDebugGroup() final;
|
||||
|
|
|
@ -489,19 +489,7 @@ bool GSDeviceVK::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTextu
|
|||
|
||||
void GSDeviceVK::DownloadTextureComplete() {}
|
||||
|
||||
void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
{
|
||||
if (!sTex || !dTex)
|
||||
{
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const GSVector4i dst_rc(r - r.xyxy());
|
||||
DoCopyRect(sTex, dTex, r, dst_rc);
|
||||
}
|
||||
|
||||
void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, const GSVector4i& dst_rc)
|
||||
void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY)
|
||||
{
|
||||
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
||||
|
||||
|
@ -514,7 +502,7 @@ void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
// source is cleared. if destination is a render target, we can carry the clear forward
|
||||
if (dTexVK->IsRenderTargetOrDepthStencil())
|
||||
{
|
||||
if (dtex_rc.eq(dst_rc))
|
||||
if (dtex_rc.eq(r))
|
||||
{
|
||||
// pass it forward if we're clearing the whole thing
|
||||
if (sTexVK->IsDepthStencil())
|
||||
|
@ -529,7 +517,7 @@ void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
// otherwise we need to do an attachment clear
|
||||
const bool depth = (dTexVK->GetType() == GSTexture::Type::DepthStencil);
|
||||
OMSetRenderTargets(depth ? nullptr : dTexVK, depth ? dTexVK : nullptr, dtex_rc, false);
|
||||
BeginRenderPassForStretchRect(dTexVK, dtex_rc, dst_rc);
|
||||
BeginRenderPassForStretchRect(dTexVK, dtex_rc, GSVector4i(destX, destY, destX + r.width(), destY + r.height()));
|
||||
|
||||
// so use an attachment clear
|
||||
VkClearAttachment ca;
|
||||
|
@ -539,7 +527,7 @@ void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
ca.clearValue.depthStencil.stencil = 0;
|
||||
ca.colorAttachment = 0;
|
||||
|
||||
const VkClearRect cr = { {{0, 0}, {static_cast<u32>(dst_rc.width()), static_cast<u32>(dst_rc.height())}}, 0u, 1u };
|
||||
const VkClearRect cr = { {{0, 0}, {static_cast<u32>(r.width()), static_cast<u32>(r.height())}}, 0u, 1u };
|
||||
vkCmdClearAttachments(g_vulkan_context->GetCurrentCommandBuffer(), 1, &ca, 1, &cr);
|
||||
return;
|
||||
}
|
||||
|
@ -551,13 +539,14 @@ void GSDeviceVK::DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i&
|
|||
|
||||
// if the destination has been cleared, and we're not overwriting the whole thing, commit the clear first
|
||||
// (the area outside of where we're copying to)
|
||||
if (dTexVK->GetState() == GSTexture::State::Cleared && !dtex_rc.eq(dst_rc))
|
||||
if (dTexVK->GetState() == GSTexture::State::Cleared && !dtex_rc.eq(r))
|
||||
dTexVK->CommitClear();
|
||||
|
||||
// *now* we can do a normal image copy.
|
||||
const VkImageAspectFlags src_aspect = (sTexVK->IsDepthStencil()) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
const VkImageAspectFlags dst_aspect = (dTexVK->IsDepthStencil()) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
const VkImageCopy ic = {{src_aspect, 0u, 0u, 1u}, {r.left, r.top, 0u}, {dst_aspect, 0u, 0u, 1u}, {dst_rc.left, dst_rc.top, 0u},
|
||||
const VkImageCopy ic = {{src_aspect, 0u, 0u, 1u}, {r.left, r.top, 0u}, {dst_aspect, 0u, 0u, 1u},
|
||||
{static_cast<s32>(destX), static_cast<s32>(destY), 0u},
|
||||
{static_cast<u32>(r.width()), static_cast<u32>(r.height()), 1u}};
|
||||
|
||||
EndRenderPass();
|
||||
|
@ -2925,7 +2914,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
DoCopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea);
|
||||
CopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(2, draw_rt_clone, true);
|
||||
}
|
||||
}
|
||||
|
@ -2942,7 +2931,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
DoCopyRect(config.ds, copy_ds, config.drawarea, config.drawarea);
|
||||
CopyRect(config.ds, copy_ds, config.drawarea, config.drawarea.left, config.drawarea.top);
|
||||
PSSetShaderResource(0, copy_ds, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,8 +223,7 @@ public:
|
|||
bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) override;
|
||||
void DownloadTextureComplete() override;
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) override;
|
||||
void DoCopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, const GSVector4i& dst_rc);
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
|
|
Loading…
Reference in New Issue