[Mesa-dev] [PATCH crucible 2/3] Add support for non-packed strides in cru_image.
Bas Nieuwenhuizen
bas at basnieuwenhuizen.nl
Wed Mar 7 21:50:51 UTC 2018
From: Bas Nieuwenhuizen <basni at 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
More information about the mesa-dev
mailing list