Vulkan: Implement Component Swizzling

Component swizzling is part of an image view and localized in the code.
With component swizzling a different channel (or 0 or 1) can be read
when the component is accessed.

Pull Request: https://projects.blender.org/blender/blender/pulls/112273
This commit is contained in:
Jeroen Bakker
2023-09-12 11:54:57 +02:00
parent ded7d96ba1
commit 6920c690f1
5 changed files with 39 additions and 14 deletions

View File

@@ -729,17 +729,27 @@ VkImageViewType to_vk_image_view_type(const eGPUTextureType type, const eImageVi
return VK_IMAGE_VIEW_TYPE_1D;
}
VkComponentMapping to_vk_component_mapping(const eGPUTextureFormat /*format*/)
VkComponentSwizzle to_vk_component_swizzle(const char swizzle)
{
/* TODO: this should map to OpenGL defaults based on the eGPUTextureFormat. The
* implementation of this function will be implemented when implementing other parts of
* VKTexture. */
VkComponentMapping component_mapping;
component_mapping.r = VK_COMPONENT_SWIZZLE_R;
component_mapping.g = VK_COMPONENT_SWIZZLE_G;
component_mapping.b = VK_COMPONENT_SWIZZLE_B;
component_mapping.a = VK_COMPONENT_SWIZZLE_A;
return component_mapping;
switch (swizzle) {
case '0':
return VK_COMPONENT_SWIZZLE_ZERO;
case '1':
return VK_COMPONENT_SWIZZLE_ONE;
case 'r':
return VK_COMPONENT_SWIZZLE_R;
case 'g':
return VK_COMPONENT_SWIZZLE_G;
case 'b':
return VK_COMPONENT_SWIZZLE_B;
case 'a':
return VK_COMPONENT_SWIZZLE_A;
default:
break;
}
BLI_assert_unreachable();
return VK_COMPONENT_SWIZZLE_IDENTITY;
}
template<typename T> void copy_color(T dst[4], const T *src)

View File

@@ -47,7 +47,7 @@ VkFormat to_vk_format(const GPUVertCompType type,
const GPUVertFetchMode fetch_mode);
VkFormat to_vk_format(const shader::Type type);
VkComponentMapping to_vk_component_mapping(const eGPUTextureFormat format);
VkComponentSwizzle to_vk_component_swizzle(const char swizzle);
VkImageViewType to_vk_image_view_type(const eGPUTextureType type, eImageViewUsage view_type);
VkImageType to_vk_image_type(const eGPUTextureType type);
VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const void *data);

View File

@@ -34,7 +34,7 @@ VKImageView::VKImageView(VKTexture &texture,
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 = to_vk_format(texture.format_get());
image_view_info.components = to_vk_component_mapping(texture.format_get());
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();

View File

@@ -172,9 +172,14 @@ void VKTexture::clear_depth_stencil(const eGPUFrameBufferBits buffers,
Span<VkImageSubresourceRange>(&range, 1));
}
void VKTexture::swizzle_set(const char /*swizzle_mask*/[4])
void VKTexture::swizzle_set(const char swizzle_mask[4])
{
NOT_YET_IMPLEMENTED;
vk_component_mapping_.r = to_vk_component_swizzle(swizzle_mask[0]);
vk_component_mapping_.g = to_vk_component_swizzle(swizzle_mask[1]);
vk_component_mapping_.b = to_vk_component_swizzle(swizzle_mask[2]);
vk_component_mapping_.a = to_vk_component_swizzle(swizzle_mask[3]);
flags_ |= IMAGE_VIEW_DIRTY;
}
void VKTexture::mip_range_set(int min, int max)

View File

@@ -36,6 +36,11 @@ class VKTexture : public Texture, public VKBindableResource {
int layer_offset_ = 0;
bool use_stencil_ = false;
VkComponentMapping vk_component_mapping_ = {VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY};
enum eDirtyFlags {
IMAGE_VIEW_DIRTY = (1 << 0),
};
@@ -164,6 +169,11 @@ class VKTexture : public Texture, public VKBindableResource {
return *image_view_;
}
const VkComponentMapping &vk_component_mapping_get() const
{
return vk_component_mapping_;
}
private:
IndexRange mip_map_range() const;
IndexRange layer_range() const;