mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	Merge pull request #4111 from ReinUsesLisp/preserve-contents-vk
vk_rasterizer: Don't preserve contents on full screen clears
This commit is contained in:
		@@ -143,6 +143,49 @@ Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @brief Determine if an attachment to be updated has to preserve contents
 | 
			
		||||
/// @param is_clear True when a clear is being executed
 | 
			
		||||
/// @param regs 3D registers
 | 
			
		||||
/// @return True when the contents have to be preserved
 | 
			
		||||
bool HasToPreserveColorContents(bool is_clear, const Maxwell& regs) {
 | 
			
		||||
    if (!is_clear) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    // First we have to make sure all clear masks are enabled.
 | 
			
		||||
    if (!regs.clear_buffers.R || !regs.clear_buffers.G || !regs.clear_buffers.B ||
 | 
			
		||||
        !regs.clear_buffers.A) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    // If scissors are disabled, the whole screen is cleared
 | 
			
		||||
    if (!regs.clear_flags.scissor) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // Then we have to confirm scissor testing clears the whole image
 | 
			
		||||
    const std::size_t index = regs.clear_buffers.RT;
 | 
			
		||||
    const auto& scissor = regs.scissor_test[0];
 | 
			
		||||
    return scissor.min_x > 0 || scissor.min_y > 0 || scissor.max_x < regs.rt[index].width ||
 | 
			
		||||
           scissor.max_y < regs.rt[index].height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @brief Determine if an attachment to be updated has to preserve contents
 | 
			
		||||
/// @param is_clear True when a clear is being executed
 | 
			
		||||
/// @param regs 3D registers
 | 
			
		||||
/// @return True when the contents have to be preserved
 | 
			
		||||
bool HasToPreserveDepthContents(bool is_clear, const Maxwell& regs) {
 | 
			
		||||
    // If we are not clearing, the contents have to be preserved
 | 
			
		||||
    if (!is_clear) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    // For depth stencil clears we only have to confirm scissor test covers the whole image
 | 
			
		||||
    if (!regs.clear_flags.scissor) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // Make sure the clear cover the whole image
 | 
			
		||||
    const auto& scissor = regs.scissor_test[0];
 | 
			
		||||
    return scissor.min_x > 0 || scissor.min_y > 0 || scissor.max_x < regs.zeta_width ||
 | 
			
		||||
           scissor.max_y < regs.zeta_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
class BufferBindings final {
 | 
			
		||||
@@ -344,7 +387,7 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
 | 
			
		||||
 | 
			
		||||
    buffer_cache.Unmap();
 | 
			
		||||
 | 
			
		||||
    const Texceptions texceptions = UpdateAttachments();
 | 
			
		||||
    const Texceptions texceptions = UpdateAttachments(false);
 | 
			
		||||
    SetupImageTransitions(texceptions, color_attachments, zeta_attachment);
 | 
			
		||||
 | 
			
		||||
    key.renderpass_params = GetRenderPassParams(texceptions);
 | 
			
		||||
@@ -400,7 +443,7 @@ void RasterizerVulkan::Clear() {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [[maybe_unused]] const auto texceptions = UpdateAttachments();
 | 
			
		||||
    [[maybe_unused]] const auto texceptions = UpdateAttachments(true);
 | 
			
		||||
    DEBUG_ASSERT(texceptions.none());
 | 
			
		||||
    SetupImageTransitions(0, color_attachments, zeta_attachment);
 | 
			
		||||
 | 
			
		||||
@@ -677,9 +720,12 @@ void RasterizerVulkan::FlushWork() {
 | 
			
		||||
    draw_counter = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
 | 
			
		||||
RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) {
 | 
			
		||||
    MICROPROFILE_SCOPE(Vulkan_RenderTargets);
 | 
			
		||||
    auto& dirty = system.GPU().Maxwell3D().dirty.flags;
 | 
			
		||||
    auto& maxwell3d = system.GPU().Maxwell3D();
 | 
			
		||||
    auto& dirty = maxwell3d.dirty.flags;
 | 
			
		||||
    auto& regs = maxwell3d.regs;
 | 
			
		||||
 | 
			
		||||
    const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets];
 | 
			
		||||
    dirty[VideoCommon::Dirty::RenderTargets] = false;
 | 
			
		||||
 | 
			
		||||
@@ -688,7 +734,8 @@ RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
 | 
			
		||||
    Texceptions texceptions;
 | 
			
		||||
    for (std::size_t rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
 | 
			
		||||
        if (update_rendertargets) {
 | 
			
		||||
            color_attachments[rt] = texture_cache.GetColorBufferSurface(rt, true);
 | 
			
		||||
            const bool preserve_contents = HasToPreserveColorContents(is_clear, regs);
 | 
			
		||||
            color_attachments[rt] = texture_cache.GetColorBufferSurface(rt, preserve_contents);
 | 
			
		||||
        }
 | 
			
		||||
        if (color_attachments[rt] && WalkAttachmentOverlaps(*color_attachments[rt])) {
 | 
			
		||||
            texceptions[rt] = true;
 | 
			
		||||
@@ -696,7 +743,8 @@ RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (update_rendertargets) {
 | 
			
		||||
        zeta_attachment = texture_cache.GetDepthBufferSurface(true);
 | 
			
		||||
        const bool preserve_contents = HasToPreserveDepthContents(is_clear, regs);
 | 
			
		||||
        zeta_attachment = texture_cache.GetDepthBufferSurface(preserve_contents);
 | 
			
		||||
    }
 | 
			
		||||
    if (zeta_attachment && WalkAttachmentOverlaps(*zeta_attachment)) {
 | 
			
		||||
        texceptions[ZETA_TEXCEPTION_INDEX] = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ private:
 | 
			
		||||
 | 
			
		||||
    void FlushWork();
 | 
			
		||||
 | 
			
		||||
    Texceptions UpdateAttachments();
 | 
			
		||||
    /// @brief Updates the currently bound attachments
 | 
			
		||||
    /// @param is_clear True when the framebuffer is updated as a clear
 | 
			
		||||
    /// @return Bitfield of attachments being used as sampled textures
 | 
			
		||||
    Texceptions UpdateAttachments(bool is_clear);
 | 
			
		||||
 | 
			
		||||
    std::tuple<VkFramebuffer, VkExtent2D> ConfigureFramebuffers(VkRenderPass renderpass);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user