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
);
47 } tile_alignment
[] = {
48 [1] = { 128, 32 }, [2] = { 128, 16 }, [3] = { 128, 16 }, [4] = { 64, 16 },
49 [8] = { 64, 16 }, [12] = { 64, 16 }, [16] = { 64, 16 },
53 setup_slices(struct tu_image
*image
, const VkImageCreateInfo
*pCreateInfo
)
55 enum vk_format_layout layout
=
56 vk_format_description(pCreateInfo
->format
)->layout
;
57 uint32_t layer_size
= 0;
58 uint32_t width
= pCreateInfo
->extent
.width
;
59 uint32_t height
= pCreateInfo
->extent
.height
;
60 uint32_t depth
= pCreateInfo
->extent
.depth
;
61 bool layer_first
= pCreateInfo
->imageType
!= VK_IMAGE_TYPE_3D
;
62 uint32_t alignment
= pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
? 4096 : 1;
63 uint32_t cpp
= vk_format_get_blocksize(pCreateInfo
->format
);
65 uint32_t heightalign
= tile_alignment
[cpp
].heightalign
;
67 for (unsigned level
= 0; level
< pCreateInfo
->mipLevels
; level
++) {
68 struct tu_image_level
*slice
= &image
->levels
[level
];
69 bool linear_level
= image_level_linear(image
, level
);
70 uint32_t aligned_height
= height
;
74 if (image
->tile_mode
&& !linear_level
) {
75 pitchalign
= tile_alignment
[cpp
].pitchalign
;
76 aligned_height
= align(aligned_height
, heightalign
);
80 /* The blits used for mem<->gmem work at a granularity of
81 * 32x32, which can cause faults due to over-fetch on the
82 * last level. The simple solution is to over-allocate a
83 * bit the last level to ensure any over-fetch is harmless.
84 * The pitch is already sufficiently aligned, but height
87 if ((level
+ 1 == pCreateInfo
->mipLevels
))
88 aligned_height
= align(aligned_height
, 32);
91 if (layout
== VK_FORMAT_LAYOUT_ASTC
)
92 slice
->pitch
= util_align_npot(
94 pitchalign
* vk_format_get_blockwidth(pCreateInfo
->format
));
96 slice
->pitch
= align(width
, pitchalign
);
98 slice
->offset
= layer_size
;
99 blocks
= vk_format_get_block_count(pCreateInfo
->format
, slice
->pitch
,
102 /* 1d array and 2d array textures must all have the same layer size
103 * for each miplevel on a3xx. 3d textures can have different layer
104 * sizes for high levels, but the hw auto-sizer is buggy (or at least
105 * different than what this code does), so as soon as the layer size
106 * range gets into range, we stop reducing it.
108 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
&&
110 (level
> 1 && image
->levels
[level
- 1].size
> 0xf000)))
111 slice
->size
= align(blocks
* cpp
, alignment
);
112 else if (level
== 0 || layer_first
|| alignment
== 1)
113 slice
->size
= align(blocks
* cpp
, alignment
);
115 slice
->size
= image
->levels
[level
- 1].size
;
117 layer_size
+= slice
->size
* depth
;
119 width
= u_minify(width
, 1);
120 height
= u_minify(height
, 1);
121 depth
= u_minify(depth
, 1);
124 image
->layer_size
= layer_size
;
128 tu_image_create(VkDevice _device
,
129 const struct tu_image_create_info
*create_info
,
130 const VkAllocationCallbacks
*alloc
,
133 TU_FROM_HANDLE(tu_device
, device
, _device
);
134 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
135 struct tu_image
*image
= NULL
;
136 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
138 tu_assert(pCreateInfo
->mipLevels
> 0);
139 tu_assert(pCreateInfo
->arrayLayers
> 0);
140 tu_assert(pCreateInfo
->samples
> 0);
141 tu_assert(pCreateInfo
->extent
.width
> 0);
142 tu_assert(pCreateInfo
->extent
.height
> 0);
143 tu_assert(pCreateInfo
->extent
.depth
> 0);
145 image
= vk_zalloc2(&device
->alloc
, alloc
, sizeof(*image
), 8,
146 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
148 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
150 image
->type
= pCreateInfo
->imageType
;
152 image
->vk_format
= pCreateInfo
->format
;
153 image
->tiling
= pCreateInfo
->tiling
;
154 image
->usage
= pCreateInfo
->usage
;
155 image
->flags
= pCreateInfo
->flags
;
156 image
->extent
= pCreateInfo
->extent
;
157 image
->level_count
= pCreateInfo
->mipLevels
;
158 image
->layer_count
= pCreateInfo
->arrayLayers
;
160 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
161 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
162 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
163 if (pCreateInfo
->pQueueFamilyIndices
[i
] ==
164 VK_QUEUE_FAMILY_EXTERNAL
)
165 image
->queue_family_mask
|= (1u << TU_MAX_QUEUE_FAMILIES
) - 1u;
167 image
->queue_family_mask
|=
168 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
172 vk_find_struct_const(pCreateInfo
->pNext
,
173 EXTERNAL_MEMORY_IMAGE_CREATE_INFO
) != NULL
;
175 image
->tile_mode
= TILE6_LINEAR
;
176 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_OPTIMAL
&& !create_info
->scanout
)
177 image
->tile_mode
= TILE6_3
;
179 setup_slices(image
, pCreateInfo
);
181 image
->size
= image
->layer_size
* pCreateInfo
->arrayLayers
;
182 *pImage
= tu_image_to_handle(image
);
187 static enum a6xx_tex_fetchsize
188 translate_fetchsize(uint32_t cpp
)
191 case 1: return TFETCH6_1_BYTE
;
192 case 2: return TFETCH6_2_BYTE
;
193 case 4: return TFETCH6_4_BYTE
;
194 case 8: return TFETCH6_8_BYTE
;
195 case 16: return TFETCH6_16_BYTE
;
197 unreachable("bad block size");
201 static enum a6xx_tex_swiz
202 translate_swiz(VkComponentSwizzle swiz
, enum a6xx_tex_swiz ident
)
206 case VK_COMPONENT_SWIZZLE_IDENTITY
: return ident
;
207 case VK_COMPONENT_SWIZZLE_R
: return A6XX_TEX_X
;
208 case VK_COMPONENT_SWIZZLE_G
: return A6XX_TEX_Y
;
209 case VK_COMPONENT_SWIZZLE_B
: return A6XX_TEX_Z
;
210 case VK_COMPONENT_SWIZZLE_A
: return A6XX_TEX_W
;
211 case VK_COMPONENT_SWIZZLE_ZERO
: return A6XX_TEX_ZERO
;
212 case VK_COMPONENT_SWIZZLE_ONE
: return A6XX_TEX_ONE
;
216 static enum a6xx_tex_type
217 translate_tex_type(VkImageViewType type
)
221 case VK_IMAGE_VIEW_TYPE_1D
:
222 case VK_IMAGE_VIEW_TYPE_1D_ARRAY
:
224 case VK_IMAGE_VIEW_TYPE_2D
:
225 case VK_IMAGE_VIEW_TYPE_2D_ARRAY
:
227 case VK_IMAGE_VIEW_TYPE_3D
:
229 case VK_IMAGE_VIEW_TYPE_CUBE
:
230 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
:
231 return A6XX_TEX_CUBE
;
236 tu_image_view_init(struct tu_image_view
*iview
,
237 struct tu_device
*device
,
238 const VkImageViewCreateInfo
*pCreateInfo
)
240 TU_FROM_HANDLE(tu_image
, image
, pCreateInfo
->image
);
241 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
243 switch (image
->type
) {
244 case VK_IMAGE_TYPE_1D
:
245 case VK_IMAGE_TYPE_2D
:
246 assert(range
->baseArrayLayer
+ tu_get_layerCount(image
, range
) <=
249 case VK_IMAGE_TYPE_3D
:
250 assert(range
->baseArrayLayer
+ tu_get_layerCount(image
, range
) <=
251 tu_minify(image
->extent
.depth
, range
->baseMipLevel
));
254 unreachable("bad VkImageType");
257 iview
->image
= image
;
258 iview
->type
= pCreateInfo
->viewType
;
259 iview
->vk_format
= pCreateInfo
->format
;
260 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
262 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
263 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
264 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
265 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
269 iview
->extent
= image
->extent
;
271 iview
->base_layer
= range
->baseArrayLayer
;
272 iview
->layer_count
= tu_get_layerCount(image
, range
);
273 iview
->base_mip
= range
->baseMipLevel
;
274 iview
->level_count
= tu_get_levelCount(image
, range
);
276 memset(iview
->descriptor
, 0, sizeof(iview
->descriptor
));
278 const struct tu_native_format
*fmt
= tu6_get_native_format(iview
->vk_format
);
279 assert(fmt
&& fmt
->tex
>= 0);
281 struct tu_image_level
*slice0
= &image
->levels
[iview
->base_mip
];
282 uint32_t cpp
= vk_format_get_blocksize(iview
->vk_format
);
283 uint32_t block_width
= vk_format_get_blockwidth(iview
->vk_format
);
284 const VkComponentMapping
*comps
= &pCreateInfo
->components
;
286 iview
->descriptor
[0] =
287 A6XX_TEX_CONST_0_TILE_MODE(image
->tile_mode
) |
288 COND(vk_format_is_srgb(iview
->vk_format
), A6XX_TEX_CONST_0_SRGB
) |
289 A6XX_TEX_CONST_0_FMT(fmt
->tex
) |
290 A6XX_TEX_CONST_0_SAMPLES(0) |
291 A6XX_TEX_CONST_0_SWAP(fmt
->swap
) |
292 A6XX_TEX_CONST_0_SWIZ_X(translate_swiz(comps
->r
, A6XX_TEX_X
)) |
293 A6XX_TEX_CONST_0_SWIZ_Y(translate_swiz(comps
->g
, A6XX_TEX_Y
)) |
294 A6XX_TEX_CONST_0_SWIZ_Z(translate_swiz(comps
->b
, A6XX_TEX_Z
)) |
295 A6XX_TEX_CONST_0_SWIZ_W(translate_swiz(comps
->a
, A6XX_TEX_W
)) |
296 A6XX_TEX_CONST_0_MIPLVLS(iview
->level_count
- 1);
297 iview
->descriptor
[1] =
298 A6XX_TEX_CONST_1_WIDTH(u_minify(image
->extent
.width
, iview
->base_mip
)) |
299 A6XX_TEX_CONST_1_HEIGHT(u_minify(image
->extent
.height
, iview
->base_mip
));
300 iview
->descriptor
[2] =
301 A6XX_TEX_CONST_2_FETCHSIZE(translate_fetchsize(cpp
)) |
302 A6XX_TEX_CONST_2_PITCH(slice0
->pitch
/ block_width
* cpp
) |
303 A6XX_TEX_CONST_2_TYPE(translate_tex_type(pCreateInfo
->viewType
));
304 if (pCreateInfo
->viewType
!= VK_IMAGE_VIEW_TYPE_3D
) {
305 iview
->descriptor
[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(image
->layer_size
);
307 iview
->descriptor
[3] =
308 A6XX_TEX_CONST_3_MIN_LAYERSZ(image
->levels
[image
->level_count
- 1].size
) |
309 A6XX_TEX_CONST_3_ARRAY_PITCH(slice0
->size
);
311 uint64_t base_addr
= image
->bo
->iova
+ iview
->base_layer
* image
->layer_size
+ slice0
->offset
;
312 iview
->descriptor
[4] = base_addr
;
313 iview
->descriptor
[5] = base_addr
>> 32 | A6XX_TEX_CONST_5_DEPTH(iview
->layer_count
);
317 tu_image_queue_family_mask(const struct tu_image
*image
,
319 uint32_t queue_family
)
321 if (!image
->exclusive
)
322 return image
->queue_family_mask
;
323 if (family
== VK_QUEUE_FAMILY_EXTERNAL
)
324 return (1u << TU_MAX_QUEUE_FAMILIES
) - 1u;
325 if (family
== VK_QUEUE_FAMILY_IGNORED
)
326 return 1u << queue_family
;
331 tu_CreateImage(VkDevice device
,
332 const VkImageCreateInfo
*pCreateInfo
,
333 const VkAllocationCallbacks
*pAllocator
,
337 const VkNativeBufferANDROID
*gralloc_info
=
338 vk_find_struct_const(pCreateInfo
->pNext
, NATIVE_BUFFER_ANDROID
);
341 return tu_image_from_gralloc(device
, pCreateInfo
, gralloc_info
,
345 const struct wsi_image_create_info
*wsi_info
=
346 vk_find_struct_const(pCreateInfo
->pNext
, WSI_IMAGE_CREATE_INFO_MESA
);
347 bool scanout
= wsi_info
&& wsi_info
->scanout
;
349 return tu_image_create(device
,
350 &(struct tu_image_create_info
) {
351 .vk_info
= pCreateInfo
,
358 tu_DestroyImage(VkDevice _device
,
360 const VkAllocationCallbacks
*pAllocator
)
362 TU_FROM_HANDLE(tu_device
, device
, _device
);
363 TU_FROM_HANDLE(tu_image
, image
, _image
);
368 if (image
->owned_memory
!= VK_NULL_HANDLE
)
369 tu_FreeMemory(_device
, image
->owned_memory
, pAllocator
);
371 vk_free2(&device
->alloc
, pAllocator
, image
);
375 tu_GetImageSubresourceLayout(VkDevice _device
,
377 const VkImageSubresource
*pSubresource
,
378 VkSubresourceLayout
*pLayout
)
380 TU_FROM_HANDLE(tu_image
, image
, _image
);
382 const uint32_t layer_offset
= image
->layer_size
* pSubresource
->arrayLayer
;
383 const struct tu_image_level
*level
=
384 image
->levels
+ pSubresource
->mipLevel
;
386 pLayout
->offset
= layer_offset
+ level
->offset
;
387 pLayout
->size
= level
->size
;
389 level
->pitch
* vk_format_get_blocksize(image
->vk_format
);
390 pLayout
->arrayPitch
= image
->layer_size
;
391 pLayout
->depthPitch
= level
->size
;
395 tu_CreateImageView(VkDevice _device
,
396 const VkImageViewCreateInfo
*pCreateInfo
,
397 const VkAllocationCallbacks
*pAllocator
,
400 TU_FROM_HANDLE(tu_device
, device
, _device
);
401 struct tu_image_view
*view
;
403 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
404 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
406 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
408 tu_image_view_init(view
, device
, pCreateInfo
);
410 *pView
= tu_image_view_to_handle(view
);
416 tu_DestroyImageView(VkDevice _device
,
418 const VkAllocationCallbacks
*pAllocator
)
420 TU_FROM_HANDLE(tu_device
, device
, _device
);
421 TU_FROM_HANDLE(tu_image_view
, iview
, _iview
);
425 vk_free2(&device
->alloc
, pAllocator
, iview
);
429 tu_buffer_view_init(struct tu_buffer_view
*view
,
430 struct tu_device
*device
,
431 const VkBufferViewCreateInfo
*pCreateInfo
)
433 TU_FROM_HANDLE(tu_buffer
, buffer
, pCreateInfo
->buffer
);
435 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
436 ? buffer
->size
- pCreateInfo
->offset
437 : pCreateInfo
->range
;
438 view
->vk_format
= pCreateInfo
->format
;
442 tu_CreateBufferView(VkDevice _device
,
443 const VkBufferViewCreateInfo
*pCreateInfo
,
444 const VkAllocationCallbacks
*pAllocator
,
447 TU_FROM_HANDLE(tu_device
, device
, _device
);
448 struct tu_buffer_view
*view
;
450 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
451 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
453 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
455 tu_buffer_view_init(view
, device
, pCreateInfo
);
457 *pView
= tu_buffer_view_to_handle(view
);
463 tu_DestroyBufferView(VkDevice _device
,
464 VkBufferView bufferView
,
465 const VkAllocationCallbacks
*pAllocator
)
467 TU_FROM_HANDLE(tu_device
, device
, _device
);
468 TU_FROM_HANDLE(tu_buffer_view
, view
, bufferView
);
473 vk_free2(&device
->alloc
, pAllocator
, view
);