xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pvr_formats.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #ifndef PVR_FORMATS_H
25 #define PVR_FORMATS_H
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <vulkan/vulkan.h>
30 
31 #include "util/format/u_formats.h"
32 #include "vk_format.h"
33 
34 /* This is based on VkClearColorValue which is an array of RGBA, and on the
35  * output register usage for the biggest 32 bit 4 component formats which use up
36  * all 4 output registers.
37  * So this can be used for both unpacked RGBA value and to represent values
38  * packed according to the hardware (the accum format).
39  */
40 #define PVR_CLEAR_COLOR_ARRAY_SIZE 4
41 
42 #define PVR_TEX_FORMAT_COUNT (PVRX(TEXSTATE_IMAGE_WORD0_TEXFORMAT_MAX_SIZE) + 1)
43 
44 enum pvr_pbe_accum_format {
45    PVR_PBE_ACCUM_FORMAT_INVALID = 0, /* Explicitly treat 0 as invalid. */
46    PVR_PBE_ACCUM_FORMAT_U8,
47    PVR_PBE_ACCUM_FORMAT_S8,
48    PVR_PBE_ACCUM_FORMAT_U16,
49    PVR_PBE_ACCUM_FORMAT_S16,
50    PVR_PBE_ACCUM_FORMAT_F16,
51    PVR_PBE_ACCUM_FORMAT_F32,
52    PVR_PBE_ACCUM_FORMAT_UINT8,
53    PVR_PBE_ACCUM_FORMAT_UINT16,
54    PVR_PBE_ACCUM_FORMAT_UINT32,
55    PVR_PBE_ACCUM_FORMAT_SINT8,
56    PVR_PBE_ACCUM_FORMAT_SINT16,
57    PVR_PBE_ACCUM_FORMAT_SINT32,
58    /* Formats with medp shader output precision. */
59    PVR_PBE_ACCUM_FORMAT_UINT32_MEDP,
60    PVR_PBE_ACCUM_FORMAT_SINT32_MEDP,
61    PVR_PBE_ACCUM_FORMAT_U1010102,
62    PVR_PBE_ACCUM_FORMAT_U24,
63 };
64 
65 /**
66  * Pixel related shader selector. The logic selecting the shader has to take
67  * into account the pixel related properties (controlling the conversion path in
68  * the shader) and the geometry related properties (controlling the sample
69  * position calcs). These two can be orthogonal.
70  *
71  * integer format conversions, bit depth : 8, 16, 32 per ch formats : signed,
72  * unsigned. Strategy: convert everything to U32 or S32 then USC pack. PBE just
73  * pass through.
74  *
75  * fixed point format conversions, bit depth 565, 1555, 555 etc. Strategy:
76  * fcnorm to 4 F32, then USC pack to F16F16. PBE converts to destination
77  *
78  * float/fixed format conversions
79  * strategy: fcnorm, then pack to f16 _when_ destination is not f32.
80  *      fmt | unorm | flt |
81  *        8 |     x |     |
82  *       16 |     x |   x |
83  *       32 |     x |   x |
84  *
85  *
86  * non-merge type DS blit table
87  * **********************************************
88  * *        *  S8    D16   D24S8  D32    D32S8  *
89  * **********************************************
90  * * S8     *  cpy   i     i      i      i      *
91  * * D16    *  i     cpy   i      -      i      *
92  * * D24S8  *  swiz  -     cpy    (1)    -      *
93  * * D32    *  i     -     i      cpy    i      *
94  * * D32S8  *  (2)   -     -      cpy    cpy    *
95  * **********************************************
96  *
97  * merge with stencil pick type DS blit table
98  * **********************************************
99  * *        *  S8    D16   D24S8  D32    D32S8  *
100  * **********************************************
101  * * S8     *  i     i     (1)    i      (2)    *
102  * * D16    *  i     i     i      i      i      *
103  * * D24S8  *  i     i     (3)    i      (4)    *
104  * * D32    *  i     i     i      i      i      *
105  * * D32S8  *  i     i     (5)    i      (6)    *
106  * **********************************************
107  *
108  * merge with depth pick type DS blit table
109  * **********************************************
110  * *        *  S8    D16   D24S8  D32    D32S8  *
111  * **********************************************
112  * * S8     *  i     i     i      i      i      *
113  * * D16    *  -     -     -      -      -      *
114  * * D24S8  *  -     -     (s)    -      -      *
115  * * D32    *  -     -     (1)    -      (2)    *
116  * * D32S8  *  -     -     -      -      (s)    *
117  * **********************************************
118  *
119  * D formats are unpacked into a single register according to their format
120  * S formats are unpacked into a single register in U8
121  * D24S8 is in a single 32 bit register (as the PBE can't read it from
122  * unpacked.)
123  *
124  * Swizzles are applied on the TPU not the PBE because of potential
125  * accumulation i.e. a non-iterated shader doesn't know if it writes the output
126  * buffer for PBE emit or a second pass blend.
127  */
128 enum pvr_transfer_pbe_pixel_src {
129    PVR_TRANSFER_PBE_PIXEL_SRC_UU8888 = 0,
130    PVR_TRANSFER_PBE_PIXEL_SRC_US8888 = 1,
131    PVR_TRANSFER_PBE_PIXEL_SRC_UU16U16 = 2,
132    PVR_TRANSFER_PBE_PIXEL_SRC_US16S16 = 3,
133    PVR_TRANSFER_PBE_PIXEL_SRC_SU8888 = 4,
134    PVR_TRANSFER_PBE_PIXEL_SRC_SS8888 = 5,
135    PVR_TRANSFER_PBE_PIXEL_SRC_SU16U16 = 6,
136    PVR_TRANSFER_PBE_PIXEL_SRC_SS16S16 = 7,
137 
138    PVR_TRANSFER_PBE_PIXEL_SRC_UU1010102 = 8,
139    PVR_TRANSFER_PBE_PIXEL_SRC_SU1010102 = 9,
140    PVR_TRANSFER_PBE_PIXEL_SRC_RBSWAP_UU1010102 = 10,
141    PVR_TRANSFER_PBE_PIXEL_SRC_RBSWAP_SU1010102 = 11,
142 
143    PVR_TRANSFER_PBE_PIXEL_SRC_SU32U32 = 12,
144    PVR_TRANSFER_PBE_PIXEL_SRC_S4XU32 = 13,
145    PVR_TRANSFER_PBE_PIXEL_SRC_US32S32 = 14,
146    PVR_TRANSFER_PBE_PIXEL_SRC_U4XS32 = 15,
147 
148    PVR_TRANSFER_PBE_PIXEL_SRC_F16F16 = 16,
149    PVR_TRANSFER_PBE_PIXEL_SRC_U16NORM = 17,
150    PVR_TRANSFER_PBE_PIXEL_SRC_S16NORM = 18,
151 
152    PVR_TRANSFER_PBE_PIXEL_SRC_F32X4 = 19,
153    PVR_TRANSFER_PBE_PIXEL_SRC_F32X2 = 20,
154    PVR_TRANSFER_PBE_PIXEL_SRC_F32 = 21,
155 
156    PVR_TRANSFER_PBE_PIXEL_SRC_RAW32 = 22,
157    PVR_TRANSFER_PBE_PIXEL_SRC_RAW64 = 23,
158    PVR_TRANSFER_PBE_PIXEL_SRC_RAW128 = 24,
159 
160    /* f16 to U8 conversion in shader. */
161    PVR_TRANSFER_PBE_PIXEL_SRC_F16_U8 = 25,
162 
163    PVR_TRANSFER_PBE_PIXEL_SRC_SWAP_LMSB = 26,
164    PVR_TRANSFER_PBE_PIXEL_SRC_MOV_BY45 = 27,
165 
166    PVR_TRANSFER_PBE_PIXEL_SRC_D24S8 = 28,
167    PVR_TRANSFER_PBE_PIXEL_SRC_S8D24 = 29,
168    PVR_TRANSFER_PBE_PIXEL_SRC_D32S8 = 30,
169 
170    /* D: D32_S8 */
171    PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D32S8 = 31,
172    PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D32S8 = 32,
173    PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D32S8_D32S8 = 33,
174    PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32S8_D32S8 = 34,
175 
176    /* D: D32 */
177    PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D24_D32 = 35,
178    PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D32U_D32F = 36,
179 
180    /* D : D24_S8 */
181    PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D24S8 = 37,
182    PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D24S8 = 38,
183    PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D24S8_D24S8 = 39,
184    PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D32_D24S8 = 40,
185    PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32_D24S8 = 41,
186    PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32U_D24S8 = 42,
187 
188    /* ob0 holds Y and ob0 holds U or V. */
189    PVR_TRANSFER_PBE_PIXEL_SRC_YUV_PACKED = 43,
190 
191    /* ob0 holds Y, ob1 holds U, ob2 holds V. */
192    PVR_TRANSFER_PBE_PIXEL_SRC_Y_U_V = 44,
193 
194    PVR_TRANSFER_PBE_PIXEL_SRC_MASK16 = 45,
195    PVR_TRANSFER_PBE_PIXEL_SRC_MASK32 = 46,
196    PVR_TRANSFER_PBE_PIXEL_SRC_MASK48 = 47,
197    PVR_TRANSFER_PBE_PIXEL_SRC_MASK64 = 48,
198    PVR_TRANSFER_PBE_PIXEL_SRC_MASK96 = 49,
199    PVR_TRANSFER_PBE_PIXEL_SRC_MASK128 = 50,
200 
201    PVR_TRANSFER_PBE_PIXEL_SRC_CONV_S8D24_D24S8 = 51,
202 
203    /* ob0 holds Y and ob0 holds V or U. */
204    PVR_TRANSFER_PBE_PIXEL_SRC_YVU_PACKED = 52,
205 
206    /* ob0 holds Y, ob1 holds UV interleaved. */
207    PVR_TRANSFER_PBE_PIXEL_SRC_Y_UV_INTERLEAVED = 53,
208 
209    /* FIXME: This changes for other BVNC's which may change the hashing logic
210     * in pvr_hash_shader.
211     */
212    PVR_TRANSFER_PBE_PIXEL_SRC_NUM = 54,
213 };
214 
215 /* FIXME: Replace all instances of uint32_t with PVRX(TEXSTATE_FORMAT) or
216  * PVRX(TEXSTATE_FORMAT_COMPRESSED) after the pvr_common cleanup is complete.
217  */
218 
219 struct pvr_tex_format_description {
220    uint32_t tex_format;
221    enum pipe_format pipe_format_int;
222    enum pipe_format pipe_format_float;
223 };
224 
225 struct pvr_tex_format_compressed_description {
226    uint32_t tex_format;
227    enum pipe_format pipe_format;
228    uint32_t tex_format_simple;
229 };
230 
231 bool pvr_tex_format_is_supported(uint32_t tex_format);
232 
233 const struct pvr_tex_format_description *
234 pvr_get_tex_format_description(uint32_t tex_format);
235 
236 bool pvr_tex_format_compressed_is_supported(uint32_t tex_format);
237 
238 const struct pvr_tex_format_compressed_description *
239 pvr_get_tex_format_compressed_description(uint32_t tex_format);
240 
241 const uint8_t *pvr_get_format_swizzle(VkFormat vk_format);
242 uint32_t pvr_get_tex_format(VkFormat vk_format);
243 uint32_t pvr_get_tex_format_aspect(VkFormat vk_format,
244                                    VkImageAspectFlags aspect_mask);
245 uint32_t pvr_get_pbe_packmode(VkFormat vk_format);
246 uint32_t pvr_get_pbe_accum_format(VkFormat vk_format);
247 uint32_t pvr_get_pbe_accum_format_size_in_bytes(VkFormat vk_format);
248 bool pvr_format_is_pbe_downscalable(VkFormat vk_format);
249 
250 void pvr_get_hw_clear_color(VkFormat vk_format,
251                             VkClearColorValue value,
252                             uint32_t packed_out[static const 4]);
253 
254 uint32_t pvr_pbe_pixel_num_loads(enum pvr_transfer_pbe_pixel_src pbe_format);
255 
pvr_vk_format_has_32bit_component(VkFormat vk_format)256 static inline bool pvr_vk_format_has_32bit_component(VkFormat vk_format)
257 {
258    const struct util_format_description *desc =
259       vk_format_description(vk_format);
260 
261    for (uint32_t i = 0; i < desc->nr_channels; i++) {
262       if (desc->channel[i].size == 32U)
263          return true;
264    }
265 
266    return false;
267 }
268 
pvr_vk_format_is_fully_normalized(VkFormat vk_format)269 static inline bool pvr_vk_format_is_fully_normalized(VkFormat vk_format)
270 {
271    const struct util_format_description *desc =
272       vk_format_description(vk_format);
273 
274    for (uint32_t i = 0; i < desc->nr_channels; i++) {
275       if (!desc->channel[i].normalized)
276          return false;
277    }
278 
279    return true;
280 }
281 
282 static inline uint32_t
pvr_vk_format_get_common_color_channel_count(VkFormat src_format,VkFormat dst_format)283 pvr_vk_format_get_common_color_channel_count(VkFormat src_format,
284                                          VkFormat dst_format)
285 {
286    const struct util_format_description *dst_desc =
287       vk_format_description(dst_format);
288    const struct util_format_description *src_desc =
289       vk_format_description(src_format);
290    uint32_t count = 0;
291 
292    /* Check if destination format is alpha only and source format has alpha
293     * channel.
294     */
295    if (util_format_is_alpha(vk_format_to_pipe_format(dst_format))) {
296       count = 1;
297    } else if (dst_desc->nr_channels <= src_desc->nr_channels) {
298       for (uint32_t i = 0; i < dst_desc->nr_channels; i++) {
299          enum pipe_swizzle swizzle = dst_desc->swizzle[i];
300 
301          if (swizzle > PIPE_SWIZZLE_W)
302             continue;
303 
304          for (uint32_t j = 0; j < src_desc->nr_channels; j++) {
305             if (src_desc->swizzle[j] == swizzle) {
306                count++;
307                break;
308             }
309          }
310       }
311    } else {
312       count = dst_desc->nr_channels;
313    }
314 
315    return count;
316 }
317 
318 
319 #endif /* PVR_FORMATS_H */
320