enum piglit_result piglit_display(void) { const unsigned w = 2; const unsigned h = 2; const unsigned cpp = 4; const unsigned fourcc = DRM_FORMAT_ARGB8888; const unsigned char *pixels = alloca(w * h * cpp); struct piglit_dma_buf *buf; EGLImageKHR img; enum piglit_result res; bool pass = true; res = piglit_create_dma_buf(w, h, fourcc, pixels, &buf); if (res != PIGLIT_PASS) return res; img = create_image(w, h, buf->fd, buf->stride[0], buf->offset[0]); if (!img) { piglit_destroy_dma_buf(buf); /* unsupported format (BAD_MATCH) is not an error. */ return piglit_check_egl_error(EGL_BAD_MATCH) ? PIGLIT_SKIP : PIGLIT_FAIL; } pass = try_as_texture_2d(img) && pass; pass = try_as_render_buffer(img) && pass; eglDestroyImageKHR(eglGetCurrentDisplay(), img); piglit_destroy_dma_buf(buf); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
/** * Here one tries to create an image with six different attribute sets each * missing one of the mandatory attribute. * * One and same buffer is used for all the tests. Each test is expected to fail * meaning that the ownership is not transferred to the EGL in any point. */ enum piglit_result piglit_display(void) { const unsigned w = 2; const unsigned h = 2; const unsigned cpp = 2; const unsigned char pixels[w * h * cpp]; EGLint all[2 * NUM_MANDATORY_ATTRS]; EGLint missing[2 * (NUM_MANDATORY_ATTRS - 1) + 1]; struct piglit_dma_buf *buf; unsigned stride; unsigned offset; int fd; enum piglit_result res; bool pass = true; res = piglit_create_dma_buf(w, h, cpp, pixels, w * cpp, &buf, &fd, &stride, &offset); if (res != PIGLIT_PASS) return res; fill_full_set(w, h, fd, offset, stride, all); fill_one_missing(all, missing, EGL_HEIGHT); pass = test_missing(fd, missing) && pass; fill_one_missing(all, missing, EGL_WIDTH); pass = test_missing(fd, missing) && pass; fill_one_missing(all, missing, EGL_LINUX_DRM_FOURCC_EXT); pass = test_missing(fd, missing) && pass; fill_one_missing(all, missing, EGL_DMA_BUF_PLANE0_FD_EXT); pass = test_missing(fd, missing) && pass; fill_one_missing(all, missing, EGL_DMA_BUF_PLANE0_OFFSET_EXT); pass = test_missing(fd, missing) && pass; fill_one_missing(all, missing, EGL_DMA_BUF_PLANE0_PITCH_EXT); pass = test_missing(fd, missing) && pass; /** * EGL stack can claim the ownership of the file descriptor only when it * succeeds. Close the file descriptor here and check that it really * wasn't closed by EGL. */ pass = (close(fd) == 0) && pass; piglit_destroy_dma_buf(buf); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
/** * One and same buffer is used for all the tests. Each test is expected to fail * meaning that the ownership is not transferred to the EGL in any point. */ enum piglit_result piglit_display(void) { const unsigned w = 2; const unsigned h = 2; const unsigned cpp = 4; const unsigned char *pixels = alloca(w * h * cpp); struct piglit_dma_buf *buf; unsigned stride; unsigned offset; int fd; enum piglit_result res; bool pass = true; res = piglit_create_dma_buf(w, h, cpp, pixels, w * cpp, &buf, &fd, &stride, &offset); if (res != PIGLIT_PASS) return res; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE1_FD_EXT, fd) && pass; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0) && pass; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE1_PITCH_EXT, stride) && pass; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE2_FD_EXT, fd) && pass; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE2_OFFSET_EXT, 0) && pass; pass = test_excess_attributes(w, h, fd, stride, offset, EGL_DMA_BUF_PLANE2_PITCH_EXT, stride) && pass; pass = test_buffer_not_null(w, h, fd, stride, offset) && pass; pass = test_invalid_context(w, h, fd, stride, offset) && pass; pass = test_invalid_format(w, h, fd, stride, offset) && pass; pass = test_pitch_zero(w, h, fd, stride, offset) && pass; piglit_destroy_dma_buf(buf); /** * EGL stack can claim the ownership of the file descriptor only when it * succeeds. Close the file descriptor here and check that it really * wasn't closed by EGL. */ pass = (close(fd) == 0) && pass; return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
enum piglit_result piglit_display(void) { const unsigned w = 2; const unsigned h = 2; const unsigned cpp = 4; const unsigned char pixels[w * h * cpp]; struct piglit_dma_buf *buf; unsigned stride; unsigned offset; int fd; EGLImageKHR img; enum piglit_result res; res = piglit_create_dma_buf(w, h, cpp, pixels, w * cpp, &buf, &fd, &stride, &offset); if (res != PIGLIT_PASS) return res; img = create_image(w, h, fd, stride, offset); if (!piglit_check_egl_error(EGL_BAD_MATCH)) { if (img) eglDestroyImageKHR(eglGetCurrentDisplay(), img); return PIGLIT_FAIL; } piglit_destroy_dma_buf(buf); /** * EGL stack can claim the ownership of the file descriptor only when it * succeeds. Close the descriptor and check that it really wasn't closed * by EGL. */ return close(fd) == 0 ? PIGLIT_PASS : PIGLIT_FAIL; }
PIGLIT_GL_TEST_CONFIG_END static enum piglit_result test_create_and_destroy(unsigned w, unsigned h, void *buf, int fd, unsigned stride, unsigned offset) { EGLint error; EGLImageKHR img; EGLint attr[] = { EGL_WIDTH, w, EGL_HEIGHT, h, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, EGL_DMA_BUF_PLANE0_FD_EXT, fd, EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset, EGL_DMA_BUF_PLANE0_PITCH_EXT, stride, EGL_NONE }; img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr); /* Release the creator side of the buffer. */ piglit_destroy_dma_buf(buf); error = eglGetError(); /* EGL may not support the format, this is not an error. */ if (!img && error == EGL_BAD_MATCH) return PIGLIT_SKIP; if (error != EGL_SUCCESS) { fprintf(stderr, "eglCreateImageKHR() failed: %s 0x%x\n", piglit_get_egl_error_name(error), error); return PIGLIT_FAIL; } if (!img) { fprintf(stderr, "image creation succeed but returned NULL\n"); return PIGLIT_FAIL; } eglDestroyImageKHR(eglGetCurrentDisplay(), img); if (!piglit_check_egl_error(EGL_SUCCESS)) return PIGLIT_FAIL; /** * EGL stack is allowed to keep the importing file descriptor open until * all resources are released. Therefore close the display first. */ if (!eglTerminate(eglGetCurrentDisplay())) { fprintf(stderr, "eglTerminate() failed\n"); return PIGLIT_FAIL; } /* * Our own file descriptor must still be valid, and therefore * closing it must succeed. */ return close(fd) == 0 ? PIGLIT_PASS : PIGLIT_FAIL; }
static enum piglit_result sample_buffer(void *buf, int fd, int fourcc, unsigned w, unsigned h, unsigned stride, unsigned offset) { EGLint error; EGLImageKHR img; EGLint attr_packed[] = { EGL_WIDTH, w, EGL_HEIGHT, 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_NONE }; EGLint attr_nv12[] = { EGL_WIDTH, w, EGL_HEIGHT, 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_PLANE1_FD_EXT, fd, EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset + h * stride, EGL_DMA_BUF_PLANE1_PITCH_EXT, stride, EGL_NONE }; EGLint attr_yuv420[] = { EGL_WIDTH, w, EGL_HEIGHT, 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_PLANE1_FD_EXT, fd, EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset + h * stride, EGL_DMA_BUF_PLANE1_PITCH_EXT, stride, 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_NONE }; EGLint *attr; switch (fourcc) { case DRM_FORMAT_NV12: attr = attr_nv12; break; case DRM_FORMAT_YUV420: case DRM_FORMAT_YVU420: attr = attr_yuv420; break; default: attr = attr_packed; break; } img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr); /* Release the creator side of the buffer. */ piglit_destroy_dma_buf(buf); error = eglGetError(); /* EGL may not support the format, this is not an error. */ if (!img && error == EGL_BAD_MATCH) return PIGLIT_SKIP; if (error != EGL_SUCCESS) { printf("eglCreateImageKHR() failed: %s 0x%x\n", piglit_get_egl_error_name(error), error); /* Close the descriptor also, EGL does not have ownership */ close(fd); return PIGLIT_FAIL; } if (!img) { fprintf(stderr, "image creation succeeded but returned NULL\n"); return PIGLIT_FAIL; } return sample_and_destroy_img(w, h, img); }