Allow binding of framebuffers without sRGB to linear transform. `GPU_framebuffer_bind_no_srgb`. This Patch removes color transform artifacts in node, image and sequence editor. When the framebuffer is an srgb framebuffer and it is bound without the transformation, the SRGB textures are bound as UNORM variants. As framebuffer, render pass and subpass recreation is ensured by `VKCommandBuffer` we don't need to mark the framebuffer dirty at this time. Later on we can optimize this by adding a state changed detection for framebuffers and render passes. Pull Request: https://projects.blender.org/blender/blender/pulls/113838
89 lines
2.8 KiB
C++
89 lines
2.8 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "vk_image_view.hh"
|
|
#include "vk_backend.hh"
|
|
#include "vk_debug.hh"
|
|
#include "vk_device.hh"
|
|
#include "vk_memory.hh"
|
|
#include "vk_texture.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
static VkFormat to_non_srgb_format(const VkFormat format)
|
|
{
|
|
switch (format) {
|
|
case VK_FORMAT_R8G8B8_SRGB:
|
|
return VK_FORMAT_R8G8B8_UNORM;
|
|
case VK_FORMAT_R8G8B8A8_SRGB:
|
|
return VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return format;
|
|
}
|
|
|
|
VKImageView::VKImageView(VKTexture &texture,
|
|
eImageViewUsage usage,
|
|
IndexRange layer_range,
|
|
IndexRange mip_range,
|
|
bool use_stencil,
|
|
bool use_srgb,
|
|
StringRefNull name)
|
|
{
|
|
const VkImageAspectFlagBits allowed_bits = static_cast<VkImageAspectFlagBits>(
|
|
VK_IMAGE_ASPECT_COLOR_BIT |
|
|
(use_stencil ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT));
|
|
VkImageAspectFlagBits image_aspect = static_cast<VkImageAspectFlagBits>(
|
|
(to_vk_image_aspect_flag_bits(texture.format_get()) & allowed_bits));
|
|
|
|
vk_format_ = to_vk_format(texture.format_get());
|
|
if (texture.format_flag_get() & GPU_FORMAT_SRGB && !use_srgb) {
|
|
vk_format_ = to_non_srgb_format(vk_format_);
|
|
}
|
|
|
|
VK_ALLOCATION_CALLBACKS
|
|
VkImageViewCreateInfo image_view_info = {};
|
|
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
image_view_info.image = texture.vk_image_handle();
|
|
image_view_info.viewType = to_vk_image_view_type(texture.type_get(), usage);
|
|
image_view_info.format = vk_format_;
|
|
image_view_info.components = texture.vk_component_mapping_get();
|
|
image_view_info.subresourceRange.aspectMask = image_aspect;
|
|
image_view_info.subresourceRange.baseMipLevel = mip_range.first();
|
|
image_view_info.subresourceRange.levelCount = mip_range.size();
|
|
image_view_info.subresourceRange.baseArrayLayer = layer_range.first();
|
|
image_view_info.subresourceRange.layerCount = layer_range.size();
|
|
|
|
const VKDevice &device = VKBackend::get().device_get();
|
|
vkCreateImageView(
|
|
device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
|
|
debug::object_label(vk_image_view_, name.c_str());
|
|
}
|
|
|
|
VKImageView::VKImageView(VKImageView &&other)
|
|
{
|
|
vk_image_view_ = other.vk_image_view_;
|
|
other.vk_image_view_ = VK_NULL_HANDLE;
|
|
vk_format_ = other.vk_format_;
|
|
other.vk_format_ = VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
VKImageView::~VKImageView()
|
|
{
|
|
if (vk_image_view_ != VK_NULL_HANDLE) {
|
|
VKDevice &device = VKBackend::get().device_get();
|
|
device.discard_image_view(vk_image_view_);
|
|
vk_image_view_ = VK_NULL_HANDLE;
|
|
}
|
|
vk_format_ = VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
} // namespace blender::gpu
|