mirror of https://github.com/PCSX2/pcsx2.git
GS/Vulkan: Don't ever fully clear stencil on DATE draws
We manually clear the drawn region when it's needed, in all other cases it's pre-filled with the setup. Therefore, the two load actions should be preserve and don't care.
This commit is contained in:
parent
0ae3cbf4d6
commit
875fdc40a5
|
@ -3826,7 +3826,7 @@ bool GSDeviceVK::CreateRenderPasses()
|
|||
{
|
||||
for (u32 hdr = 0; hdr < 2; hdr++)
|
||||
{
|
||||
for (u32 date = DATE_RENDER_PASS_NONE; date <= DATE_RENDER_PASS_STENCIL_ONE; date++)
|
||||
for (u32 stencil = 0; stencil < 2; stencil++)
|
||||
{
|
||||
for (u32 fbl = 0; fbl < 2; fbl++)
|
||||
{
|
||||
|
@ -3840,12 +3840,10 @@ bool GSDeviceVK::CreateRenderPasses()
|
|||
const VkFormat rp_rt_format =
|
||||
(rt != 0) ? ((hdr != 0) ? hdr_rt_format : rt_format) : VK_FORMAT_UNDEFINED;
|
||||
const VkFormat rp_depth_format = (ds != 0) ? depth_format : VK_FORMAT_UNDEFINED;
|
||||
const VkAttachmentLoadOp opc =
|
||||
((date == DATE_RENDER_PASS_NONE || !m_features.stencil_buffer) ?
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
|
||||
(date == DATE_RENDER_PASS_STENCIL_ONE ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD));
|
||||
GET(m_tfx_render_pass[rt][ds][hdr][date][fbl][dsp][opa][opb], rp_rt_format,
|
||||
const VkAttachmentLoadOp opc = (!stencil || !m_features.stencil_buffer) ?
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
GET(m_tfx_render_pass[rt][ds][hdr][stencil][fbl][dsp][opa][opb], rp_rt_format,
|
||||
rp_depth_format, (fbl != 0), (dsp != 0), static_cast<VkAttachmentLoadOp>(opa),
|
||||
static_cast<VkAttachmentLoadOp>(opb), static_cast<VkAttachmentLoadOp>(opc));
|
||||
}
|
||||
|
@ -4004,7 +4002,7 @@ bool GSDeviceVK::CompileConvertPipelines()
|
|||
{
|
||||
pxAssert(!arr[ds][fbl]);
|
||||
|
||||
gpb.SetRenderPass(GetTFXRenderPass(true, ds != 0, is_setup, DATE_RENDER_PASS_NONE, fbl != 0, false,
|
||||
gpb.SetRenderPass(GetTFXRenderPass(true, ds != 0, is_setup, false, fbl != 0, false,
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE),
|
||||
0);
|
||||
arr[ds][fbl] = gpb.Create(m_device, g_vulkan_shader_cache->GetPipelineCache(true), false);
|
||||
|
@ -4805,7 +4803,7 @@ VkPipeline GSDeviceVK::CreateTFXPipeline(const PipelineSelector& p)
|
|||
else
|
||||
{
|
||||
gpb.SetRenderPass(
|
||||
GetTFXRenderPass(p.rt, p.ds, p.ps.hdr, p.dss.date ? DATE_RENDER_PASS_STENCIL : DATE_RENDER_PASS_NONE,
|
||||
GetTFXRenderPass(p.rt, p.ds, p.ps.hdr, p.dss.date,
|
||||
p.IsRTFeedbackLoop(), p.IsTestingAndSamplingDepth(),
|
||||
p.rt ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
p.ds ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE),
|
||||
|
@ -5557,7 +5555,6 @@ GSTextureVK* GSDeviceVK::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config)
|
|||
void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
// Destination Alpha Setup
|
||||
DATE_RENDER_PASS DATE_rp = DATE_RENDER_PASS_NONE;
|
||||
switch (config.destination_alpha)
|
||||
{
|
||||
case GSHWDrawConfig::DestinationAlphaMode::Off: // No setup
|
||||
|
@ -5570,18 +5567,13 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
if (!m_features.texture_barrier)
|
||||
{
|
||||
SetupDATE(config.rt, config.ds, config.datm, config.drawarea);
|
||||
DATE_rp = DATE_RENDER_PASS_STENCIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DATE_rp = DATE_RENDER_PASS_STENCIL_ONE;
|
||||
config.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Stencil;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSHWDrawConfig::DestinationAlphaMode::Stencil:
|
||||
SetupDATE(config.rt, config.ds, config.datm, config.drawarea);
|
||||
DATE_rp = DATE_RENDER_PASS_STENCIL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5731,22 +5723,21 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
{
|
||||
const VkAttachmentLoadOp rt_op = GetLoadOpForTexture(draw_rt);
|
||||
const VkAttachmentLoadOp ds_op = GetLoadOpForTexture(draw_ds);
|
||||
const VkRenderPass rp = GetTFXRenderPass(pipe.rt, pipe.ds, pipe.ps.hdr, DATE_rp, pipe.IsRTFeedbackLoop(),
|
||||
const VkRenderPass rp = GetTFXRenderPass(pipe.rt, pipe.ds, pipe.ps.hdr,
|
||||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil, pipe.IsRTFeedbackLoop(),
|
||||
pipe.IsTestingAndSamplingDepth(), rt_op, ds_op);
|
||||
const bool is_clearing_rt = (rt_op == VK_ATTACHMENT_LOAD_OP_CLEAR || ds_op == VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||
const GSVector4i render_area = GSVector4i::loadh(rtsize);
|
||||
|
||||
if (is_clearing_rt || DATE_rp == DATE_RENDER_PASS_STENCIL_ONE)
|
||||
if (is_clearing_rt)
|
||||
{
|
||||
// when we're clearing, we set the draw area to the whole fb, otherwise part of it will be undefined
|
||||
alignas(16) VkClearValue cvs[2];
|
||||
u32 cv_count = 0;
|
||||
if (draw_rt)
|
||||
GSVector4::store<true>(&cvs[cv_count++].color, draw_rt->GetUNormClearColor());
|
||||
|
||||
// the only time the stencil value is used here is DATE_one, so setting it to 1 is fine (not used otherwise)
|
||||
if (draw_ds)
|
||||
cvs[cv_count++].depthStencil = {draw_ds->GetClearDepth(), 1};
|
||||
cvs[cv_count++].depthStencil = {draw_ds->GetClearDepth(), 0};
|
||||
|
||||
BeginClearRenderPass(rp, render_area, cvs, cv_count);
|
||||
}
|
||||
|
@ -5755,7 +5746,8 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
BeginRenderPass(rp, render_area);
|
||||
}
|
||||
}
|
||||
else if (DATE_rp == DATE_RENDER_PASS_STENCIL_ONE)
|
||||
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
|
||||
{
|
||||
const VkClearAttachment ca = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, {.depthStencil = {0.0f, 1u}}};
|
||||
const VkClearRect rc = {{{config.drawarea.left, config.drawarea.top},
|
||||
|
@ -5846,7 +5838,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
if (draw_ds)
|
||||
cvs[cv_count++].depthStencil = {draw_ds->GetClearDepth(), 1};
|
||||
|
||||
BeginClearRenderPass(GetTFXRenderPass(true, pipe.ds, false, DATE_RENDER_PASS_NONE, pipe.IsRTFeedbackLoop(),
|
||||
BeginClearRenderPass(GetTFXRenderPass(true, pipe.ds, false, false, pipe.IsRTFeedbackLoop(),
|
||||
pipe.IsTestingAndSamplingDepth(), VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
pipe.ds ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE),
|
||||
draw_rt->GetRect(), cvs, cv_count);
|
||||
|
@ -5854,7 +5846,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
else
|
||||
{
|
||||
BeginRenderPass(GetTFXRenderPass(true, pipe.ds, false, DATE_RENDER_PASS_NONE, pipe.IsRTFeedbackLoop(),
|
||||
BeginRenderPass(GetTFXRenderPass(true, pipe.ds, false, false, pipe.IsRTFeedbackLoop(),
|
||||
pipe.IsTestingAndSamplingDepth(), VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
pipe.ds ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE),
|
||||
draw_rt->GetRect());
|
||||
|
|
|
@ -390,12 +390,6 @@ public:
|
|||
|
||||
NUM_TFX_TEXTURES
|
||||
};
|
||||
enum DATE_RENDER_PASS : u32
|
||||
{
|
||||
DATE_RENDER_PASS_NONE = 0,
|
||||
DATE_RENDER_PASS_STENCIL = 1,
|
||||
DATE_RENDER_PASS_STENCIL_ONE = 2,
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<VKSwapChain> m_swap_chain;
|
||||
|
@ -514,10 +508,10 @@ public:
|
|||
/// Returns true if Vulkan is suitable as a default for the devices in the system.
|
||||
static bool IsSuitableDefaultRenderer();
|
||||
|
||||
__fi VkRenderPass GetTFXRenderPass(bool rt, bool ds, bool hdr, DATE_RENDER_PASS date, bool fbl, bool dsp,
|
||||
__fi VkRenderPass GetTFXRenderPass(bool rt, bool ds, bool hdr, bool stencil, bool fbl, bool dsp,
|
||||
VkAttachmentLoadOp rt_op, VkAttachmentLoadOp ds_op) const
|
||||
{
|
||||
return m_tfx_render_pass[rt][ds][hdr][date][fbl][dsp][rt_op][ds_op];
|
||||
return m_tfx_render_pass[rt][ds][hdr][stencil][fbl][dsp][rt_op][ds_op];
|
||||
}
|
||||
__fi VkSampler GetPointSampler() const { return m_point_sampler; }
|
||||
__fi VkSampler GetLinearSampler() const { return m_linear_sampler; }
|
||||
|
|
Loading…
Reference in New Issue