tornavis/source/blender/gpu/vulkan/vk_framebuffer.hh

151 lines
4.6 KiB
C++

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#pragma once
#include "BLI_array.hh"
#include "BLI_math_vector.hh"
#include "BLI_span.hh"
#include "BLI_vector.hh"
#include "gpu_framebuffer_private.hh"
#include "vk_common.hh"
#include "vk_image_view.hh"
namespace blender::gpu {
class VKContext;
class VKFrameBuffer : public FrameBuffer {
private:
/* Vulkan object handle. */
VkFramebuffer vk_framebuffer_ = VK_NULL_HANDLE;
/* Vulkan device who created the handle. */
VkDevice vk_device_ = VK_NULL_HANDLE;
/* Base render pass used for frame-buffer creation. */
VkRenderPass vk_render_pass_ = VK_NULL_HANDLE;
/* Number of layers if the attachments are layered textures. */
int depth_ = 1;
Vector<VKImageView, GPU_FB_MAX_ATTACHMENT> image_views_;
/** Is the first attachment an SRGB texture. */
bool srgb_;
bool enabled_srgb_;
public:
/**
* Create a conventional frame-buffer to attach texture to.
*/
VKFrameBuffer(const char *name);
~VKFrameBuffer();
void bind(bool enabled_srgb) override;
bool check(char err_out[256]) override;
void clear(eGPUFrameBufferBits buffers,
const float clear_color[4],
float clear_depth,
uint clear_stencil) override;
void clear_multi(const float (*clear_color)[4]) override;
void clear_attachment(GPUAttachmentType type,
eGPUDataFormat data_format,
const void *clear_value) override;
void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore /*ls*/) override;
protected:
void subpass_transition_impl(const GPUAttachmentState depth_attachment_state,
Span<GPUAttachmentState> color_attachment_states) override;
public:
void read(eGPUFrameBufferBits planes,
eGPUDataFormat format,
const int area[4],
int channel_len,
int slot,
void *r_data) override;
void blit_to(eGPUFrameBufferBits planes,
int src_slot,
FrameBuffer *dst,
int dst_slot,
int dst_offset_x,
int dst_offset_y) override;
bool is_valid() const
{
return vk_framebuffer_ != VK_NULL_HANDLE;
}
VkFramebuffer vk_framebuffer_get() const
{
BLI_assert(vk_framebuffer_ != VK_NULL_HANDLE);
return vk_framebuffer_;
}
void vk_render_pass_ensure();
VkRenderPass vk_render_pass_get() const
{
BLI_assert(vk_render_pass_ != VK_NULL_HANDLE);
BLI_assert(!dirty_attachments_);
return vk_render_pass_;
}
Array<VkViewport, 16> vk_viewports_get() const;
Array<VkRect2D, 16> vk_render_areas_get() const;
void depth_attachment_layout_ensure(VKContext &context, VkImageLayout requested_layout);
void color_attachment_layout_ensure(VKContext &context,
int color_attachment,
VkImageLayout requested_layout);
/**
* Ensure that the size of the frame-buffer matches the first attachment resolution.
*
* Frame buffers attachments are updated when actually used as the image layout has to be
* correct. After binding frame-buffers the layout of images can still be modified.
*
* But for correct behavior of blit/clear operation the size of the frame-buffer should be
* set, when activating the frame buffer.
*/
void update_size();
void update_srgb();
/**
* Return the number of color attachments of this frame buffer, including unused color
* attachments.
*
* Frame-buffers can have unused attachments. When higher attachment slots are being used, unused
* lower attachment slots will be counted as they are required resources in render-passes.
*/
int color_attachments_resource_size() const;
private:
void update_attachments();
void render_pass_free();
void render_pass_create();
/* Clearing attachments */
void build_clear_attachments_depth_stencil(eGPUFrameBufferBits buffers,
float clear_depth,
uint32_t clear_stencil,
Vector<VkClearAttachment> &r_attachments) const;
void build_clear_attachments_color(const float (*clear_colors)[4],
const bool multi_clear_colors,
Vector<VkClearAttachment> &r_attachments) const;
void clear(Span<VkClearAttachment> attachments) const;
};
static inline VKFrameBuffer *unwrap(FrameBuffer *framebuffer)
{
return static_cast<VKFrameBuffer *>(framebuffer);
}
} // namespace blender::gpu