CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/Vulkan/VulkanFramebuffer.h
Views: 1401
#pragma once12#include "Common/Common.h"3#include "Common/GPU/Vulkan/VulkanContext.h"45class VKRRenderPass;6class VulkanBarrierBatch;78// Pipelines need to be created for the right type of render pass.9// TODO: Rename to RenderPassFlags?10// When you add more flags, don't forget to update rpTypeDebugNames[].11enum class RenderPassType {12DEFAULT = 0,13// These eight are organized so that bit 0 is DEPTH and bit 1 is INPUT and bit 2 is MULTIVIEW, so14// they can be OR-ed together in MergeRPTypes.15HAS_DEPTH = 1,16MULTIVIEW = 2,17MULTISAMPLE = 4,1819// This is the odd one out, and gets special handling in MergeRPTypes.20// If this flag is set, none of the other flags can be set.21// For the backbuffer we can always use CLEAR/DONT_CARE, so bandwidth cost for a depth channel is negligible22// so we don't bother with a non-depth version.23BACKBUFFER = 8,2425TYPE_COUNT = BACKBUFFER + 1,26};27ENUM_CLASS_BITOPS(RenderPassType);2829// Simple independent framebuffer image.30struct VKRImage {31// These four are "immutable".32VkImage image;3334VkImageView rtView; // Used for rendering to, and readbacks of stencil. 2D if single layer, 2D_ARRAY if multiple. Includes both depth and stencil if depth/stencil.3536// This is for texturing all layers at once. If aspect is depth/stencil, does not include stencil.37VkImageView texAllLayersView;3839// If it's a layered image (for stereo), this is two 2D views of it, to make it compatible with shaders that don't yet support stereo.40// If there's only one layer, layerViews[0] only is initialized.41VkImageView texLayerViews[2]{};4243VmaAllocation alloc;44VkFormat format;45VkSampleCountFlagBits sampleCount;4647// This one is used by QueueRunner's Perform functions to keep track. CANNOT be used anywhere else due to sync issues.48VkImageLayout layout;4950int numLayers;5152// For debugging.53std::string tag;5455void Delete(VulkanContext *vulkan);56};5758class VKRFramebuffer {59public:60VKRFramebuffer(VulkanContext *vk, VulkanBarrierBatch *barriers, VkCommandBuffer initCmd, VKRRenderPass *compatibleRenderPass, int _width, int _height, int _numLayers, int _multiSampleLevel, bool createDepthStencilBuffer, const char *tag);61~VKRFramebuffer();6263VkFramebuffer Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType);6465int width = 0;66int height = 0;67int numLayers = 0;68VkSampleCountFlagBits sampleCount;6970VKRImage color{}; // color.image is always there.71VKRImage depth{}; // depth.image is allowed to be VK_NULL_HANDLE.7273// These are only initialized and used if numSamples > 1.74VKRImage msaaColor{};75VKRImage msaaDepth{};7677const char *Tag() const {78return tag_.c_str();79}8081void UpdateTag(const char *newTag);8283bool HasDepth() const {84return depth.image != VK_NULL_HANDLE;85}8687VkImageView GetRTView() {88if (sampleCount == VK_SAMPLE_COUNT_1_BIT) {89return color.rtView;90} else {91return msaaColor.rtView;92}93}9495VulkanContext *Vulkan() const { return vulkan_; }96private:97static void CreateImage(VulkanContext *vulkan, VulkanBarrierBatch *barriers, VkCommandBuffer cmd, VKRImage &img, int width, int height, int numLayers, VkSampleCountFlagBits sampleCount, VkFormat format, VkImageLayout initialLayout, bool color, const char *tag);9899VkFramebuffer framebuf[(size_t)RenderPassType::TYPE_COUNT]{};100101VulkanContext *vulkan_;102std::string tag_;103};104105inline bool RenderPassTypeHasDepth(RenderPassType type) {106return (type & RenderPassType::HAS_DEPTH) || type == RenderPassType::BACKBUFFER;107}108109inline bool RenderPassTypeHasMultiView(RenderPassType type) {110return (type & RenderPassType::MULTIVIEW) != 0;111}112113inline bool RenderPassTypeHasMultisample(RenderPassType type) {114return (type & RenderPassType::MULTISAMPLE) != 0;115}116117VkSampleCountFlagBits MultiSampleLevelToFlagBits(int count);118119// Must be the same order as Draw::RPAction120enum class VKRRenderPassLoadAction : uint8_t {121KEEP, // default. avoid when possible.122CLEAR,123DONT_CARE,124};125126enum class VKRRenderPassStoreAction : uint8_t {127STORE, // default. avoid when possible.128DONT_CARE,129};130131struct RPKey {132// Only render-pass-compatibility-volatile things can be here.133VKRRenderPassLoadAction colorLoadAction;134VKRRenderPassLoadAction depthLoadAction;135VKRRenderPassLoadAction stencilLoadAction;136VKRRenderPassStoreAction colorStoreAction;137VKRRenderPassStoreAction depthStoreAction;138VKRRenderPassStoreAction stencilStoreAction;139};140141class VKRRenderPass {142public:143VKRRenderPass(const RPKey &key) : key_(key) {}144145VkRenderPass Get(VulkanContext *vulkan, RenderPassType rpType, VkSampleCountFlagBits sampleCount);146void Destroy(VulkanContext *vulkan) {147for (size_t i = 0; i < (size_t)RenderPassType::TYPE_COUNT; i++) {148if (pass[i]) {149vulkan->Delete().QueueDeleteRenderPass(pass[i]);150}151}152}153154private:155// TODO: Might be better off with a hashmap once the render pass type count grows really large..156VkRenderPass pass[(size_t)RenderPassType::TYPE_COUNT]{};157VkSampleCountFlagBits sampleCounts[(size_t)RenderPassType::TYPE_COUNT]{};158RPKey key_;159};160161const char *GetRPTypeName(RenderPassType rpType);162163164