mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
- EGL swap semantics make the presented colour buffer's content undefined at its next acquire (EGL_BUFFER_DESTROYED, the implementation default) and every ancillary depth/stencil buffer's content undefined after ANY swap, yet the default-FBO render pass reloaded both with LOAD_OP_LOAD every frame; SwapchainObject now tracks per-image content validity (defined when a pass stores into the attachment, invalidated at present) and the render-pass manager turns an undefined attachment's tile load into LOAD_OP_DONT_CARE with initialLayout=UNDEFINED, keyed into both hashes so the cached LOAD variants cannot be hit by mistake - the default framebuffer's depth attachment is now attached ON DEMAND: a draw with depth test and stencil test both disabled (GL: a disabled test neither reads nor writes its buffer), and no pending depth/stencil clear, resolves to a depth-less pass flavour, dropping the D24S8 tile load AND store outright - MC 26.2 renders its GUI into its own FBO and only ever blits colour to the default framebuffer, so its swapchain pass carried a full-screen depth round-trip for nothing - the flavour only escalates: an active depth-full pass absorbs depth-less draws unchanged, while a depth-using draw against a depth-less pass resolves to an incompatible entry and splits, its depth loading DONT_CARE (the content was undefined all along); the depth-less flavour is folded into ComputeHash and the per-draw fast-path memo so the two flavours can never alias
99 lines
4.9 KiB
C++
99 lines
4.9 KiB
C++
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#pragma once
|
|
|
|
#include <Includes.h>
|
|
#include "../VkIncludes.h"
|
|
|
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
|
class SwapchainObject {
|
|
public:
|
|
struct SwapchainCapabilities {
|
|
VkSurfaceCapabilitiesKHR capabilities;
|
|
Vector<VkSurfaceFormatKHR> surfaceFormats;
|
|
Vector<VkPresentModeKHR> presentModes;
|
|
|
|
Bool IsComplete() const {
|
|
return !surfaceFormats.empty() && !presentModes.empty();
|
|
}
|
|
};
|
|
|
|
static SwapchainCapabilities GetSwapchainCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
|
|
static VkSurfaceFormatKHR ChooseSwapchainSurfaceFormat(const Vector<VkSurfaceFormatKHR>& availableFormats);
|
|
static VkPresentModeKHR ChooseSwapchainPresentMode(const Vector<VkPresentModeKHR>& availablePresentModes);
|
|
|
|
void Create(VkDevice device, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, Uint32 graphicsQueueFamily,
|
|
Uint32 presentQueueFamily, Uint32 minImageCountHint, VkExtent2D desiredExtent);
|
|
void Shutdown(VkDevice device);
|
|
|
|
VkSwapchainKHR GetHandle() const { return m_swapchain; }
|
|
const VkSurfaceFormatKHR& GetSurfaceFormat() const { return m_surfaceFormat; }
|
|
VkExtent2D GetExtent() const { return m_extent; }
|
|
// Surface-space extent (before the pre-rotation quarter-turn swap) this swapchain was
|
|
// created from - the value to compare a freshly queried currentExtent against.
|
|
VkExtent2D GetSurfaceExtent() const { return m_surfaceExtent; }
|
|
VkSurfaceTransformFlagBitsKHR GetPreTransform() const { return m_preTransform; }
|
|
const Vector<VkImage>& GetImages() const { return m_images; }
|
|
const Vector<VkImageView>& GetImageViews() const { return m_imageViews; }
|
|
VkFormat GetDepthStencilFormat() const { return m_depthStencilFormat; }
|
|
const Vector<VkImageView>& GetDepthStencilImageViews() const { return m_depthStencilImageViews; }
|
|
VkImage GetDepthStencilImage(Uint32 index) const;
|
|
VkImageView GetDepthStencilImageView(Uint32 index) const;
|
|
VkImageLayout GetDepthStencilImageLayout(Uint32 index) const;
|
|
void SetDepthStencilImageLayout(Uint32 index, VkImageLayout layout);
|
|
VkImage GetImage(Uint32 index) const;
|
|
VkImageLayout GetImageLayout(Uint32 index) const;
|
|
void SetImageLayout(Uint32 index, VkImageLayout layout);
|
|
SizeT GetImageCount() const { return m_images.size(); }
|
|
|
|
// EGL content-validity tracking for the default framebuffer. A color
|
|
// buffer's content is undefined once its image has been presented
|
|
// (EGL_BUFFER_DESTROYED swap behaviour, the implementation default),
|
|
// and every ancillary (depth/stencil) buffer's content is undefined
|
|
// after ANY swap regardless of swap behaviour (EGL 1.5 §3.10.1). The
|
|
// render-pass manager turns an undefined attachment's tile load into
|
|
// LOAD_OP_DONT_CARE. Flags start false (a fresh swapchain image holds
|
|
// garbage) and a render pass storing into an attachment sets it back
|
|
// to defined.
|
|
Bool IsImageContentDefined(Uint32 index) const;
|
|
void SetImageContentDefined(Uint32 index, Bool defined);
|
|
Bool IsDepthStencilContentDefined(Uint32 index) const;
|
|
void SetDepthStencilContentDefined(Uint32 index, Bool defined);
|
|
void SetAllDepthStencilContentUndefined();
|
|
|
|
private:
|
|
void CreateImageViews(VkDevice device);
|
|
void CreateDepthStencilResources(VkDevice device, VkPhysicalDevice physicalDevice);
|
|
void DestroyDepthStencilResources(VkDevice device);
|
|
static constexpr VkPresentModeKHR s_desiredPresentModes[] {
|
|
VK_PRESENT_MODE_MAILBOX_KHR,
|
|
VK_PRESENT_MODE_IMMEDIATE_KHR,
|
|
VK_PRESENT_MODE_FIFO_RELAXED_KHR,
|
|
VK_PRESENT_MODE_FIFO_KHR
|
|
};
|
|
|
|
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
|
VkSurfaceFormatKHR m_surfaceFormat{};
|
|
VkExtent2D m_extent{};
|
|
VkExtent2D m_surfaceExtent{};
|
|
VkSurfaceTransformFlagBitsKHR m_preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
|
Vector<VkImage> m_images;
|
|
Vector<VkImageView> m_imageViews;
|
|
Vector<VkImageLayout> m_imageLayouts;
|
|
|
|
VkFormat m_depthStencilFormat = VK_FORMAT_UNDEFINED;
|
|
Vector<VkImage> m_depthStencilImages;
|
|
Vector<VkDeviceMemory> m_depthStencilImageMemories;
|
|
Vector<VkImageView> m_depthStencilImageViews;
|
|
Vector<VkImageLayout> m_depthStencilImageLayouts;
|
|
Vector<Bool> m_imageContentDefined;
|
|
Vector<Bool> m_depthStencilContentDefined;
|
|
};
|
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|