[Piglit] [RFC] Trying to fix dmabuf/yuv tests
Kristian Høgsberg
hoegsberg at gmail.com
Tue Sep 6 20:04:27 UTC 2016
On Sun, Sep 4, 2016 at 9:34 AM, Rob Clark <robdclark at gmail.com> wrote:
> Ok, so the basic problem with the YUV tests is that they currently
> completely ignore driver/hw pitch requirements, since the code that
> allocates the buffer doesn't know the pixel format, only the 'cpp'.
>
> The yuv test creates a small 4x4 yuv eglimage. If, say, the hardware
> requires the pitch to be aligned to, say, 32pixels, everything is fine
> for the Y plane, but the subsampled U/V or U+V plane has half as many
> pixels. (This did help me catch a bug in driver, not rejecting the
> dmabuf import with invalid pitch, but that doesn't help to get the
> piglit tests running.)
>
> My original idea was that, since cpp values are never valid fourcc
> values, and visa versa, to avoid changing too much the other existing
> RGB tests by allowing to pass down either cpp or fourcc. Especially
> since in the case of RGB we really don't care about, for example,
> ARGB vs BRGA. Whereas for YUV formats, we really do want to know the
> exact format to copy the src data into the allocated buffer correctly.
> But this patch turned out to be big/intrusive enough that maybe just
> fixing up the other RGB tests to use fourcc everywhere might be ok.
>
> The other issue is that egl_image_for_dma_buf_fd() made assumptions
> about the offset/pitch of each plane, which were not valid. (And,
> I believe, incorrect even for i965.. I'm not entirely sure why it
> worked at all.) So I ended up needing to expose piglit_dma_buf and
> adding an array of per-plane offsets/pitches.
>
> Maybe this could be split up better or made a bit more clean.. not
> sure.
>
> Fwiw, this applies on top of anholt's gbm dmabuf backend. And also
> needs the mesa patch I sent yesterday to add gbm R8/GR88 formats.
> ---
> tests/spec/ext_image_dma_buf_import/refcount.c | 6 +-
> .../spec/ext_image_dma_buf_import/sample_common.c | 70 ++++----
> .../spec/ext_image_dma_buf_import/sample_common.h | 5 +-
> tests/spec/ext_image_dma_buf_import/sample_rgb.c | 2 +-
> tests/spec/ext_image_dma_buf_import/sample_yuv.c | 2 +-
> tests/util/piglit-framework-gl.c | 8 +-
> tests/util/piglit-framework-gl.h | 2 +-
> .../util/piglit-framework-gl/piglit_drm_dma_buf.c | 176 ++++++++++++++++-----
> .../util/piglit-framework-gl/piglit_drm_dma_buf.h | 16 +-
> .../util/piglit-framework-gl/piglit_gl_framework.h | 7 +-
> 10 files changed, 193 insertions(+), 101 deletions(-)
>
> diff --git a/tests/spec/ext_image_dma_buf_import/refcount.c b/tests/spec/ext_image_dma_buf_import/refcount.c
> index 5b14cdd..ddb0fc8 100644
> --- a/tests/spec/ext_image_dma_buf_import/refcount.c
> +++ b/tests/spec/ext_image_dma_buf_import/refcount.c
> @@ -72,13 +72,11 @@ piglit_display(void)
> if (res != PIGLIT_PASS)
> return res;
>
> - res = egl_image_for_dma_buf_fd(dup(fd), fourcc, w, h, stride, offset,
> - &img1);
> + res = egl_image_for_dma_buf_fd(buf, dup(fd), fourcc, &img1);
> if (res != PIGLIT_PASS)
> return res;
>
> - res = egl_image_for_dma_buf_fd(dup(fd), fourcc, w, h, stride, offset,
> - &img2);
> + res = egl_image_for_dma_buf_fd(buf, dup(fd), fourcc, &img2);
> if (res != PIGLIT_PASS)
> return res;
>
> diff --git a/tests/spec/ext_image_dma_buf_import/sample_common.c b/tests/spec/ext_image_dma_buf_import/sample_common.c
> index c5aa1e1..538f3c4 100644
> --- a/tests/spec/ext_image_dma_buf_import/sample_common.c
> +++ b/tests/spec/ext_image_dma_buf_import/sample_common.c
> @@ -23,6 +23,8 @@
>
> #include <unistd.h>
>
> +#include "piglit-framework-gl/piglit_drm_dma_buf.h"
> +
> #include "image_common.h"
> #include "sample_common.h"
>
> @@ -105,47 +107,46 @@ sample_tex(GLuint tex, unsigned x, unsigned y, unsigned w, unsigned h)
> }
>
> enum piglit_result
> -egl_image_for_dma_buf_fd(int fd, int fourcc, int w, int h,
> - unsigned stride, unsigned offset, EGLImageKHR *out_img)
> +egl_image_for_dma_buf_fd(struct piglit_dma_buf *buf, int fd, int fourcc, EGLImageKHR *out_img)
> {
> EGLint error;
> EGLImageKHR img;
> EGLint attr_packed[] = {
> - EGL_WIDTH, w,
> - EGL_HEIGHT, h,
> + EGL_WIDTH, buf->w,
> + EGL_HEIGHT, buf->h,
> EGL_LINUX_DRM_FOURCC_EXT, fourcc,
> EGL_DMA_BUF_PLANE0_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
> - EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE0_OFFSET_EXT, buf->offset[0],
> + EGL_DMA_BUF_PLANE0_PITCH_EXT, buf->stride[0],
> EGL_NONE
> };
>
> EGLint attr_nv12[] = {
> - EGL_WIDTH, w,
> - EGL_HEIGHT, h,
> + EGL_WIDTH, buf->w,
> + EGL_HEIGHT, buf->h,
> EGL_LINUX_DRM_FOURCC_EXT, fourcc,
> EGL_DMA_BUF_PLANE0_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
> - EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE0_OFFSET_EXT, buf->offset[0],
> + EGL_DMA_BUF_PLANE0_PITCH_EXT, buf->stride[0],
> EGL_DMA_BUF_PLANE1_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset + h * stride,
> - EGL_DMA_BUF_PLANE1_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE1_OFFSET_EXT, buf->offset[1],
> + EGL_DMA_BUF_PLANE1_PITCH_EXT, buf->stride[1],
> EGL_NONE
> };
>
> EGLint attr_yuv420[] = {
> - EGL_WIDTH, w,
> - EGL_HEIGHT, h,
> + EGL_WIDTH, buf->w,
> + EGL_HEIGHT, buf->h,
> EGL_LINUX_DRM_FOURCC_EXT, fourcc,
> EGL_DMA_BUF_PLANE0_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
> - EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE0_OFFSET_EXT, buf->offset[0],
> + EGL_DMA_BUF_PLANE0_PITCH_EXT, buf->stride[0],
> EGL_DMA_BUF_PLANE1_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset + h * stride,
> - EGL_DMA_BUF_PLANE1_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE1_OFFSET_EXT, buf->offset[1],
> + EGL_DMA_BUF_PLANE1_PITCH_EXT, buf->stride[1],
> EGL_DMA_BUF_PLANE2_FD_EXT, fd,
> - EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset + h * stride + w / 2,
> - EGL_DMA_BUF_PLANE2_PITCH_EXT, stride,
> + EGL_DMA_BUF_PLANE2_OFFSET_EXT, buf->offset[2],
> + EGL_DMA_BUF_PLANE2_PITCH_EXT, buf->stride[2],
> EGL_NONE
> };
>
> @@ -191,21 +192,22 @@ egl_image_for_dma_buf_fd(int fd, int fourcc, int w, int h,
> }
>
> static enum piglit_result
> -sample_buffer(void *buf, int fd, int fourcc, unsigned w, unsigned h,
> - unsigned stride, unsigned offset)
> +sample_buffer(struct piglit_dma_buf *buf, int fourcc)
> {
> enum piglit_result res;
> EGLImageKHR img;
> GLuint tex;
> + int w = buf->w;
> + int h = buf->h;
>
> - res = egl_image_for_dma_buf_fd(fd, fourcc, w, h, stride, offset, &img);
> + res = egl_image_for_dma_buf_fd(buf, buf->fd, fourcc, &img);
>
> /* Release the creator side of the buffer. */
> piglit_destroy_dma_buf(buf);
>
> if (!img) {
> /* Close the descriptor also, EGL does not have ownership */
> - close(fd);
> + close(buf->fd);
> }
>
> if (res != PIGLIT_PASS)
> @@ -225,7 +227,7 @@ destroy:
> }
>
> enum piglit_result
> -dma_buf_create_and_sample_32bpp(unsigned w, unsigned h, unsigned cpp,
> +dma_buf_create_and_sample_32bpp(unsigned w, unsigned h,
> int fourcc, const unsigned char *src)
> {
> struct piglit_dma_buf *buf;
> @@ -233,24 +235,10 @@ dma_buf_create_and_sample_32bpp(unsigned w, unsigned h, unsigned cpp,
> int fd;
> enum piglit_result res;
>
> - unsigned buffer_height;
> -
> - switch (fourcc) {
> - case DRM_FORMAT_NV12:
> - case DRM_FORMAT_YUV420:
> - case DRM_FORMAT_YVU420:
> - buffer_height = h * 3 / 2;
> - break;
> - default:
> - buffer_height = h;
> - break;
> - }
> -
> - res = piglit_create_dma_buf(w, buffer_height,
> - cpp, src, w * cpp, &buf, &fd, &stride,
> + res = piglit_create_dma_buf(w, h, fourcc, src, w, &buf, &fd, &stride,
> &offset);
> if (res != PIGLIT_PASS)
> return res;
>
> - return sample_buffer(buf, fd, fourcc, w, h, stride, offset);
> + return sample_buffer(buf, fourcc);
> }
> diff --git a/tests/spec/ext_image_dma_buf_import/sample_common.h b/tests/spec/ext_image_dma_buf_import/sample_common.h
> index db2ff82..36a5bb5 100644
> --- a/tests/spec/ext_image_dma_buf_import/sample_common.h
> +++ b/tests/spec/ext_image_dma_buf_import/sample_common.h
> @@ -32,12 +32,11 @@
> * sample it using a shader program.
> */
> enum piglit_result
> -dma_buf_create_and_sample_32bpp(unsigned w, unsigned h, unsigned cpp,
> +dma_buf_create_and_sample_32bpp(unsigned w, unsigned h,
> int fourcc, const unsigned char *src);
>
> enum piglit_result
> -egl_image_for_dma_buf_fd(int fd, int fourcc, int w, int h,
> - unsigned stride, unsigned offset, EGLImageKHR *out_img);
> +egl_image_for_dma_buf_fd(struct piglit_dma_buf *buf, int fd, int fourcc, EGLImageKHR *out_img);
>
> enum piglit_result
> texture_for_egl_image(EGLImageKHR img, GLuint *out_tex);
> diff --git a/tests/spec/ext_image_dma_buf_import/sample_rgb.c b/tests/spec/ext_image_dma_buf_import/sample_rgb.c
> index af9b39f..ae69e98 100644
> --- a/tests/spec/ext_image_dma_buf_import/sample_rgb.c
> +++ b/tests/spec/ext_image_dma_buf_import/sample_rgb.c
> @@ -59,7 +59,7 @@ piglit_display(void)
>
> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
>
> - res = dma_buf_create_and_sample_32bpp(2, 2, 4, fourcc, src);
> + res = dma_buf_create_and_sample_32bpp(2, 2, 4, src);
> if (res != PIGLIT_PASS)
> return res;
>
> diff --git a/tests/spec/ext_image_dma_buf_import/sample_yuv.c b/tests/spec/ext_image_dma_buf_import/sample_yuv.c
> index 74826c1..6119b08 100644
> --- a/tests/spec/ext_image_dma_buf_import/sample_yuv.c
> +++ b/tests/spec/ext_image_dma_buf_import/sample_yuv.c
> @@ -108,7 +108,7 @@ piglit_display(void)
>
> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
>
> - res = dma_buf_create_and_sample_32bpp(4, 4, 1, fourcc, t);
> + res = dma_buf_create_and_sample_32bpp(4, 4, fourcc, t);
> if (res != PIGLIT_PASS)
> return res;
>
> diff --git a/tests/util/piglit-framework-gl.c b/tests/util/piglit-framework-gl.c
> index 9748ddf..09a6932 100644
> --- a/tests/util/piglit-framework-gl.c
> +++ b/tests/util/piglit-framework-gl.c
> @@ -265,9 +265,9 @@ piglit_set_reshape_func(void (*func)(int w, int h))
> gl_fw->set_reshape_func(gl_fw, func);
> }
>
> -
> +/* TODO drop fd/stride/offset args */
> enum piglit_result
> -piglit_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> +piglit_create_dma_buf(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> const void *src_data, unsigned src_stride,
> struct piglit_dma_buf **buf, int *fd,
> unsigned *stride, unsigned *offset)
> @@ -279,8 +279,8 @@ piglit_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> if (!gl_fw->create_dma_buf)
> return PIGLIT_SKIP;
>
> - return gl_fw->create_dma_buf(w, h, cpp, src_data, src_stride, buf, fd,
> - stride, offset);
> + return gl_fw->create_dma_buf(w, h, cpp_or_fourcc, src_data,
> + buf, fd, stride, offset);
> }
>
> void
> diff --git a/tests/util/piglit-framework-gl.h b/tests/util/piglit-framework-gl.h
> index 81c1a5e..ee0b9f2 100644
> --- a/tests/util/piglit-framework-gl.h
> +++ b/tests/util/piglit-framework-gl.h
> @@ -316,7 +316,7 @@ struct piglit_dma_buf;
> * buffers, the return value is PIGLIT_SKIP instead of PIGLIT_FAIL.
> */
> enum piglit_result
> -piglit_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> +piglit_create_dma_buf(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> const void *src_data, unsigned src_stride,
> struct piglit_dma_buf **buf, int *fd,
> unsigned *stride, unsigned *offset);
> diff --git a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
> index cd308bc..6b813d3 100644
> --- a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
> +++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
> @@ -23,6 +23,7 @@
>
> #include "piglit-util-gl.h"
> #include "piglit_drm_dma_buf.h"
> +#include "drm_fourcc.h"
> #ifdef HAVE_LIBDRM_INTEL
> #include <libdrm/intel_bufmgr.h>
> #endif
> @@ -41,21 +42,13 @@
>
> #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
>
> -struct piglit_dma_buf {
> - unsigned w;
> - unsigned h;
> - unsigned stride;
> - int fd;
> - void *priv;
> -};
> -
> struct piglit_drm_driver {
> int fd;
> char *name;
>
> bool
> (*create)(unsigned w, unsigned h, unsigned cpp,
> - const unsigned char *src_data, unsigned src_stride,
> + const unsigned char *src_data,
> struct piglit_dma_buf *buf);
>
> bool
> @@ -133,23 +126,43 @@ piglit_intel_bufmgr_get(void)
> }
>
> static bool
> -piglit_intel_buf_create(unsigned w, unsigned h, unsigned cpp,
> - const unsigned char *src_data, unsigned src_stride,
> - struct piglit_dma_buf *buf)
> +piglit_intel_buf_create(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> + const unsigned char *src_data, struct piglit_dma_buf *buf)
> {
> unsigned i;
> drm_intel_bo *bo;
> - unsigned stride = ALIGN(w * cpp, 4);
> drm_intel_bufmgr *mgr = piglit_intel_bufmgr_get();
> + unsigned stride, src_stride, cpp;
> + unsigned buf_h = h;
>
> if (!mgr || h % 2)
> return false;
>
> - bo = drm_intel_bo_alloc(mgr, "piglit_dma_buf", h * stride, 4096);
> + switch (cpp_or_fourcc) {
> + case 1:
> + case 2:
> + case 4:
> + cpp = cpp_or_fourcc;
> + break;
> + case DRM_FORMAT_NV12:
> + case DRM_FORMAT_YUV420:
> + case DRM_FORMAT_YVU420:
> + cpp = 1;
> + buf_h = h * 3 / 2;
> + break;
> + default:
> + assert(0);
> + return false;
> + }
> +
> + src_stride = cpp * w;
> + stride = ALIGN(w * cpp, 4);
> +
> + bo = drm_intel_bo_alloc(mgr, "piglit_dma_buf", buf_h * stride, 4096);
> if (!bo)
> return false;
>
> - for (i = 0; i < h; ++i) {
> + for (i = 0; i < buf_h; ++i) {
> if (drm_intel_bo_subdata(bo, i * stride, w * cpp,
> src_data + i * src_stride)) {
> drm_intel_bo_unreference(bo);
> @@ -159,10 +172,33 @@ piglit_intel_buf_create(unsigned w, unsigned h, unsigned cpp,
>
> buf->w = w;
> buf->h = h;
> - buf->stride = stride;
> + buf->offset[0] = 0;
> + buf->stride[0] = stride;
> buf->fd = 0;
> buf->priv = bo;
>
> + switch (cpp_or_fourcc) {
> + case DRM_FORMAT_NV12:
> + buf->offset[1] = stride * h;
> + buf->stride[1] = stride;
> + break;
> + case DRM_FORMAT_YUV420:
> + case DRM_FORMAT_YVU420:
> + // XXX previously egl_image_for_dma_buf_fd() was using
> + // stride rather than stride/2 for U and V planes, which
> + // is probably not right.. maybe i965 ignores it??
> + // Now things fail for YV12 (but not YU12??).. seems like
> + // there is a bug in i965, since at least what the test
> + // was doing before seems pretty bogus
The test was using U and V planes with the same stride as the Y plane,
laid out side by side below the Y plane:
+-------+
| |
| |
+---+---+
| | |
+---+---+
Plane 1 is at offset (sizeof plane 0) with the same stride, plane 2 is
at offset (sizeof plane 0 + stride / 2) with the same stride.
If we have the gbm eglimage path, why do we keep the intel specific code around?
> + buf->offset[1] = stride * h;
> + buf->stride[1] = stride / 2;
> + buf->offset[2] = buf->offset[1] + (stride * h / 2 / 2);
> + buf->stride[2] = stride / 2;
> + break;
> + default:
> + break;
> + }
> +
> return true;
> }
>
> @@ -201,9 +237,8 @@ piglit_gbm_get(void)
> }
>
> static bool
> -piglit_gbm_buf_create(unsigned w, unsigned h, unsigned cpp,
> - const unsigned char *src_data, unsigned src_stride,
> - struct piglit_dma_buf *buf)
> +piglit_gbm_buf_create(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> + const unsigned char *src_data, struct piglit_dma_buf *buf)
> {
> unsigned i;
> struct gbm_bo *bo;
> @@ -212,28 +247,65 @@ piglit_gbm_buf_create(unsigned w, unsigned h, unsigned cpp,
> void *dst_data;
> void *map_data = NULL;
> enum gbm_bo_format format;
> + unsigned cpp = 0, src_stride;
> + unsigned buf_w = w;
> + unsigned buf_h = h;
>
> - if (!gbm || h % 2)
> + if (!gbm || h % 2 || w % 2)
> return false;
>
> - /* It would be nice if we took in a fourcc instead of a cpp */
> - switch (cpp) {
Can we just switch over to always taking a fourcc? This cpp_or_fourcc is messy.
> + switch (cpp_or_fourcc) {
> case 1:
> - format = GBM_FORMAT_C8;
> + format = GBM_FORMAT_R8;
> + cpp = 1;
> + src_stride = cpp * w;
> + break;
> + case 2:
> + format = GBM_FORMAT_GR88;
> + cpp = 2;
> + src_stride = cpp * w;
> break;
> case 4:
> format = GBM_BO_FORMAT_ARGB8888;
> + cpp = 4;
> + src_stride = cpp * w;
> + break;
> + /* For YUV formats, the U/V planes might have a greater relative
> + * pitch. For example, if the driver needs pitch aligned to 32
> + * pixels, for a 4x4 YUV image, the stride of both the Y and U/V
> + * planes will be 32 bytes. Not 32 for Y and 16 for U/V. To
> + * account for this, use a 2cpp format with half the width. For
> + * hardware that only has stride requirements in bytes (rather
> + * than pixels) this will work out the same. For hardware that
> + * has pitch alignment requirements in pixels, this will give an
> + * overly conservative alignment for Y but a sufficient alignment
> + * for U/V.
> + */
> + case DRM_FORMAT_NV12:
> + format = GBM_FORMAT_GR88;
> + buf_w = w / 2;
> + buf_h = h * 3 / 2;
> + src_stride = w;
> + cpp = 1;
> + break;
> + case DRM_FORMAT_YUV420:
> + case DRM_FORMAT_YVU420:
> + format = GBM_FORMAT_GR88;
> + buf_w = w / 2;
> + buf_h = h * 2; /* U/V not interleaved */
> + src_stride = w;
> + cpp = 1;
> break;
> default:
> - fprintf(stderr, "Unknown cpp %d\n", cpp);
> + fprintf(stderr, "Unknown cpp/fourcc %x\n", cpp_or_fourcc);
> return false;
> }
>
> - bo = gbm_bo_create(gbm, w, h, format, GBM_BO_USE_RENDERING);
> + bo = gbm_bo_create(gbm, buf_w, buf_h, format, GBM_BO_USE_RENDERING);
> if (!bo)
> return false;
>
> - dst_data = gbm_bo_map(bo, 0, 0, w, h, GBM_BO_TRANSFER_WRITE,
> + dst_data = gbm_bo_map(bo, 0, 0, buf_w, buf_h, GBM_BO_TRANSFER_WRITE,
> &dst_stride, &map_data);
> if (!dst_data) {
> fprintf(stderr, "Failed to map GBM bo\n");
> @@ -241,18 +313,49 @@ piglit_gbm_buf_create(unsigned w, unsigned h, unsigned cpp,
> return NULL;
> }
>
> + buf->w = w;
> + buf->h = h;
> + buf->offset[0] = 0;
> + buf->stride[0] = dst_stride;
> + buf->fd = -1;
> + buf->priv = bo;
> +
> for (i = 0; i < h; ++i) {
> memcpy((char *)dst_data + i * dst_stride,
> src_data + i * src_stride,
> w * cpp);
> }
> +
> + switch (cpp_or_fourcc) {
> + case DRM_FORMAT_NV12:
> + buf->offset[1] = dst_stride * h;
> + buf->stride[1] = dst_stride;
> + for (i = 0; i < h/2; ++i) {
> + memcpy(((char *)dst_data + buf->offset[1]) + i * buf->stride[1],
> + (src_data + (w*h)) + i * src_stride, w);
> + }
> + break;
> + case DRM_FORMAT_YUV420:
> + case DRM_FORMAT_YVU420:
> + buf->offset[1] = dst_stride * h;
> + buf->stride[1] = dst_stride / 2;
> + for (i = 0; i < h/2; ++i) {
> + memcpy(((char *)dst_data + buf->offset[1]) + i * buf->stride[1],
> + (src_data + (w*h)) + i * src_stride / 2, w / 2);
> + }
> + buf->offset[2] = buf->offset[1] + (dst_stride * h / 2 / 2);
> + buf->stride[2] = dst_stride / 2;
> + for (i = 0; i < h/2; ++i) {
> + memcpy(((char *)dst_data + buf->offset[2]) + i * buf->stride[2],
> + (src_data + (w*h) + (w*h/4)) + i * src_stride / 2, w / 2);
> + }
> + break;
> + default:
> + break;
> + }
> +
> gbm_bo_unmap(bo, map_data);
>
> - buf->w = w;
> - buf->h = h;
> - buf->stride = dst_stride;
> - buf->fd = 0;
> - buf->priv = bo;
>
> return true;
> }
> @@ -352,10 +455,9 @@ piglit_drm_get_driver(void)
> }
>
> enum piglit_result
> -piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> - const void *src_data, unsigned src_stride,
> - struct piglit_dma_buf **buf, int *fd,
> - unsigned *stride, unsigned *offset)
> +piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> + const void *src_data, struct piglit_dma_buf **buf,
> + int *fd, unsigned *stride, unsigned *offset)
> {
> struct piglit_dma_buf *drm_buf;
> const struct piglit_drm_driver *drv = piglit_drm_get_driver();
> @@ -367,7 +469,7 @@ piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> if (!drm_buf)
> return PIGLIT_FAIL;
>
> - if (!drv->create(w, h, cpp, src_data, src_stride, drm_buf)) {
> + if (!drv->create(w, h, cpp_or_fourcc, src_data, drm_buf)) {
> free(drm_buf);
> return PIGLIT_FAIL;
> }
> @@ -379,7 +481,7 @@ piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
>
> *buf = drm_buf;
> *fd = drm_buf->fd;
> - *stride = drm_buf->stride;
> + *stride = drm_buf->stride[0];
> *offset = 0;
>
> return PIGLIT_PASS;
> diff --git a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
> index 2c72eca..7a2b5c5 100644
> --- a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
> +++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
> @@ -23,13 +23,19 @@
> #ifndef PIGLIT_DRM_DMA_BUF_H
> #define PIGLIT_DRM_DMA_BUF_H
>
> -struct piglit_dma_buf;
> +struct piglit_dma_buf {
> + unsigned w;
> + unsigned h;
> + unsigned offset[3];
> + unsigned stride[3];
> + int fd;
> + void *priv;
> +};
>
> enum piglit_result
> -piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
> - const void *src_data, unsigned src_stride,
> - struct piglit_dma_buf **buf, int *fd,
> - unsigned *stride, unsigned *offset);
> +piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> + const void *src_data, struct piglit_dma_buf **buf,
> + int *fd, unsigned *stride, unsigned *offset);
>
> void
> piglit_drm_destroy_dma_buf(struct piglit_dma_buf *buf);
> diff --git a/tests/util/piglit-framework-gl/piglit_gl_framework.h b/tests/util/piglit-framework-gl/piglit_gl_framework.h
> index 97fecca..1966cf9 100644
> --- a/tests/util/piglit-framework-gl/piglit_gl_framework.h
> +++ b/tests/util/piglit-framework-gl/piglit_gl_framework.h
> @@ -73,10 +73,9 @@ struct piglit_gl_framework {
> (*destroy)(struct piglit_gl_framework *gl_fw);
>
> enum piglit_result
> - (*create_dma_buf)(unsigned w, unsigned h, unsigned cpp,
> - const void *src_data, unsigned src_stride,
> - struct piglit_dma_buf **buf, int *fd,
> - unsigned *stride, unsigned *offset);
> + (*create_dma_buf)(unsigned w, unsigned h, unsigned cpp_or_fourcc,
> + const void *src_data, struct piglit_dma_buf **buf,
> + int *fd, unsigned *stride, unsigned *offset);
>
> void
> (*destroy_dma_buf)(struct piglit_dma_buf *buf);
> --
> 2.7.4
>
More information about the Piglit
mailing list