From 76125cb7afb1676b76e58601c747a81f661f470b Mon Sep 17 00:00:00 2001 From: squidbus <1249084-squidbus@users.noreply.gitlab.freedesktop.org> Date: Fri, 15 May 2026 18:06:36 -0700 Subject: [PATCH] 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 Part-of: --- src/kosmickrisp/bridge/mtl_device.m | 8 ++++---- src/kosmickrisp/vulkan/kk_buffer_view.c | 1 + src/kosmickrisp/vulkan/kk_image.c | 8 ++++---- src/kosmickrisp/vulkan/kk_image_layout.c | 14 +++++++++++++- src/kosmickrisp/vulkan/kk_image_layout.h | 9 +++++++++ 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/kosmickrisp/bridge/mtl_device.m b/src/kosmickrisp/bridge/mtl_device.m index ff6ccc35953..f1506b3c7e5 100644 --- a/src/kosmickrisp/bridge/mtl_device.m +++ b/src/kosmickrisp/bridge/mtl_device.m @@ -230,15 +230,15 @@ mtl_heap_texture_size_and_align_with_descriptor(mtl_device *device, { @autoreleasepool { id dev = (id)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]; } } } diff --git a/src/kosmickrisp/vulkan/kk_buffer_view.c b/src/kosmickrisp/vulkan/kk_buffer_view.c index dffb9aa8473..c67ac82ed15 100644 --- a/src/kosmickrisp/vulkan/kk_buffer_view.c +++ b/src/kosmickrisp/vulkan/kk_buffer_view.c @@ -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}, diff --git a/src/kosmickrisp/vulkan/kk_image.c b/src/kosmickrisp/vulkan/kk_image.c index e8c6379f0f7..08bab315697 100644 --- a/src/kosmickrisp/vulkan/kk_image.c +++ b/src/kosmickrisp/vulkan/kk_image.c @@ -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 diff --git a/src/kosmickrisp/vulkan/kk_image_layout.c b/src/kosmickrisp/vulkan/kk_image_layout.c index 5f0ce81a736..2c71eb009bc 100644 --- a/src/kosmickrisp/vulkan/kk_image_layout.c +++ b/src/kosmickrisp/vulkan/kk_image_layout.c @@ -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; diff --git a/src/kosmickrisp/vulkan/kk_image_layout.h b/src/kosmickrisp/vulkan/kk_image_layout.h index 706a9a109ca..c32fe791829 100644 --- a/src/kosmickrisp/vulkan/kk_image_layout.h +++ b/src/kosmickrisp/vulkan/kk_image_layout.h @@ -14,6 +14,8 @@ #include "vk_image.h" +#include + #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,