36 enabled_srgb_ =
false;
42 if (context && context->active_framebuffer_get() ==
this) {
43 context->deactivate_framebuffer();
48void VKFrameBuffer::render_pass_free()
51 if (vk_framebuffer != VK_NULL_HANDLE) {
53 vk_framebuffer = VK_NULL_HANDLE;
71 if (context.has_active_framebuffer()) {
72 context.deactivate_framebuffer();
75 context.activate_framebuffer(*
this);
80 enabled_srgb_ = enabled_srgb;
95 viewport.minDepth = 0.0f;
96 viewport.maxDepth = 1.0f;
97 r_viewports.
append(viewport);
108 render_area.extent.width =
clamp_i(scissor_rect[2], 1,
width_ - scissor_rect[0]);
109 render_area.extent.height =
clamp_i(scissor_rect[3], 1,
height_ - scissor_rect[1]);
112 render_area.offset.x = 0;
113 render_area.offset.y = 0;
114 render_area.extent.width =
width_;
115 render_area.extent.height =
height_;
122 VkRect2D render_area;
131 if (has_gaps_between_color_attachments()) {
136 "Framebuffer '%s' has gaps between color attachments. This is not supported by "
137 "legacy devices using VkRenderPass natively.\n",
144bool VKFrameBuffer::has_gaps_between_color_attachments()
const
146 bool empty_slot =
false;
149 if (attachment.
tex ==
nullptr) {
152 else if (empty_slot) {
159void VKFrameBuffer::build_clear_attachments_depth_stencil(
162 uint32_t clear_stencil,
169 clear_attachments.attachments[clear_attachments.attachment_count++];
176void VKFrameBuffer::build_clear_attachments_color(
177 const float (*clear_colors)[4],
178 const bool multi_clear_colors,
184 if (attachment.
tex ==
nullptr) {
188 clear_attachments.attachments[clear_attachments.attachment_count++];
193 &clear_colors[color_index]);
195 color_index += multi_clear_colors ? 1 : 0;
207 context.render_graph().add_node(clear_attachments);
211 const float clear_color[4],
217 clear_attachments.vk_clear_rect.baseArrayLayer = 0;
218 clear_attachments.vk_clear_rect.layerCount = 1;
235 if ((context.state_manager_get().state.write_mask & needed_mask) == needed_mask &&
238 build_clear_attachments_depth_stencil(
239 buffers, clear_depth, clear_stencil, clear_attachments);
244 if (depth_texture !=
nullptr) {
249 attachment.
layer == -1 ? std::nullopt : std::make_optional(attachment.
layer));
254 float clear_color_single[4];
256 build_clear_attachments_color(&clear_color_single,
false, clear_attachments);
259 if (clear_attachments.attachment_count) {
260 clear(clear_attachments);
268 clear_attachments.vk_clear_rect.baseArrayLayer = 0;
269 clear_attachments.vk_clear_rect.layerCount = 1;
271 build_clear_attachments_color(clear_color,
true, clear_attachments);
272 if (clear_attachments.attachment_count) {
273 clear(clear_attachments);
295 load_stores[type] = ls;
302 return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
304 return VK_ATTACHMENT_LOAD_OP_CLEAR;
306 return VK_ATTACHMENT_LOAD_OP_LOAD;
309 return VK_ATTACHMENT_LOAD_OP_LOAD;
316 return VK_ATTACHMENT_STORE_OP_DONT_CARE;
318 return VK_ATTACHMENT_STORE_OP_STORE;
321 return VK_ATTACHMENT_STORE_OP_STORE;
345 attachment_states_.as_mutable_span()
347 .copy_from(color_attachment_states);
349 if (supports_local_read) {
356 context.state_manager_get().image_bind(
texture, index);
361 is_rendering_ =
false;
381 context.state_manager_get().texture_bind(
421 "Trying to read back texture from framebuffer, but no texture is available in "
426 const int region[6] = {area[0], area[1], 0, area[0] + area[2], area[1] + area[3], 1};
442 VkImageAspectFlags image_aspect)
446 if (dst_offset_x == 0 && dst_offset_y == 0 &&
451 src_texture.
copy_to(dst_texture, image_aspect);
459 blit_image.
filter = VK_FILTER_NEAREST;
461 VkImageBlit ®ion = blit_image.
region;
462 region.srcSubresource.aspectMask = image_aspect;
463 region.srcSubresource.mipLevel = 0;
464 region.srcSubresource.baseArrayLayer = 0;
465 region.srcSubresource.layerCount = 1;
466 region.srcOffsets[0].x = 0;
467 region.srcOffsets[0].y = 0;
468 region.srcOffsets[0].z = 0;
469 region.srcOffsets[1].x = src_texture.
width_get();
470 region.srcOffsets[1].y = src_texture.
height_get();
471 region.srcOffsets[1].z = 1;
473 region.dstSubresource.aspectMask = image_aspect;
474 region.dstSubresource.mipLevel = 0;
475 region.dstSubresource.baseArrayLayer = 0;
476 region.dstSubresource.layerCount = 1;
479 region.dstOffsets[0].z = 0;
480 region.dstOffsets[1].x =
clamp_i(
482 region.dstOffsets[1].y =
clamp_i(
484 region.dstOffsets[1].z = 1;
486 context.render_graph().add_node(blit_image);
498 "VKFrameBuffer::blit_to only supports a single color or depth aspect.");
502 if (!context.has_active_framebuffer()) {
512 if (src_attachment.
tex && dst_attachment.
tex) {
520 VK_IMAGE_ASPECT_COLOR_BIT);
533 if (src_attachment.
tex && dst_attachment.
tex) {
541 VK_IMAGE_ASPECT_DEPTH_BIT);
560 if (attachment.
tex) {
595 is_rendering_ =
false;
602 depth_attachment_format_ = VK_FORMAT_UNDEFINED;
603 stencil_attachment_format_ = VK_FORMAT_UNDEFINED;
611 uint32_t max_layer_count = 1;
614 VkAttachmentReference depth_attachment_reference = {0u};
615 for (
int color_attachment_index :
619 if (attachment.
tex ==
nullptr) {
624 "Texture is used as an attachment, but doesn't have the "
625 "GPU_TEXTURE_USAGE_ATTACHMENT flag.");
629 if (attachment.
layer == -1 && layer_count != 1) {
630 max_layer_count =
max_ii(max_layer_count, layer_count);
636 layer_count != 1 ?
max_ii(layer_count - layer_base, 1) : layer_count),
638 {{
'r',
'g',
'b',
'a'}},
640 srgb_ && enabled_srgb_,
645 VK_IMAGE_LAYOUT_GENERAL :
646 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
650 depth_attachment_reference.attachment = attachment_reference + 1;
652 VkAttachmentDescription vk_attachment_description = {};
653 vk_attachment_description.format = image_view.
vk_format();
654 vk_attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
655 vk_attachment_description.initialLayout = vk_image_layout;
656 vk_attachment_description.finalLayout = vk_image_layout;
657 vk_attachment_descriptions.
append(std::move(vk_attachment_description));
660 switch (attachment_state) {
662 color_attachments.
append({attachment_reference, vk_image_layout});
664 access_info.
images.append(
666 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
667 VK_IMAGE_ASPECT_COLOR_BIT,
673 input_attachments.
append({attachment_reference, vk_image_layout});
675 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
676 VK_IMAGE_ASPECT_COLOR_BIT,
682 input_attachments.
append({VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED});
693 bool has_depth_attachment =
false;
697 if (attachment.
tex ==
nullptr) {
700 has_depth_attachment =
true;
704 "Texture is used as an attachment, but doesn't have the "
705 "GPU_TEXTURE_USAGE_ATTACHMENT flag.");
708 bool is_depth_stencil_attachment = depth_texture_aspect & VK_IMAGE_ASPECT_STENCIL_BIT;
709 VkImageLayout vk_image_layout = is_depth_stencil_attachment ?
710 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
711 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
713 VkImageView depth_image_view = VK_NULL_HANDLE;
719 {{
'r',
'g',
'b',
'a'}},
720 is_stencil_attachment,
725 VkAttachmentDescription vk_attachment_description = {};
727 vk_attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
728 vk_attachment_description.initialLayout = vk_image_layout;
729 vk_attachment_description.finalLayout = vk_image_layout;
730 vk_attachment_descriptions.
append(std::move(vk_attachment_description));
731 depth_attachment_reference.layout = vk_image_layout;
732 vk_image_views.
append(depth_image_view);
734 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
735 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
736 is_stencil_attachment ?
737 static_cast<VkImageAspectFlags
>(VK_IMAGE_ASPECT_DEPTH_BIT |
738 VK_IMAGE_ASPECT_STENCIL_BIT) :
739 static_cast<VkImageAspectFlags
>(VK_IMAGE_ASPECT_DEPTH_BIT),
743 depth_attachment_format_ = vk_format;
744 if (is_stencil_attachment) {
745 stencil_attachment_format_ = vk_format;
750 VkSubpassDescription vk_subpass_description = {};
751 vk_subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
752 vk_subpass_description.colorAttachmentCount = color_attachments.
size();
753 vk_subpass_description.pColorAttachments = color_attachments.
data();
754 vk_subpass_description.inputAttachmentCount = input_attachments.
size();
755 vk_subpass_description.pInputAttachments = input_attachments.
data();
756 if (has_depth_attachment) {
757 vk_subpass_description.pDepthStencilAttachment = &depth_attachment_reference;
762 VkRenderPassCreateInfo vk_render_pass_create_info = {};
763 vk_render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
764 vk_render_pass_create_info.subpassCount = 1;
765 vk_render_pass_create_info.pSubpasses = &vk_subpass_description;
766 vk_render_pass_create_info.attachmentCount = vk_attachment_descriptions.
size();
767 vk_render_pass_create_info.pAttachments = vk_attachment_descriptions.
data();
772 VkFramebufferCreateInfo vk_framebuffer_create_info = {};
773 vk_framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
775 vk_framebuffer_create_info.attachmentCount = vk_image_views.
size();
776 vk_framebuffer_create_info.pAttachments = vk_image_views.
data();
777 vk_framebuffer_create_info.width =
width_;
778 vk_framebuffer_create_info.height =
height_;
779 vk_framebuffer_create_info.layers = max_layer_count;
780 vkCreateFramebuffer(device.
vk_handle(), &vk_framebuffer_create_info,
nullptr, &vk_framebuffer);
786 begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
788 begin_info.framebuffer = vk_framebuffer;
791 context.render_graph().add_node(begin_rendering);
805 GPULoadStore &load_store = load_stores[attachment_index];
812 build_clear_attachments_depth_stencil(
816 build_clear_attachments_color(&load_store.
clear_value,
false, clear_attachments);
820 if (clear_attachments.attachment_count != 0) {
822 clear_attachments.vk_clear_rect.baseArrayLayer = 0;
823 clear_attachments.vk_clear_rect.layerCount = 1;
824 context.render_graph().add_node(clear_attachments);
835 depth_attachment_format_ = VK_FORMAT_UNDEFINED;
836 stencil_attachment_format_ = VK_FORMAT_UNDEFINED;
844 color_attachment_formats_.clear();
845 for (
int color_attachment_index :
849 if (attachment.
tex ==
nullptr) {
855 "Texture is used as an attachment, but doesn't have the "
856 "GPU_TEXTURE_USAGE_ATTACHMENT flag.");
861 if (attachment.
layer == -1 && layer_count != 1) {
866 VkRenderingAttachmentInfo &attachment_info =
869 attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
871 VkImageView vk_image_view = VK_NULL_HANDLE;
879 layer_count != 1 ?
max_ii(layer_count - layer_base, 1) : layer_count),
881 {{
'r',
'g',
'b',
'a'}},
883 srgb_ && enabled_srgb_,
889 attachment_info.imageView = vk_image_view;
890 attachment_info.imageLayout = supports_local_read ? VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR :
891 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
892 set_load_store(attachment_info, load_stores[color_attachment_index]);
894 access_info.
images.append(
896 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
897 VK_IMAGE_ASPECT_COLOR_BIT,
899 color_attachment_formats_.append(
901 VK_FORMAT_UNDEFINED :
912 if (attachment.
tex ==
nullptr) {
918 "Texture is used as an attachment, but doesn't have the "
919 "GPU_TEXTURE_USAGE_ATTACHMENT flag.");
922 VK_IMAGE_ASPECT_STENCIL_BIT;
923 VkImageLayout vk_image_layout = is_depth_stencil_attachment ?
924 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
925 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
927 VkImageView depth_image_view = VK_NULL_HANDLE;
932 {{
'r',
'g',
'b',
'a'}},
933 is_stencil_attachment,
939 depth_image_view == VK_NULL_HANDLE) ?
940 VK_FORMAT_UNDEFINED :
948 attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
949 attachment_info.imageView = depth_image_view;
950 attachment_info.imageLayout = vk_image_layout;
952 set_load_store(attachment_info, load_stores[depth_attachment_index]);
953 depth_attachment_format_ = vk_format;
958 if (is_stencil_attachment) {
960 attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
961 attachment_info.imageView = depth_image_view;
962 attachment_info.imageLayout = vk_image_layout;
964 set_load_store(attachment_info, load_stores[depth_attachment_index]);
965 stencil_attachment_format_ = vk_format;
971 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
972 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
973 is_stencil_attachment ?
974 static_cast<VkImageAspectFlags
>(VK_IMAGE_ASPECT_DEPTH_BIT |
975 VK_IMAGE_ASPECT_STENCIL_BIT) :
976 static_cast<VkImageAspectFlags
>(VK_IMAGE_ASPECT_DEPTH_BIT),
981 context.render_graph().add_node(begin_rendering);
1003 is_rendering_ =
true;
1016 return depth_attachment_format_;
1020 return stencil_attachment_format_;
1024 return color_attachment_formats_;
1033 if (is_rendering_) {
1041 context.render_graph().add_node(end_rendering);
1042 is_rendering_ =
false;
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE int max_ii(int a, int b)
MINLINE int clamp_i(int value, int min, int max)
MINLINE void copy_v4_v4(float r[4], const float a[4])
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
@ GPU_LOADACTION_DONT_CARE
@ GPU_STOREACTION_DONT_CARE
static constexpr int GPU_MAX_VIEWPORTS
@ GPU_TEXTURE_USAGE_ATTACHMENT
void GPU_texture_get_mipmap_size(GPUTexture *texture, int mip_level, int *r_size)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
void append(const T &value)
void append_n_times(const T &value, const int64_t n)
void size_set(int width, int height)
bool use_explicit_load_store_
bool scissor_test_get() const
char name_[DEBUG_NAME_LEN]
const GPUAttachment & depth_attachment() const
void scissor_get(int r_scissor[4]) const
GPUTexture * color_tex(int slot) const
FrameBuffer(const char *name)
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
int viewport_[GPU_MAX_VIEWPORTS][4]
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
eGPUTextureUsage usage_get() const
VkDevice vk_handle() const
const VKExtensions & extensions_get() const
void discard_framebuffer(VkFramebuffer vk_framebuffer)
static VKDiscardPool & discard_pool_get()
void discard_render_pass(VkRenderPass vk_render_pass)
void rendering_ensure_dynamic_rendering(VKContext &context, const VKExtensions &extensions)
void rendering_ensure(VKContext &context)
void rendering_ensure_render_pass(VKContext &context)
VKFrameBuffer(const char *name)
void clear_multi(const float(*clear_color)[4]) override
void vk_render_areas_append(Vector< VkRect2D > &r_render_areas) const
uint32_t color_attachment_size
VkFormat stencil_attachment_format_get() const
void read(eGPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data) override
void subpass_transition_impl(const GPUAttachmentState depth_attachment_state, Span< GPUAttachmentState > color_attachment_states) override
void render_area_update(VkRect2D &render_area) const
void clear(eGPUFrameBufferBits buffers, const float clear_color[4], float clear_depth, uint clear_stencil) override
void bind(bool enabled_srgb) override
VkFormat depth_attachment_format_get() const
void rendering_end(VKContext &context)
VkRenderPass vk_render_pass
bool check(char err_out[256]) override
void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore) override
void blit_to(eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y) override
int color_attachments_resource_size() const
void clear_attachment(GPUAttachmentType type, eGPUDataFormat data_format, const void *clear_value) override
void vk_viewports_append(Vector< VkViewport > &r_viewports) const
Span< VkFormat > color_attachment_formats_get() const
VkFormat vk_format() const
VkImageView vk_handle() const
void clear_depth_stencil(const eGPUFrameBufferBits buffer, float clear_depth, uint clear_stencil, std::optional< int > layer)
void copy_to(Texture *tex) override
eGPUTextureFormat device_format_get() const
VkImage vk_image_handle() const
const VKImageView & image_view_get(const VKImageViewInfo &info)
VKClearAttachmentsData CreateInfo
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
int context(const bContext *C, const char *member, bContextDataResult *result)
void object_label(GLenum type, GLuint object, const char *name)
constexpr GPULoadStore default_load_store()
static Context * unwrap(GPUContext *ctx)
static VkAttachmentStoreOp to_vk_attachment_store_op(eGPUStoreOp store_op)
static void set_load_store(VkRenderingAttachmentInfo &r_rendering_attachment, const GPULoadStore &ls)
static VkAttachmentLoadOp to_vk_attachment_load_op(eGPULoadOp load_op)
VkFormat to_vk_format(const eGPUTextureFormat format)
VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const void *data)
VkImageAspectFlags to_vk_image_aspect_flag_bits(const eGPUTextureFormat format)
static void blit_aspect(VKContext &context, VKTexture &dst_texture, VKTexture &src_texture, int dst_offset_x, int dst_offset_y, VkImageAspectFlags image_aspect)
constexpr DataFormat to_data_format(TextureFormat format)
static constexpr GPUSamplerState default_sampler()
bool dynamic_rendering_unused_attachments
bool dynamic_rendering_local_read
VKBeginRenderingData node_data
VkRenderingAttachmentInfo stencil_attachment
VkRenderingAttachmentInfo color_attachments[8]
VkRenderingAttachmentInfo depth_attachment
VkRenderingInfoKHR vk_rendering_info
VkRenderPassBeginInfo vk_render_pass_begin_info
VkRenderPass vk_render_pass
Vector< VKImageAccess > images