From: Bas Nieuwenhuizen <ba...@chromium.org> In vulkan linear images can have a stride that is larger than the width, which impacts the utility functions from cru_image. --- include/tapi/t_image.h | 12 ++++++++++++ include/util/cru_image.h | 8 ++++++++ src/framework/test/t_image.c | 15 +++++++++++++++ src/util/cru_image.c | 22 ++++++++-------------- src/util/cru_image.h | 5 ++++- src/util/cru_pixel_image.c | 30 +++++++++++++++++++++++++++++- src/util/cru_png_image.c | 9 +++------ src/util/cru_vk_image.c | 2 +- 8 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/include/tapi/t_image.h b/include/tapi/t_image.h index 77a6ed6..71a22d4 100644 --- a/include/tapi/t_image.h +++ b/include/tapi/t_image.h @@ -64,3 +64,15 @@ t_new_cru_image_from_vk_image(VkDevice dev, VkQueue queue, VkImage image, malloclike cru_image_t * t_new_cru_image_from_pixels(void *restrict pixels, VkFormat format, uint32_t width, uint32_t height); + +/// \brief Create a Crucible image from an array of pixels. +/// +/// This is a wrapper around cru_image_from_pixels_with_stride(). On success, +/// the new image is pushed onto the test thread's cleanup stack. On failure, +/// the test fails. +/// +/// \see cru_image_from_from_pixels_with_stride() +malloclike cru_image_t * +t_new_cru_image_from_pixels_with_stride(void *restrict pixels, VkFormat format, + uint32_t width, uint32_t height, + uint32_t stride); diff --git a/include/util/cru_image.h b/include/util/cru_image.h index 48db399..ef63008 100644 --- a/include/util/cru_image.h +++ b/include/util/cru_image.h @@ -66,6 +66,14 @@ malloclike cru_image_t * cru_image_from_pixels(void *restrict pixels, VkFormat format, uint32_t width, uint32_t height); +/// \brief Create a Crucible image from an array of pixels. +/// +/// If writing a test, consider using t_new_cru_image_from_pixels_with_stride(), +/// which has a simpler interface. +malloclike cru_image_t * +cru_image_from_pixels_with_stride(void *restrict pixels, VkFormat format, + uint32_t width, uint32_t height, + uint32_t stride); /// \brief Create a Crucible image from a file. /// diff --git a/src/framework/test/t_image.c b/src/framework/test/t_image.c index 266ce6d..01cb91e 100644 --- a/src/framework/test/t_image.c +++ b/src/framework/test/t_image.c @@ -70,3 +70,18 @@ t_new_cru_image_from_pixels(void *restrict pixels, VkFormat format, return cimg; } + +malloclike cru_image_t * +t_new_cru_image_from_pixels_with_stride(void *restrict pixels, VkFormat format, + uint32_t width, uint32_t height, uint32_t stride) +{ + t_thread_yield(); + + cru_image_t *cimg = cru_image_from_pixels_with_stride(pixels, format, width, height, stride); + if (!cimg) + t_failf("%s: failed to create image", __func__); + + t_cleanup_push_cru_image(cimg); + + return cimg; +} diff --git a/src/util/cru_image.c b/src/util/cru_image.c index 7860ad3..1e9bd98 100644 --- a/src/util/cru_image.c +++ b/src/util/cru_image.c @@ -90,7 +90,7 @@ cru_image_get_format(cru_image_t *image) bool cru_image_init(cru_image_t *image, enum cru_image_type type, VkFormat format, uint32_t width, uint32_t height, - bool read_only) + bool read_only, uint32_t stride) { cru_refcount_init(&image->refcount); @@ -115,6 +115,8 @@ cru_image_init(cru_image_t *image, enum cru_image_type type, image->type = type; image->read_only = read_only; + image->stride = stride ? stride : image->format_info->cpp * width; + return true; } @@ -299,12 +301,6 @@ cru_image_copy_pixels_to_pixels(cru_image_t *dest, cru_image_t *src) const uint32_t width = src->width; const uint32_t height = src->height; - const uint32_t src_cpp = src->format_info->cpp; - const uint32_t src_stride = src_cpp * width; - - const uint32_t dest_cpp = dest->format_info->cpp; - const uint32_t dest_stride = dest_cpp * width; - assert(!dest->read_only); // Extent equality is enforced by cru_image_check_compatible(). @@ -320,7 +316,7 @@ cru_image_copy_pixels_to_pixels(cru_image_t *dest, cru_image_t *src) goto fail_map_dest_pixels; if (src->format_info == dest->format_info - && src_stride == dest_stride) { + && src->stride == dest->stride) { copy_func = copy_oneshot_memcpy; } else if (src_format == VK_FORMAT_R8_UNORM && dest_format == VK_FORMAT_D32_SFLOAT) { @@ -340,8 +336,8 @@ cru_image_copy_pixels_to_pixels(cru_image_t *dest, cru_image_t *src) } result = copy_func(width, height, - src_pixels, 0, 0, src_stride, - dest_pixels, 0, 0, dest_stride); + src_pixels, 0, 0, src->stride, + dest_pixels, 0, 0, dest->stride); fail_no_copy_func: @@ -422,8 +418,6 @@ cru_image_compare_rect(cru_image_t *a, uint32_t a_x, uint32_t a_y, const uint32_t cpp = a->format_info->cpp; const uint32_t row_size = cpp * width; - const uint32_t a_stride = cpp * a->width; - const uint32_t b_stride = cpp * b->width; a_map = a->map_pixels(a, CRU_IMAGE_MAP_ACCESS_READ); if (!a_map) @@ -436,8 +430,8 @@ cru_image_compare_rect(cru_image_t *a, uint32_t a_x, uint32_t a_y, // FINISHME: Support a configurable tolerance. // FINISHME: Support dumping the diff to file. for (uint32_t y = 0; y < height; ++y) { - const void *a_row = a_map + ((a_y + y) * a_stride + a_x * cpp); - const void *b_row = b_map + ((b_y + y) * b_stride + b_x * cpp); + const void *a_row = a_map + ((a_y + y) * a->stride + a_x * cpp); + const void *b_row = b_map + ((b_y + y) * b->stride + b_x * cpp); if (memcmp(a_row, b_row, row_size) != 0) { loge("%s: diff found in row %u of rect", __func__, y); diff --git a/src/util/cru_image.h b/src/util/cru_image.h index fae72d0..2d74125 100644 --- a/src/util/cru_image.h +++ b/src/util/cru_image.h @@ -39,6 +39,9 @@ struct cru_image { uint32_t height; bool read_only; + /* stride in bytes */ + uint32_t stride; + cru_refcount_t refcount; enum cru_image_type type; @@ -54,7 +57,7 @@ struct cru_image { // file: cru_image.c bool cru_image_init(cru_image_t *image, enum cru_image_type type, VkFormat format, - uint32_t width, uint32_t height, bool read_only); + uint32_t width, uint32_t height, bool read_only, uint32_t stride); char *cru_image_get_abspath(const char *filename); // file: cru_png_image.c diff --git a/src/util/cru_pixel_image.c b/src/util/cru_pixel_image.c index d9ed531..2034f09 100644 --- a/src/util/cru_pixel_image.c +++ b/src/util/cru_pixel_image.c @@ -79,7 +79,35 @@ cru_image_from_pixels(void *restrict pixels, if (!cru_image_init(&kpix_image->image, CRU_IMAGE_TYPE_PIXELS, format, width, height, - /*read_only*/ false)) { + /*read_only*/ false, 0)) { + goto fail; + } + + kpix_image->pixels = pixels; + kpix_image->map_access = 0; + + kpix_image->image.destroy = cru_pixel_image_destroy; + kpix_image->image.map_pixels = cru_pixel_image_map_pixels; + kpix_image->image.unmap_pixels = cru_pixel_image_unmap_pixels; + + return &kpix_image->image; + +fail: + cru_pixel_image_destroy((cru_image_t *) kpix_image); + return NULL; +} + +cru_image_t * +cru_image_from_pixels_with_stride(void *restrict pixels, + VkFormat format, + uint32_t width, uint32_t height, + uint32_t stride) +{ + cru_pixel_image_t *kpix_image = xmalloc(sizeof(*kpix_image)); + + if (!cru_image_init(&kpix_image->image, CRU_IMAGE_TYPE_PIXELS, + format, width, height, + /*read_only*/ false, stride)) { goto fail; } diff --git a/src/util/cru_png_image.c b/src/util/cru_png_image.c index 9a3ffb1..316cfbd 100644 --- a/src/util/cru_png_image.c +++ b/src/util/cru_png_image.c @@ -138,9 +138,7 @@ copy_direct_from_png(cru_image_t *src, cru_image_t *dest) png_structp png_reader = NULL; png_infop png_info = NULL; - const uint32_t width = src->width; const uint32_t height = src->height; - const uint32_t stride = width * src->format_info->cpp; uint8_t *dest_pixels = NULL; uint8_t *dest_rows[height]; @@ -157,7 +155,7 @@ copy_direct_from_png(cru_image_t *src, cru_image_t *dest) return false; for (uint32_t y = 0; y < height; ++y) { - dest_rows[y] = dest_pixels + y * stride; + dest_rows[y] = dest_pixels + y * src->stride; } // FINISHME: Error callbacks for libpng @@ -368,7 +366,7 @@ cru_png_image_load_file(const char *filename) if (!cru_image_init(&png_image->image, CRU_IMAGE_TYPE_PNG, format, width, height, - /*read_only*/ true)) { + /*read_only*/ true, 0)) { goto fail_image_init; } @@ -402,7 +400,6 @@ write_direct_to_png(cru_image_t *image, const string_t *filename) char *abspath = NULL; const uint32_t src_width = image->width; const uint32_t src_height = image->height; - const uint32_t src_stride = image->format_info->cpp * src_width; uint8_t *src_pixels = NULL; uint8_t *src_rows[src_height]; @@ -442,7 +439,7 @@ write_direct_to_png(cru_image_t *image, const string_t *filename) goto fail_map_pixels; for (uint32_t y = 0; y < src_height; ++y) { - src_rows[y] = src_pixels + y * src_stride; + src_rows[y] = src_pixels + y * image->stride; } f = fopen(abspath, "wb"); diff --git a/src/util/cru_vk_image.c b/src/util/cru_vk_image.c index aea540e..8c7118e 100644 --- a/src/util/cru_vk_image.c +++ b/src/util/cru_vk_image.c @@ -300,7 +300,7 @@ cru_image_from_vk_image(VkDevice dev, VkQueue queue, VkImage image, if (!cru_image_init(&self->cru_image, CRU_IMAGE_TYPE_VULKAN, format, cru_minify(level0_width, miplevel), cru_minify(level0_height, miplevel), - /*read_only*/ false)) { + /*read_only*/ false, 0)) { goto fail; } -- 2.16.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev