GS-HW: Fix stretch rects errantly discarding data

This commit is contained in:
refractionpcsx2 2023-04-05 10:22:33 +01:00
parent a863466f70
commit 2a6ba739bc
4 changed files with 21 additions and 18 deletions

View File

@ -434,7 +434,7 @@ void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top)); int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect, DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get(), linear); dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get(), linear, true);
} }
void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
@ -443,8 +443,9 @@ void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha); GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0); const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
DoStretchRect( const bool allow_discard = (index == 0xf);
static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect, m_color_copy[index].get(), false); DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
m_color_copy[index].get(), false, allow_discard);
} }
void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
@ -458,7 +459,7 @@ void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
SetUtilityPushConstants(&cb, sizeof(cb)); SetUtilityPushConstants(&cb, sizeof(cb));
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect, DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
m_present[static_cast<int>(shader)].get(), linear); m_present[static_cast<int>(shader)].get(), linear, true);
} }
void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
@ -478,7 +479,7 @@ void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
const GSVector4 dRect(0, 0, dSize, 1); const GSVector4 dRect(0, 0, dSize, 1);
const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8; const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8;
DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect, DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect,
m_convert[static_cast<int>(shader)].get(), false); m_convert[static_cast<int>(shader)].get(), false, true);
} }
void GSDevice12::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) void GSDevice12::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
@ -498,7 +499,7 @@ void GSDevice12::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight()); const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I; const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect, DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect,
m_convert[static_cast<int>(shader)].get(), false); m_convert[static_cast<int>(shader)].get(), false, true);
} }
void GSDevice12::DrawMultiStretchRects( void GSDevice12::DrawMultiStretchRects(
@ -644,7 +645,8 @@ void GSDevice12::BeginRenderPassForStretchRect(
} }
} }
void GSDevice12::DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSTexture12* dTex, const GSVector4& dRect, const ID3D12PipelineState* pipeline, bool linear) void GSDevice12::DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSTexture12* dTex, const GSVector4& dRect,
const ID3D12PipelineState* pipeline, bool linear, bool allow_discard)
{ {
if (sTex->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) if (sTex->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
{ {
@ -677,7 +679,7 @@ void GSDevice12::DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSText
const bool drawing_to_current_rt = (is_present || InRenderPass()); const bool drawing_to_current_rt = (is_present || InRenderPass());
if (!drawing_to_current_rt) if (!drawing_to_current_rt)
BeginRenderPassForStretchRect(dTex, dtex_rc, dst_rc); BeginRenderPassForStretchRect(dTex, dtex_rc, dst_rc, allow_discard);
DrawStretchRect(sRect, dRect, size); DrawStretchRect(sRect, dRect, size);
} }

View File

@ -262,7 +262,7 @@ public:
void BeginRenderPassForStretchRect( void BeginRenderPassForStretchRect(
GSTexture12* dTex, const GSVector4i& dtex_rc, const GSVector4i& dst_rc, bool allow_discard = true); GSTexture12* dTex, const GSVector4i& dtex_rc, const GSVector4i& dst_rc, bool allow_discard = true);
void DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSTexture12* dTex, const GSVector4& dRect, void DoStretchRect(GSTexture12* sTex, const GSVector4& sRect, GSTexture12* dTex, const GSVector4& dRect,
const ID3D12PipelineState* pipeline, bool linear); const ID3D12PipelineState* pipeline, bool linear, bool allow_discard);
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds); void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
void SetupDATE(GSTexture* rt, GSTexture* ds, bool datm, const GSVector4i& bbox); void SetupDATE(GSTexture* rt, GSTexture* ds, bool datm, const GSVector4i& bbox);

View File

@ -532,7 +532,7 @@ void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top)); int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect,
dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)], linear); dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)], linear, true);
} }
void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
@ -541,8 +541,9 @@ void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha); GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0); const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
DoStretchRect( const bool allow_discard = (index == 0xf);
static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, m_color_copy[index], false); DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, m_color_copy[index],
false, allow_discard);
} }
void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
@ -555,7 +556,7 @@ void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
SetUtilityPushConstants(&cb, sizeof(cb)); SetUtilityPushConstants(&cb, sizeof(cb));
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect,
m_present[static_cast<int>(shader)], linear); m_present[static_cast<int>(shader)], linear, true);
} }
void GSDeviceVK::DrawMultiStretchRects( void GSDeviceVK::DrawMultiStretchRects(
@ -712,7 +713,7 @@ void GSDeviceVK::BeginRenderPassForStretchRect(
} }
void GSDeviceVK::DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSTextureVK* dTex, const GSVector4& dRect, void GSDeviceVK::DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSTextureVK* dTex, const GSVector4& dRect,
VkPipeline pipeline, bool linear) VkPipeline pipeline, bool linear, bool allow_discard)
{ {
if (sTex->GetLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) if (sTex->GetLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{ {
@ -745,7 +746,7 @@ void GSDeviceVK::DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSText
} }
if (!is_present && !InRenderPass()) if (!is_present && !InRenderPass())
BeginRenderPassForStretchRect(dTex, dtex_rc, dst_rc); BeginRenderPassForStretchRect(dTex, dtex_rc, dst_rc, allow_discard);
DrawStretchRect(sRect, dRect, size); DrawStretchRect(sRect, dRect, size);
} }
@ -813,7 +814,7 @@ void GSDeviceVK::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
const GSVector4 dRect(0, 0, dSize, 1); const GSVector4 dRect(0, 0, dSize, 1);
const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8; const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8;
DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect, DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect,
m_convert[static_cast<int>(shader)], false); m_convert[static_cast<int>(shader)], false, true);
} }
void GSDeviceVK::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) void GSDeviceVK::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
@ -833,7 +834,7 @@ void GSDeviceVK::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I; const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight()); const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect, DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect,
m_convert[static_cast<int>(shader)], false); m_convert[static_cast<int>(shader)], false, true);
} }
void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect,

View File

@ -248,7 +248,7 @@ public:
void BeginRenderPassForStretchRect( void BeginRenderPassForStretchRect(
GSTextureVK* dTex, const GSVector4i& dtex_rc, const GSVector4i& dst_rc, bool allow_discard = true); GSTextureVK* dTex, const GSVector4i& dtex_rc, const GSVector4i& dst_rc, bool allow_discard = true);
void DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSTextureVK* dTex, const GSVector4& dRect, void DoStretchRect(GSTextureVK* sTex, const GSVector4& sRect, GSTextureVK* dTex, const GSVector4& dRect,
VkPipeline pipeline, bool linear); VkPipeline pipeline, bool linear, bool allow_discard);
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds); void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
void BlitRect(GSTexture* sTex, const GSVector4i& sRect, u32 sLevel, GSTexture* dTex, const GSVector4i& dRect, void BlitRect(GSTexture* sTex, const GSVector4i& sRect, u32 sLevel, GSTexture* dTex, const GSVector4i& dRect,