This PR adds support for clearing framebuffers and scissor testing. Tweaks had to be made to VKTexture to keep track of its layout on the device. Based on the actual call the layout can switch to a more optimum layout. For example during upload of a texture the texture will be converted to a transfer destination optimized layout. When reading from the texture it will be converted to a transfer source optimized layout. The order of the attachments in the framebuffer follows the next rules - When only color attachments are there the color attachments will be placed in the slot they are defined. This way it will match the ShaderCreateInfo binding location. - When a stencil/depth attachment is added it will be placed right after the color attachments. When there isn't a color attachment it will be the first attachment. Pull Request: blender/blender#106044
114 lines
3.4 KiB
C++
114 lines
3.4 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2022 Blender Foundation. All rights reserved. */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_math_vector.hh"
|
|
#include "BLI_span.hh"
|
|
#include "BLI_vector.hh"
|
|
|
|
#include "gpu_framebuffer_private.hh"
|
|
|
|
#include "vk_common.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
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 framebuffer creation. */
|
|
VkRenderPass vk_render_pass_ = VK_NULL_HANDLE;
|
|
/* Number of layers if the attachments are layered textures. */
|
|
int depth_ = 1;
|
|
/** Internal frame-buffers are immutable. */
|
|
bool immutable_;
|
|
|
|
public:
|
|
/**
|
|
* Create a conventional framebuffer to attach texture to.
|
|
**/
|
|
VKFrameBuffer(const char *name);
|
|
|
|
/**
|
|
* Special frame-buffer encapsulating internal window frame-buffer.
|
|
* This just act as a wrapper, the actual allocations are done by GHOST_ContextVK.
|
|
**/
|
|
VKFrameBuffer(const char *name,
|
|
VkFramebuffer vk_framebuffer,
|
|
VkRenderPass vk_render_pass,
|
|
VkExtent2D vk_extent);
|
|
|
|
~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,
|
|
eGPULoadOp load_action,
|
|
eGPUStoreOp store_action) override;
|
|
|
|
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;
|
|
|
|
VkFramebuffer vk_framebuffer_get() const
|
|
{
|
|
BLI_assert(vk_framebuffer_ != VK_NULL_HANDLE);
|
|
return vk_framebuffer_;
|
|
}
|
|
|
|
VkRenderPass vk_render_pass_get() const
|
|
{
|
|
BLI_assert(vk_render_pass_ != VK_NULL_HANDLE);
|
|
return vk_render_pass_;
|
|
}
|
|
VkRect2D vk_render_area_get() 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(const Vector<VkClearAttachment> &attachments) const;
|
|
};
|
|
|
|
static inline VKFrameBuffer *unwrap(FrameBuffer *framebuffer)
|
|
{
|
|
return static_cast<VKFrameBuffer *>(framebuffer);
|
|
}
|
|
|
|
} // namespace blender::gpu
|