[Mesa-dev] [PATCH crucible 3/3] Handle pitch != width with linear images in miptree tests.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Wed Mar 7 21:50:52 UTC 2018


From: Bas Nieuwenhuizen <basni at chromium.org>

We basically split the loop so we create the images before
allocation, as well pass on the pitch to the cru_images for
the comparison.
---
 src/tests/func/miptree/miptree.c | 181 ++++++++++++++++++++++++++++-----------
 1 file changed, 130 insertions(+), 51 deletions(-)

diff --git a/src/tests/func/miptree/miptree.c b/src/tests/func/miptree/miptree.c
index b9a73c5..0fe989e 100644
--- a/src/tests/func/miptree/miptree.c
+++ b/src/tests/func/miptree/miptree.c
@@ -114,7 +114,8 @@ struct mipslice {
     uint32_t height;
     uint32_t depth;
 
-    uint32_t buffer_offset;
+    uint32_t src_buffer_offset;
+    uint32_t dst_buffer_offset;
 
     VkImage src_vk_image;
     VkImage dest_vk_image;
@@ -505,42 +506,14 @@ miptree_create(void)
         },
         .tiling = VK_IMAGE_TILING_OPTIMAL,
         .usage = usage_bits);
-    VkBuffer src_buffer = qoCreateBuffer(t_device,
-        .size = buffer_size,
-        .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
-    VkBuffer dest_buffer = qoCreateBuffer(t_device,
-        .size = buffer_size,
-        .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
-
-    VkDeviceMemory image_mem = qoAllocImageMemory(t_device, image,
-        .properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-    VkDeviceMemory src_buffer_mem = qoAllocBufferMemory(t_device, src_buffer,
-        .properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-    VkDeviceMemory dest_buffer_mem = qoAllocBufferMemory(t_device, dest_buffer,
-        .properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
-    void *src_buffer_map = qoMapMemory(t_device, src_buffer_mem,
-                                       /*offset*/ 0, buffer_size, 0);
-    void *dest_buffer_map = qoMapMemory(t_device, dest_buffer_mem,
-                                        /*offset*/ 0, buffer_size, 0);
 
-    qoBindImageMemory(t_device, image, image_mem, /*offset*/ 0);
-    qoBindBufferMemory(t_device, src_buffer, src_buffer_mem, /*offset*/ 0);
-    qoBindBufferMemory(t_device, dest_buffer, dest_buffer_mem, /*offset*/ 0);
-
-    miptree_t *mt = xzalloc(sizeof(*mt));
-    t_cleanup_push_callback((cru_cleanup_callback_func_t) miptree_destroy, mt);
-
-    mt->image = image;
-    mt->src_buffer = src_buffer;
-    mt->dest_buffer = dest_buffer;
-    mt->width = width;
-    mt->height = height;
-    mt->levels = levels;
-    mt->array_length = array_length;
-    cru_vec_init(&mt->mipslices);
-
-    uint32_t buffer_offset = 0;
+    uint32_t src_buffer_offset = 0;
+    uint32_t dst_buffer_offset = 0;
+    VkImage src_images[levels * MAX(depth, array_length)];
+    VkImage dst_images[levels * MAX(depth, array_length)];
+    uint32_t src_buffer_offsets[levels * MAX(depth, array_length)];
+    uint32_t dst_buffer_offsets[levels * MAX(depth, array_length)];
+    unsigned image_idx = 0;
 
     for (uint32_t l = 0; l < levels; ++l) {
         const uint32_t level_width = cru_minify(width, l);
@@ -553,9 +526,6 @@ miptree_create(void)
         const uint32_t num_layers = MAX(level_depth, array_length);
 
         for (uint32_t layer = 0; layer < num_layers; ++layer) {
-            void *src_pixels = src_buffer_map + buffer_offset;
-            void *dest_pixels = dest_buffer_map + buffer_offset;
-
             uint32_t src_usage, dest_usage;
             VkFormat dest_format;
             VkImage src_vk_image;
@@ -593,8 +563,6 @@ miptree_create(void)
                     },
                     .tiling = VK_IMAGE_TILING_LINEAR,
                     .usage = src_usage);
-                qoBindImageMemory(t_device, src_vk_image, src_buffer_mem,
-                                  buffer_offset);
                 break;
             }
 
@@ -632,11 +600,121 @@ miptree_create(void)
                     },
                     .tiling = VK_IMAGE_TILING_LINEAR,
                     .usage = dest_usage);
-                qoBindImageMemory(t_device, dest_vk_image, dest_buffer_mem,
-                                  buffer_offset);
                 break;
             }
 
+            if (src_vk_image) {
+                VkMemoryRequirements requirements;
+                requirements = qoGetImageMemoryRequirements(t_device, src_vk_image);
+                src_buffer_offset = (src_buffer_offset + requirements.alignment - 1) / requirements.alignment * requirements.alignment;
+                src_buffer_offsets[image_idx] = src_buffer_offset;
+                src_buffer_offset += requirements.size;
+            } else {
+                src_buffer_offsets[image_idx] = src_buffer_offset;
+                src_buffer_offset += cpp * level_width * level_height;
+            }
+
+            if (dest_vk_image) {
+                VkMemoryRequirements requirements;
+                requirements = qoGetImageMemoryRequirements(t_device, dest_vk_image);
+                dst_buffer_offset = (dst_buffer_offset + requirements.alignment - 1) / requirements.alignment * requirements.alignment;
+                dst_buffer_offsets[image_idx] = dst_buffer_offset;
+                dst_buffer_offset += requirements.size;
+            } else {
+                dst_buffer_offsets[image_idx] = dst_buffer_offset;
+                dst_buffer_offset += cpp * level_width * level_height;
+            }
+
+            src_images[image_idx] = src_vk_image;
+            dst_images[image_idx] = dest_vk_image;
+            ++image_idx;
+        }
+    }
+
+    const uint32_t src_buffer_size = MAX(buffer_size, src_buffer_offset);
+    const uint32_t dst_buffer_size = MAX(buffer_size, dst_buffer_offset);
+
+    VkBuffer src_buffer = qoCreateBuffer(t_device,
+        .size = src_buffer_size,
+        .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+    VkBuffer dest_buffer = qoCreateBuffer(t_device,
+        .size = dst_buffer_size,
+        .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+
+    /* TODO: make sure these are allowed in the image memory requirements. */
+    VkDeviceMemory image_mem = qoAllocImageMemory(t_device, image,
+        .properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+    VkDeviceMemory src_buffer_mem = qoAllocBufferMemory(t_device, src_buffer,
+        .properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+    VkDeviceMemory dest_buffer_mem = qoAllocBufferMemory(t_device, dest_buffer,
+        .properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+
+    void *src_buffer_map = qoMapMemory(t_device, src_buffer_mem,
+                                       /*offset*/ 0, buffer_size, 0);
+    void *dest_buffer_map = qoMapMemory(t_device, dest_buffer_mem,
+                                        /*offset*/ 0, buffer_size, 0);
+
+    qoBindImageMemory(t_device, image, image_mem, /*offset*/ 0);
+    qoBindBufferMemory(t_device, src_buffer, src_buffer_mem, /*offset*/ 0);
+    qoBindBufferMemory(t_device, dest_buffer, dest_buffer_mem, /*offset*/ 0);
+
+    miptree_t *mt = xzalloc(sizeof(*mt));
+    t_cleanup_push_callback((cru_cleanup_callback_func_t) miptree_destroy, mt);
+
+    mt->image = image;
+    mt->src_buffer = src_buffer;
+    mt->dest_buffer = dest_buffer;
+    mt->width = width;
+    mt->height = height;
+    mt->levels = levels;
+    mt->array_length = array_length;
+    cru_vec_init(&mt->mipslices);
+
+    image_idx = 0;
+
+    for (uint32_t l = 0; l < levels; ++l) {
+        const uint32_t level_width = cru_minify(width, l);
+        const uint32_t level_height = cru_minify(height, l);
+        const uint32_t level_depth = cru_minify(depth, l);
+
+        // 3D array textures are illegal.
+        t_assert(level_depth == 1 || array_length == 1);
+
+        const uint32_t num_layers = MAX(level_depth, array_length);
+
+        for (uint32_t layer = 0; layer < num_layers; ++layer) {
+            const VkImage src_vk_image = src_images[image_idx];
+            const VkImage dest_vk_image = dst_images[image_idx];
+            uint32_t src_offset = src_buffer_offsets[image_idx];
+            uint32_t dst_offset = dst_buffer_offsets[image_idx];
+            uint32_t src_stride = 0, dst_stride = 0;
+            const VkImageSubresource subresource = (VkImageSubresource){
+                .aspectMask = params->aspect,
+                .mipLevel = 0,
+                .arrayLayer = 0,
+            };
+
+            if (src_vk_image) {
+                qoBindImageMemory(t_device, src_vk_image, src_buffer_mem,
+                                  src_buffer_offsets[image_idx]);
+
+                VkSubresourceLayout layout = qoGetImageSubresourceLayout(t_device, src_vk_image, &subresource);
+                src_offset += layout.offset;
+                src_stride = layout.rowPitch;
+            }
+
+            if (dest_vk_image) {
+                qoBindImageMemory(t_device, dest_vk_image, dest_buffer_mem,
+                                  dst_buffer_offsets[image_idx]);
+
+                VkSubresourceLayout layout = qoGetImageSubresourceLayout(t_device, dest_vk_image, &subresource);
+                dst_offset += layout.offset;
+                dst_stride = layout.rowPitch;
+            }
+
+            void *src_pixels = src_buffer_map + src_offset;
+            void *dest_pixels = dest_buffer_map + dst_offset;
+
             cru_image_t *templ_image;
             cru_image_t *src_image;
             cru_image_t *dest_image;
@@ -648,16 +726,16 @@ miptree_create(void)
             t_assert(level_width == cru_image_get_width(templ_image));
             t_assert(level_height == cru_image_get_height(templ_image));
 
-            src_image = t_new_cru_image_from_pixels(src_pixels,
-                    format, level_width, level_height);
+            src_image = t_new_cru_image_from_pixels_with_stride(src_pixels,
+                    format, level_width, level_height, src_stride);
             t_assert(cru_image_copy(src_image, templ_image));
             mipslice_perturb_pixels(src_pixels, format_info,
                                     level_width, level_height,
                                     l, levels,
                                     layer, num_layers);
 
-            dest_image = t_new_cru_image_from_pixels(dest_pixels,
-                    format, level_width, level_height);
+            dest_image = t_new_cru_image_from_pixels_with_stride(dest_pixels,
+                    format, level_width, level_height, dst_stride);
             fill_rect_with_canary(dest_pixels, format_info,
                                   level_width, level_height);
 
@@ -678,7 +756,8 @@ miptree_create(void)
                 .height = level_height,
                 .depth = level_depth,
 
-                .buffer_offset = buffer_offset,
+                .src_buffer_offset = src_offset,
+                .dst_buffer_offset = dst_offset,
 
                 .src_vk_image = src_vk_image,
                 .dest_vk_image = dest_vk_image,
@@ -689,7 +768,7 @@ miptree_create(void)
 
             cru_vec_push_memcpy(&mt->mipslices, &mipslice, 1);
 
-            buffer_offset += cpp * level_width * level_height;
+            ++image_idx;
         }
     }
 
@@ -726,7 +805,7 @@ miptree_upload_copy_from_buffer(const test_data_t *data)
 			 });
     cru_vec_foreach(slice, &mt->mipslices) {
         VkBufferImageCopy copy = {
-            .bufferOffset = slice->buffer_offset,
+            .bufferOffset = slice->src_buffer_offset,
             .imageSubresource = {
                 .aspectMask = params->aspect,
                 .mipLevel = slice->level,
@@ -765,7 +844,7 @@ miptree_download_copy_to_buffer(const test_data_t *data)
 
     cru_vec_foreach(slice, &mt->mipslices) {
         VkBufferImageCopy copy = {
-            .bufferOffset = slice->buffer_offset,
+            .bufferOffset = slice->dst_buffer_offset,
             .imageSubresource = {
                 .aspectMask = params->aspect,
                 .mipLevel = slice->level,
-- 
2.16.1



More information about the mesa-dev mailing list