xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_texcompress_etc2.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2023 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef VK_TEXCOMPRESS_ETC2_H
7 #define VK_TEXCOMPRESS_ETC2_H
8 
9 #include "util/simple_mtx.h"
10 
11 #include "vk_device.h"
12 #include "vk_format.h"
13 #include "vk_object.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 struct nir_shader_compiler_options;
20 
21 struct vk_texcompress_etc2_state {
22    /* these are specified by the driver */
23    const VkAllocationCallbacks *allocator;
24    const struct nir_shader_compiler_options *nir_options;
25    VkPipelineCache pipeline_cache;
26 
27    /*
28     * The pipeline is a compute pipeline with
29     *
30     *  - layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
31     *  - layout(set = 0, binding = 0) uniform utexture2DArray s_tex_2d;
32     *  - layout(set = 0, binding = 0) uniform utexture3D s_tex_3d;
33     *  - layout(set = 0, binding = 1) uniform image2DArray out_img_2d;
34     *  - layout(set = 0, binding = 1) uniform image3D out_img_3d;
35     *  - layout(push_constant) uniform Registers {
36     *      ivec3 offset;
37     *      int vk_format;
38     *      int vk_image_type;
39     *    } registers;
40     *
41     * There are other implications, such as
42     *
43     *  - to make sure vkCmdCopyBufferToImage and vkCmdCopyImage are the only
44     *    means to initialize the image data,
45     *    - the format feature flags should not include flags that allow
46     *      modifying the image data
47     *    - the image tiling should be VK_IMAGE_TILING_OPTIMAL
48     *    - the image usage flags should not include
49     *      VK_IMAGE_USAGE_STORAGE_BIT, which can be made valid via
50     *      VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
51     *  - the image create flags are assumed to include
52     *    VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT and
53     *    VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT
54     *  - the image usage flags are assumed to include
55     *    VK_IMAGE_USAGE_SAMPLED_BIT (for src) or VK_IMAGE_USAGE_STORAGE_BIT
56     *    (for dst)
57     */
58    simple_mtx_t mutex;
59    VkDescriptorSetLayout ds_layout;
60    VkPipelineLayout pipeline_layout;
61    VkPipeline pipeline;
62 };
63 
64 void vk_texcompress_etc2_init(struct vk_device *device, struct vk_texcompress_etc2_state *etc2);
65 
66 VkResult vk_texcompress_etc2_late_init(struct vk_device *device, struct vk_texcompress_etc2_state *etc2);
67 
68 void vk_texcompress_etc2_finish(struct vk_device *device, struct vk_texcompress_etc2_state *etc2);
69 
70 static inline VkImageViewType
vk_texcompress_etc2_image_view_type(VkImageType image_type)71 vk_texcompress_etc2_image_view_type(VkImageType image_type)
72 {
73    switch (image_type) {
74    case VK_IMAGE_TYPE_2D:
75       return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
76    case VK_IMAGE_TYPE_3D:
77       return VK_IMAGE_VIEW_TYPE_3D;
78    default:
79       unreachable("bad image type");
80    }
81 }
82 
83 static inline VkFormat
vk_texcompress_etc2_emulation_format(VkFormat etc2_format)84 vk_texcompress_etc2_emulation_format(VkFormat etc2_format)
85 {
86    switch (etc2_format) {
87    case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
88    case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
89    case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
90       return VK_FORMAT_R8G8B8A8_UNORM;
91    case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
92    case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
93    case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
94       return VK_FORMAT_R8G8B8A8_SRGB;
95    case VK_FORMAT_EAC_R11_UNORM_BLOCK:
96       return VK_FORMAT_R16_UNORM;
97    case VK_FORMAT_EAC_R11_SNORM_BLOCK:
98       return VK_FORMAT_R16_SNORM;
99    case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
100       return VK_FORMAT_R16G16_UNORM;
101    case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
102       return VK_FORMAT_R16G16_SNORM;
103    default:
104       return VK_FORMAT_UNDEFINED;
105    }
106 }
107 
108 static inline VkFormat
vk_texcompress_etc2_load_format(VkFormat etc2_format)109 vk_texcompress_etc2_load_format(VkFormat etc2_format)
110 {
111    return vk_format_get_blocksize(etc2_format) == 16 ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32_UINT;
112 }
113 
114 static inline VkFormat
vk_texcompress_etc2_store_format(VkFormat etc2_format)115 vk_texcompress_etc2_store_format(VkFormat etc2_format)
116 {
117    VkFormat format = vk_texcompress_etc2_emulation_format(etc2_format);
118    if (format == VK_FORMAT_R8G8B8A8_SRGB)
119       format = VK_FORMAT_R8G8B8A8_UNORM;
120    return format;
121 }
122 
123 #ifdef __cplusplus
124 }
125 #endif
126 
127 #endif /* VK_TEXCOMPRESS_ETC2_H */
128