[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