2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
28 #include "tu_private.h"
30 #include "util/debug.h"
31 #include "util/u_atomic.h"
32 #include "vk_format.h"
36 image_level_linear(struct tu_image
*image
, int level
)
38 unsigned w
= u_minify(image
->extent
.width
, level
);
42 /* indexed by cpp, including msaa 2x and 4x: */
46 } tile_alignment
[] = {
60 /* special case for r8g8: */
65 setup_slices(struct tu_image
*image
, const VkImageCreateInfo
*pCreateInfo
)
67 VkFormat format
= pCreateInfo
->format
;
68 enum vk_format_layout layout
= vk_format_description(format
)->layout
;
69 uint32_t layer_size
= 0;
72 /* The r8g8 format seems to not play by the normal tiling rules: */
73 if (image
->cpp
== 2 && vk_format_get_nr_components(format
) == 2)
76 for (unsigned level
= 0; level
< pCreateInfo
->mipLevels
; level
++) {
77 struct tu_image_level
*slice
= &image
->levels
[level
];
78 uint32_t width
= u_minify(pCreateInfo
->extent
.width
, level
);
79 uint32_t height
= u_minify(pCreateInfo
->extent
.height
, level
);
80 uint32_t depth
= u_minify(pCreateInfo
->extent
.depth
, level
);
81 uint32_t aligned_height
= height
;
85 if (image
->tile_mode
&& !image_level_linear(image
, level
)) {
86 /* tiled levels of 3D textures are rounded up to PoT dimensions: */
87 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
) {
88 width
= util_next_power_of_two(width
);
89 height
= aligned_height
= util_next_power_of_two(height
);
91 pitchalign
= tile_alignment
[ta
].pitchalign
;
92 aligned_height
= align(aligned_height
, tile_alignment
[ta
].heightalign
);
97 /* The blits used for mem<->gmem work at a granularity of
98 * 32x32, which can cause faults due to over-fetch on the
99 * last level. The simple solution is to over-allocate a
100 * bit the last level to ensure any over-fetch is harmless.
101 * The pitch is already sufficiently aligned, but height
104 if (level
+ 1 == pCreateInfo
->mipLevels
)
105 aligned_height
= align(aligned_height
, 32);
107 if (layout
== VK_FORMAT_LAYOUT_ASTC
)
109 util_align_npot(width
, pitchalign
* vk_format_get_blockwidth(format
));
111 slice
->pitch
= align(width
, pitchalign
);
113 slice
->offset
= layer_size
;
114 blocks
= vk_format_get_block_count(format
, slice
->pitch
, aligned_height
);
116 /* 1d array and 2d array textures must all have the same layer size
117 * for each miplevel on a6xx. 3d textures can have different layer
118 * sizes for high levels, but the hw auto-sizer is buggy (or at least
119 * different than what this code does), so as soon as the layer size
120 * range gets into range, we stop reducing it.
122 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
) {
123 if (level
< 1 || image
->levels
[level
- 1].size
> 0xf000) {
124 slice
->size
= align(blocks
* image
->cpp
, 4096);
126 slice
->size
= image
->levels
[level
- 1].size
;
129 slice
->size
= blocks
* image
->cpp
;
132 layer_size
+= slice
->size
* depth
;
135 image
->layer_size
= align(layer_size
, 4096);
139 tu_image_create(VkDevice _device
,
140 const struct tu_image_create_info
*create_info
,
141 const VkAllocationCallbacks
*alloc
,
144 TU_FROM_HANDLE(tu_device
, device
, _device
);
145 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
146 struct tu_image
*image
= NULL
;
147 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
149 tu_assert(pCreateInfo
->mipLevels
> 0);
150 tu_assert(pCreateInfo
->arrayLayers
> 0);
151 tu_assert(pCreateInfo
->samples
> 0);
152 tu_assert(pCreateInfo
->extent
.width
> 0);
153 tu_assert(pCreateInfo
->extent
.height
> 0);
154 tu_assert(pCreateInfo
->extent
.depth
> 0);
156 image
= vk_zalloc2(&device
->alloc
, alloc
, sizeof(*image
), 8,
157 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
159 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
161 image
->type
= pCreateInfo
->imageType
;
163 image
->vk_format
= pCreateInfo
->format
;
164 image
->tiling
= pCreateInfo
->tiling
;
165 image
->usage
= pCreateInfo
->usage
;
166 image
->flags
= pCreateInfo
->flags
;
167 image
->extent
= pCreateInfo
->extent
;
168 image
->level_count
= pCreateInfo
->mipLevels
;
169 image
->layer_count
= pCreateInfo
->arrayLayers
;
170 image
->samples
= pCreateInfo
->samples
;
171 image
->cpp
= vk_format_get_blocksize(image
->vk_format
) * image
->samples
;
173 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
174 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
175 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
176 if (pCreateInfo
->pQueueFamilyIndices
[i
] ==
177 VK_QUEUE_FAMILY_EXTERNAL
)
178 image
->queue_family_mask
|= (1u << TU_MAX_QUEUE_FAMILIES
) - 1u;
180 image
->queue_family_mask
|=
181 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
185 vk_find_struct_const(pCreateInfo
->pNext
,
186 EXTERNAL_MEMORY_IMAGE_CREATE_INFO
) != NULL
;
188 image
->tile_mode
= TILE6_LINEAR
;
189 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_OPTIMAL
&& !create_info
->scanout
)
190 image
->tile_mode
= TILE6_3
;
192 setup_slices(image
, pCreateInfo
);
194 image
->size
= image
->layer_size
* pCreateInfo
->arrayLayers
;
195 *pImage
= tu_image_to_handle(image
);
200 static enum a6xx_tex_fetchsize
201 tu6_fetchsize(VkFormat format
)
203 if (vk_format_description(format
)->layout
== VK_FORMAT_LAYOUT_ASTC
)
204 return TFETCH6_16_BYTE
;
206 switch (vk_format_get_blocksize(format
) / vk_format_get_blockwidth(format
)) {
207 case 1: return TFETCH6_1_BYTE
;
208 case 2: return TFETCH6_2_BYTE
;
209 case 4: return TFETCH6_4_BYTE
;
210 case 8: return TFETCH6_8_BYTE
;
211 case 16: return TFETCH6_16_BYTE
;
213 unreachable("bad block size");
218 tu6_texswiz(const VkComponentMapping
*comps
, const unsigned char *fmt_swiz
)
220 unsigned char swiz
[4] = {comps
->r
, comps
->g
, comps
->b
, comps
->a
};
221 unsigned char vk_swizzle
[] = {
222 [VK_COMPONENT_SWIZZLE_ZERO
] = A6XX_TEX_ZERO
,
223 [VK_COMPONENT_SWIZZLE_ONE
] = A6XX_TEX_ONE
,
224 [VK_COMPONENT_SWIZZLE_R
] = A6XX_TEX_X
,
225 [VK_COMPONENT_SWIZZLE_G
] = A6XX_TEX_Y
,
226 [VK_COMPONENT_SWIZZLE_B
] = A6XX_TEX_Z
,
227 [VK_COMPONENT_SWIZZLE_A
] = A6XX_TEX_W
,
229 for (unsigned i
= 0; i
< 4; i
++) {
230 swiz
[i
] = (swiz
[i
] == VK_COMPONENT_SWIZZLE_IDENTITY
) ? i
: vk_swizzle
[swiz
[i
]];
231 /* if format has 0/1 in channel, use that (needed for bc1_rgb) */
233 switch (fmt_swiz
[swiz
[i
]]) {
234 case VK_SWIZZLE_0
: swiz
[i
] = A6XX_TEX_ZERO
; break;
235 case VK_SWIZZLE_1
: swiz
[i
] = A6XX_TEX_ONE
; break;
240 return A6XX_TEX_CONST_0_SWIZ_X(swiz
[0]) |
241 A6XX_TEX_CONST_0_SWIZ_Y(swiz
[1]) |
242 A6XX_TEX_CONST_0_SWIZ_Z(swiz
[2]) |
243 A6XX_TEX_CONST_0_SWIZ_W(swiz
[3]);
246 static enum a6xx_tex_type
247 tu6_tex_type(VkImageViewType type
)
251 case VK_IMAGE_VIEW_TYPE_1D
:
252 case VK_IMAGE_VIEW_TYPE_1D_ARRAY
:
254 case VK_IMAGE_VIEW_TYPE_2D
:
255 case VK_IMAGE_VIEW_TYPE_2D_ARRAY
:
257 case VK_IMAGE_VIEW_TYPE_3D
:
259 case VK_IMAGE_VIEW_TYPE_CUBE
:
260 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
:
261 return A6XX_TEX_CUBE
;
266 tu_image_view_init(struct tu_image_view
*iview
,
267 struct tu_device
*device
,
268 const VkImageViewCreateInfo
*pCreateInfo
)
270 TU_FROM_HANDLE(tu_image
, image
, pCreateInfo
->image
);
271 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
273 switch (image
->type
) {
274 case VK_IMAGE_TYPE_1D
:
275 case VK_IMAGE_TYPE_2D
:
276 assert(range
->baseArrayLayer
+ tu_get_layerCount(image
, range
) <=
279 case VK_IMAGE_TYPE_3D
:
280 assert(range
->baseArrayLayer
+ tu_get_layerCount(image
, range
) <=
281 tu_minify(image
->extent
.depth
, range
->baseMipLevel
));
284 unreachable("bad VkImageType");
287 iview
->image
= image
;
288 iview
->type
= pCreateInfo
->viewType
;
289 iview
->vk_format
= pCreateInfo
->format
;
290 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
292 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
293 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
294 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
295 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
299 iview
->extent
= image
->extent
;
301 iview
->base_layer
= range
->baseArrayLayer
;
302 iview
->layer_count
= tu_get_layerCount(image
, range
);
303 iview
->base_mip
= range
->baseMipLevel
;
304 iview
->level_count
= tu_get_levelCount(image
, range
);
306 memset(iview
->descriptor
, 0, sizeof(iview
->descriptor
));
308 const struct tu_native_format
*fmt
= tu6_get_native_format(iview
->vk_format
);
309 struct tu_image_level
*slice0
= &image
->levels
[iview
->base_mip
];
310 uint64_t base_addr
= image
->bo
->iova
+ iview
->base_layer
* image
->layer_size
+ slice0
->offset
;
311 uint32_t pitch
= (slice0
->pitch
/ vk_format_get_blockwidth(iview
->vk_format
)) *
312 vk_format_get_blocksize(iview
->vk_format
);
313 enum a6xx_tile_mode tile_mode
=
314 image_level_linear(image
, iview
->base_mip
) ? TILE6_LINEAR
: image
->tile_mode
;
316 iview
->descriptor
[0] =
317 A6XX_TEX_CONST_0_TILE_MODE(tile_mode
) |
318 COND(vk_format_is_srgb(iview
->vk_format
), A6XX_TEX_CONST_0_SRGB
) |
319 A6XX_TEX_CONST_0_FMT(fmt
->tex
) |
320 A6XX_TEX_CONST_0_SAMPLES(0) |
321 A6XX_TEX_CONST_0_SWAP(image
->tile_mode
? WZYX
: fmt
->swap
) |
322 tu6_texswiz(&pCreateInfo
->components
, vk_format_description(iview
->vk_format
)->swizzle
) |
323 A6XX_TEX_CONST_0_MIPLVLS(iview
->level_count
- 1);
324 iview
->descriptor
[1] =
325 A6XX_TEX_CONST_1_WIDTH(u_minify(image
->extent
.width
, iview
->base_mip
)) |
326 A6XX_TEX_CONST_1_HEIGHT(u_minify(image
->extent
.height
, iview
->base_mip
));
327 iview
->descriptor
[2] =
328 A6XX_TEX_CONST_2_FETCHSIZE(tu6_fetchsize(iview
->vk_format
)) |
329 A6XX_TEX_CONST_2_PITCH(pitch
) |
330 A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo
->viewType
));
331 iview
->descriptor
[3] = 0;
332 iview
->descriptor
[4] = base_addr
;
333 iview
->descriptor
[5] = base_addr
>> 32;
335 if (pCreateInfo
->viewType
!= VK_IMAGE_VIEW_TYPE_3D
) {
336 iview
->descriptor
[3] |= A6XX_TEX_CONST_3_ARRAY_PITCH(image
->layer_size
);
337 iview
->descriptor
[5] |= A6XX_TEX_CONST_5_DEPTH(iview
->layer_count
);
339 iview
->descriptor
[3] |=
340 A6XX_TEX_CONST_3_MIN_LAYERSZ(image
->levels
[image
->level_count
- 1].size
) |
341 A6XX_TEX_CONST_3_ARRAY_PITCH(slice0
->size
);
342 iview
->descriptor
[5] |=
343 A6XX_TEX_CONST_5_DEPTH(u_minify(image
->extent
.depth
, iview
->base_mip
));
348 tu_image_queue_family_mask(const struct tu_image
*image
,
350 uint32_t queue_family
)
352 if (!image
->exclusive
)
353 return image
->queue_family_mask
;
354 if (family
== VK_QUEUE_FAMILY_EXTERNAL
)
355 return (1u << TU_MAX_QUEUE_FAMILIES
) - 1u;
356 if (family
== VK_QUEUE_FAMILY_IGNORED
)
357 return 1u << queue_family
;
362 tu_CreateImage(VkDevice device
,
363 const VkImageCreateInfo
*pCreateInfo
,
364 const VkAllocationCallbacks
*pAllocator
,
368 const VkNativeBufferANDROID
*gralloc_info
=
369 vk_find_struct_const(pCreateInfo
->pNext
, NATIVE_BUFFER_ANDROID
);
372 return tu_image_from_gralloc(device
, pCreateInfo
, gralloc_info
,
376 const struct wsi_image_create_info
*wsi_info
=
377 vk_find_struct_const(pCreateInfo
->pNext
, WSI_IMAGE_CREATE_INFO_MESA
);
378 bool scanout
= wsi_info
&& wsi_info
->scanout
;
380 return tu_image_create(device
,
381 &(struct tu_image_create_info
) {
382 .vk_info
= pCreateInfo
,
389 tu_DestroyImage(VkDevice _device
,
391 const VkAllocationCallbacks
*pAllocator
)
393 TU_FROM_HANDLE(tu_device
, device
, _device
);
394 TU_FROM_HANDLE(tu_image
, image
, _image
);
399 if (image
->owned_memory
!= VK_NULL_HANDLE
)
400 tu_FreeMemory(_device
, image
->owned_memory
, pAllocator
);
402 vk_free2(&device
->alloc
, pAllocator
, image
);
406 tu_GetImageSubresourceLayout(VkDevice _device
,
408 const VkImageSubresource
*pSubresource
,
409 VkSubresourceLayout
*pLayout
)
411 TU_FROM_HANDLE(tu_image
, image
, _image
);
413 const uint32_t layer_offset
= image
->layer_size
* pSubresource
->arrayLayer
;
414 const struct tu_image_level
*level
=
415 image
->levels
+ pSubresource
->mipLevel
;
417 pLayout
->offset
= layer_offset
+ level
->offset
;
418 pLayout
->size
= level
->size
;
420 level
->pitch
* vk_format_get_blocksize(image
->vk_format
);
421 pLayout
->arrayPitch
= image
->layer_size
;
422 pLayout
->depthPitch
= level
->size
;
426 tu_CreateImageView(VkDevice _device
,
427 const VkImageViewCreateInfo
*pCreateInfo
,
428 const VkAllocationCallbacks
*pAllocator
,
431 TU_FROM_HANDLE(tu_device
, device
, _device
);
432 struct tu_image_view
*view
;
434 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
435 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
437 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
439 tu_image_view_init(view
, device
, pCreateInfo
);
441 *pView
= tu_image_view_to_handle(view
);
447 tu_DestroyImageView(VkDevice _device
,
449 const VkAllocationCallbacks
*pAllocator
)
451 TU_FROM_HANDLE(tu_device
, device
, _device
);
452 TU_FROM_HANDLE(tu_image_view
, iview
, _iview
);
456 vk_free2(&device
->alloc
, pAllocator
, iview
);
460 tu_buffer_view_init(struct tu_buffer_view
*view
,
461 struct tu_device
*device
,
462 const VkBufferViewCreateInfo
*pCreateInfo
)
464 TU_FROM_HANDLE(tu_buffer
, buffer
, pCreateInfo
->buffer
);
466 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
467 ? buffer
->size
- pCreateInfo
->offset
468 : pCreateInfo
->range
;
469 view
->vk_format
= pCreateInfo
->format
;
473 tu_CreateBufferView(VkDevice _device
,
474 const VkBufferViewCreateInfo
*pCreateInfo
,
475 const VkAllocationCallbacks
*pAllocator
,
478 TU_FROM_HANDLE(tu_device
, device
, _device
);
479 struct tu_buffer_view
*view
;
481 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
482 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
484 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
486 tu_buffer_view_init(view
, device
, pCreateInfo
);
488 *pView
= tu_buffer_view_to_handle(view
);
494 tu_DestroyBufferView(VkDevice _device
,
495 VkBufferView bufferView
,
496 const VkAllocationCallbacks
*pAllocator
)
498 TU_FROM_HANDLE(tu_device
, device
, _device
);
499 TU_FROM_HANDLE(tu_buffer_view
, view
, bufferView
);
504 vk_free2(&device
->alloc
, pAllocator
, view
);