mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-11 21:23:14 +00:00
renderer_vulkan: Handle depth-stencil copies through depth render overrides. (#2134)
This commit is contained in:
parent
d94abffd9a
commit
5040be1640
8 changed files with 146 additions and 13 deletions
|
@ -70,6 +70,26 @@ bool Rasterizer::FilterDraw() {
|
|||
return false;
|
||||
}
|
||||
|
||||
const bool cb_disabled =
|
||||
regs.color_control.mode == AmdGpu::Liverpool::ColorControl::OperationMode::Disable;
|
||||
const auto depth_copy =
|
||||
regs.depth_render_override.force_z_dirty && regs.depth_render_override.force_z_valid &&
|
||||
regs.depth_buffer.DepthValid() && regs.depth_buffer.DepthWriteValid() &&
|
||||
regs.depth_buffer.DepthAddress() != regs.depth_buffer.DepthWriteAddress();
|
||||
const auto stencil_copy =
|
||||
regs.depth_render_override.force_stencil_dirty &&
|
||||
regs.depth_render_override.force_stencil_valid && regs.depth_buffer.StencilValid() &&
|
||||
regs.depth_buffer.StencilWriteValid() &&
|
||||
regs.depth_buffer.StencilAddress() != regs.depth_buffer.StencilWriteAddress();
|
||||
if (cb_disabled && (depth_copy || stencil_copy)) {
|
||||
// Games may disable color buffer and enable force depth/stencil dirty and valid to
|
||||
// do a copy from one depth-stencil surface to another, without a pixel shader.
|
||||
// We need to detect this case and perform the copy, otherwise it will have no effect.
|
||||
LOG_TRACE(Render_Vulkan, "Performing depth-stencil override copy");
|
||||
DepthStencilCopy(depth_copy, stencil_copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -899,6 +919,59 @@ void Rasterizer::Resolve() {
|
|||
}
|
||||
}
|
||||
|
||||
void Rasterizer::DepthStencilCopy(bool is_depth, bool is_stencil) {
|
||||
auto& regs = liverpool->regs;
|
||||
|
||||
auto read_desc = VideoCore::TextureCache::DepthTargetDesc(
|
||||
regs.depth_buffer, regs.depth_view, regs.depth_control,
|
||||
regs.depth_htile_data_base.GetAddress(), liverpool->last_db_extent, false);
|
||||
auto write_desc = VideoCore::TextureCache::DepthTargetDesc(
|
||||
regs.depth_buffer, regs.depth_view, regs.depth_control,
|
||||
regs.depth_htile_data_base.GetAddress(), liverpool->last_db_extent, true);
|
||||
|
||||
auto& read_image = texture_cache.GetImage(texture_cache.FindImage(read_desc));
|
||||
auto& write_image = texture_cache.GetImage(texture_cache.FindImage(write_desc));
|
||||
|
||||
VideoCore::SubresourceRange sub_range;
|
||||
sub_range.base.layer = liverpool->regs.depth_view.slice_start;
|
||||
sub_range.extent.layers = liverpool->regs.depth_view.NumSlices() - sub_range.base.layer;
|
||||
|
||||
read_image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead,
|
||||
sub_range);
|
||||
write_image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite,
|
||||
sub_range);
|
||||
|
||||
auto aspect_mask = vk::ImageAspectFlags(0);
|
||||
if (is_depth) {
|
||||
aspect_mask |= vk::ImageAspectFlagBits::eDepth;
|
||||
}
|
||||
if (is_stencil) {
|
||||
aspect_mask |= vk::ImageAspectFlagBits::eStencil;
|
||||
}
|
||||
vk::ImageCopy region = {
|
||||
.srcSubresource =
|
||||
{
|
||||
.aspectMask = aspect_mask,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = sub_range.base.layer,
|
||||
.layerCount = sub_range.extent.layers,
|
||||
},
|
||||
.srcOffset = {0, 0, 0},
|
||||
.dstSubresource =
|
||||
{
|
||||
.aspectMask = aspect_mask,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = sub_range.base.layer,
|
||||
.layerCount = sub_range.extent.layers,
|
||||
},
|
||||
.dstOffset = {0, 0, 0},
|
||||
.extent = {write_image.info.size.width, write_image.info.size.height, 1},
|
||||
};
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.copyImage(read_image.image, vk::ImageLayout::eTransferSrcOptimal, write_image.image,
|
||||
vk::ImageLayout::eTransferDstOptimal, region);
|
||||
}
|
||||
|
||||
void Rasterizer::InlineData(VAddr address, const void* value, u32 num_bytes, bool is_gds) {
|
||||
buffer_cache.InlineData(address, value, num_bytes, is_gds);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
RenderState PrepareRenderState(u32 mrt_mask);
|
||||
void BeginRendering(const GraphicsPipeline& pipeline, RenderState& state);
|
||||
void Resolve();
|
||||
void DepthStencilCopy(bool is_depth, bool is_stencil);
|
||||
void EliminateFastClear();
|
||||
|
||||
void UpdateDynamicState(const GraphicsPipeline& pipeline);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue