kk: Separate linear and GPU optimized image layout properties

`linear` controls whether the created image is in linear layout, and
`optimized_layout` controls only the `allowGPUOptimizedContents`
Metal property.

Reviewed-by: Aitor Camacho <aitor@lunarg.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41714>
This commit is contained in:
squidbus 2026-05-15 18:06:36 -07:00
parent 8cc3ca6231
commit 76125cb7af
5 changed files with 31 additions and 9 deletions

View file

@ -230,15 +230,15 @@ mtl_heap_texture_size_and_align_with_descriptor(mtl_device *device,
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
if (layout->optimized_layout) {
if (layout->linear) {
/* Linear textures have different alignment since they are allocated on top of MTLBuffers */
layout->align_B = [dev minimumLinearTextureAlignmentForPixelFormat:layout->format.mtl];
} else {
MTLTextureDescriptor *descriptor = [mtl_new_texture_descriptor(layout) autorelease];
descriptor.resourceOptions = KK_MTL_RESOURCE_OPTIONS;
MTLSizeAndAlign size_align = [dev heapTextureSizeAndAlignWithDescriptor:descriptor];
layout->size_B = size_align.size;
layout->align_B = size_align.align;
} else {
/* Linear textures have different alignment since they are allocated on top of MTLBuffers */
layout->align_B = [dev minimumLinearTextureAlignmentForPixelFormat:layout->format.mtl];
}
}
}

View file

@ -84,6 +84,7 @@ kk_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo,
.type = MTL_TEXTURE_TYPE_TEXTURE_BUFFER,
.sample_count_sa = 1u,
.levels = 1u,
.linear = true,
.optimized_layout = false,
.usage = usage,
.format = {.pipe = p_format, .mtl = supported_format->mtl_pixel_format},

View file

@ -819,12 +819,12 @@ kk_image_plane_bind(struct kk_device *dev, struct kk_image *image,
*offset_B = align64(*offset_B, plane_align_B);
/* Linear textures in Metal need to be allocated through a buffer... */
if (plane->layout.optimized_layout)
plane->mtl_handle = mtl_new_texture_with_descriptor(
mem->bo->mtl_handle, &plane->layout, *offset_B);
else
if (plane->layout.linear)
plane->mtl_handle = mtl_new_texture_with_descriptor_linear(
mem->bo->map, &plane->layout, *offset_B);
else
plane->mtl_handle = mtl_new_texture_with_descriptor(
mem->bo->mtl_handle, &plane->layout, *offset_B);
plane->addr = mem->bo->gpu + *offset_B;
/* Create auxiliary 2D array texture for 3D images so we can use 2D views of

View file

@ -76,6 +76,16 @@ vk_image_usage_flags_to_mtl_texture_usage(VkImageUsageFlags usage_flags,
return usage;
}
bool
kk_image_layout_can_optimize(VkImageUsageFlags usage, VkImageTiling tiling)
{
/* Can only optimize if tiling is optimal */
if (tiling != VK_IMAGE_TILING_OPTIMAL)
return false;
return true;
}
void
kk_image_layout_init(const struct kk_device *dev,
const struct vk_image *image,
@ -89,7 +99,9 @@ kk_image_layout_init(const struct kk_device *dev,
layout->depth_px = image->extent.depth;
layout->layers = image->array_layers;
layout->levels = image->mip_levels;
layout->optimized_layout = image->tiling == VK_IMAGE_TILING_OPTIMAL;
layout->linear = image->tiling != VK_IMAGE_TILING_OPTIMAL;
layout->optimized_layout = kk_image_layout_can_optimize(
image->usage, image->tiling);
layout->usage = vk_image_usage_flags_to_mtl_texture_usage(
image->usage, image->create_flags, supported_format->atomic);
layout->format.pipe = format;

View file

@ -14,6 +14,8 @@
#include "vk_image.h"
#include <stdbool.h>
#define KK_MAX_MIP_LEVELS 16
struct kk_device;
@ -32,6 +34,10 @@ struct kk_image_layout {
/** Number of miplevels. 1 if no mipmapping is used. */
uint8_t levels;
/** Whether the image has linear tiling */
uint8_t linear;
/** Whether to allow Metal to optimize image contents for the GPU */
uint8_t optimized_layout;
enum mtl_texture_usage usage;
@ -131,6 +137,9 @@ struct kk_view_layout {
uint16_t min_lod_clamp;
};
bool kk_image_layout_can_optimize(VkImageUsageFlags usage,
VkImageTiling tiling);
void kk_image_layout_init(const struct kk_device *dev,
const struct vk_image *image,
enum pipe_format format, const uint8_t width_scale,