ext_egl_image_storage: fix invalid dmabuf test's extension check
[piglit.git] / tests / egl / egl-ext_egl_image_storage.c
blob2010a95e53b7fcada97c0a065bcaf55e21fe9784
1 /*
2 * Copyright © 2019 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 #include "piglit-util-egl.h"
25 #include "piglit-util-gl.h"
27 /**
28 * @file egl-ext_egl_image_storage.c
31 PIGLIT_GL_TEST_CONFIG_BEGIN
33 config.supports_gl_es_version = 30;
35 PIGLIT_GL_TEST_CONFIG_END
37 /* dummy */
38 enum piglit_result
39 piglit_display(void)
41 return PIGLIT_FAIL;
44 static bool
45 verify_rgbw_texture()
47 int width, height;
48 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
49 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
51 float *expect = piglit_rgbw_image(GL_RGBA, width, height, true,
52 GL_UNSIGNED_NORMALIZED);
53 unsigned hf = width / 2;
54 unsigned color_stride = hf * 4; // one color width in image
55 unsigned box = color_stride * hf; // one color box
57 float *r = expect;
58 float *g = expect + color_stride;
59 float *b = expect + 2 * box;
60 float *w = b + color_stride;
62 bool pass = true;
64 /* Verify texture contents by probing each color box. */
65 pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, 0, 0, hf, hf, r) && pass;
66 pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, hf, 0, hf, hf, g) && pass;
67 pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, 0, hf, hf, hf, b) && pass;
68 pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, hf, hf, hf, hf, w) && pass;
70 free(expect);
71 return pass;
74 void
75 test_invalid_params(EGLImageKHR egl_image)
77 const int none_attr[] = { GL_NONE };
78 const int some_attr = GL_ONE;
80 /* "If <attrib_list> is neither NULL nor a pointer to the value
81 * GL_NONE, the error INVALID_VALUE is generated."
83 glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, egl_image, &some_attr);
84 if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
85 piglit_report_result(PIGLIT_FAIL);
88 /* "If <image> is NULL, the error INVALID_VALUE is generated." */
89 glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, 0x0, none_attr);
90 if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
91 piglit_report_result(PIGLIT_FAIL);
94 /* "If the GL is unable to specify a texture object using the supplied
95 * eglImageOES <image> (if, for example, <image> refers to a
96 * multisampled eglImageOES, or <target> is GL_TEXTURE_2D but <image>
97 * contains a cube map), the error INVALID_OPERATION is generated.
99 glEGLImageTargetTexStorageEXT(GL_TEXTURE_3D, egl_image, none_attr);
100 if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
101 piglit_report_result(PIGLIT_FAIL);
105 static bool
106 test_invalid_target_dmabuf(EGLDisplay dpy)
109 * EXT_EGL_image_storage
111 * If the EGL image was created using EGL_EXT_image_dma_buf_import,
112 * then the following applies:
114 * - <target> must be GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES.
115 * Otherwise, the error INVALID_OPERATION is generated.
118 if (!piglit_is_egl_extension_supported(dpy,
119 "EGL_MESA_image_dma_buf_export") ||
120 !piglit_is_egl_extension_supported(dpy,
121 "EGL_EXT_image_dma_buf_import")) {
122 piglit_logi("dma_buf export and/or import ext not available\n");
123 return true;
126 int w = 32, h = 32;
128 GLuint tex;
129 glGenTextures(1, &tex);
130 glBindTexture(GL_TEXTURE_3D, tex);
131 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, w, h, 1);
133 EGLImage img = eglCreateImage(dpy, eglGetCurrentContext(),
134 EGL_GL_TEXTURE_3D, (EGLClientBuffer)(uintptr_t)tex, NULL);
135 if (!img) {
136 piglit_loge("failed to create EGLImage\n");
137 return false;
139 glDeleteTextures(1, &tex);
141 PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC dmabuf_query;
142 PFNEGLEXPORTDMABUFIMAGEMESAPROC dmabuf_export;
144 dmabuf_query =
145 (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) eglGetProcAddress(
146 "eglExportDMABUFImageQueryMESA");
147 dmabuf_export =
148 (PFNEGLEXPORTDMABUFIMAGEMESAPROC) eglGetProcAddress(
149 "eglExportDMABUFImageMESA");
151 if (!dmabuf_query || !dmabuf_export) {
152 piglit_loge("could not find extension entrypoints\n");
153 return false;
156 int fourcc = -1;
157 int num_planes = -1;
158 EGLuint64KHR modifier;
159 int fd = -1;
160 EGLint stride = -1;
161 EGLint offset = -1;
163 /* Query the image properties, verify fourcc and num planes. */
164 if (!dmabuf_query(dpy, img, &fourcc, &num_planes, &modifier) ||
165 !piglit_check_egl_error(EGL_SUCCESS)) {
166 piglit_loge("failed to query EGLImage dmabuf params\n");
167 return false;
170 /* Export the image, verify success. */
171 if (!dmabuf_export(dpy, img, &fd, &stride, &offset) ||
172 !piglit_check_egl_error(EGL_SUCCESS)) {
173 piglit_loge("failed to export EGLImage dmabuf\n");
174 return false;
177 eglDestroyImage(dpy, img);
179 const EGLAttrib attrs[] = {
180 EGL_IMAGE_PRESERVED, EGL_TRUE,
181 EGL_WIDTH, w,
182 EGL_HEIGHT, h,
183 EGL_LINUX_DRM_FOURCC_EXT, fourcc,
184 EGL_DMA_BUF_PLANE0_FD_EXT, fd,
185 EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
186 EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
187 EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier,
188 EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32,
189 EGL_NONE, EGL_NONE
192 img = eglCreateImage(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
193 EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attrs);
195 if (!piglit_check_egl_error(EGL_SUCCESS)) {
196 piglit_loge("failed to import dmabuf EGLImage\n");
197 return false;
200 glGenTextures(1, &tex);
201 glBindTexture(GL_TEXTURE_3D, tex);
202 glEGLImageTargetTexStorageEXT(GL_TEXTURE_3D, img, NULL);
204 bool ret = piglit_check_gl_error(GL_INVALID_OPERATION);
206 eglDestroyImage(dpy, img);
207 glDeleteTextures(1, &tex);
209 return ret;
212 void
213 piglit_init(int argc, char **argv)
215 piglit_require_extension("GL_EXT_EGL_image_storage");
217 PFNEGLCREATEIMAGEKHRPROC peglCreateImageKHR = NULL;
218 peglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)
219 eglGetProcAddress("eglCreateImageKHR");
220 if (!peglCreateImageKHR) {
221 fprintf(stderr, "eglCreateImageKHR missing\n");
222 piglit_report_result(PIGLIT_SKIP);
225 PFNEGLDESTROYIMAGEKHRPROC peglDestroyImageKHR = NULL;
226 peglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)
227 eglGetProcAddress("eglDestroyImageKHR");
228 if (!peglDestroyImageKHR) {
229 fprintf(stderr, "eglDestroyImageKHR missing\n");
230 piglit_report_result(PIGLIT_SKIP);
233 /* Require EGL_MESA_platform_surfaceless extension. */
234 const char *exts = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
235 if (!strstr(exts, "EGL_MESA_platform_surfaceless"))
236 piglit_report_result(PIGLIT_SKIP);
238 EGLint major, minor;
239 EGLDisplay dpy;
241 dpy = piglit_egl_get_default_display(EGL_PLATFORM_SURFACELESS_MESA);
243 if (!eglInitialize(dpy, &major, &minor))
244 piglit_report_result(PIGLIT_FAIL);
246 piglit_require_egl_extension(dpy, "EGL_MESA_configless_context");
248 EGLint ctx_attr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
249 EGLContext ctx =
250 eglCreateContext(dpy, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
251 ctx_attr);
252 if (ctx == EGL_NO_CONTEXT) {
253 fprintf(stderr, "could not create EGL context\n");
254 piglit_report_result(PIGLIT_FAIL);
257 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
259 /* Create a texture. */
260 GLuint texture_a = piglit_rgbw_texture(GL_RGBA, 256, 256, true, true,
261 GL_UNSIGNED_BYTE);
262 glBindTexture(GL_TEXTURE_2D, texture_a);
264 /* Create EGLImage from texture. */
265 EGLint attribs[] = { EGL_NONE };
266 EGLImageKHR egl_image;
267 egl_image = peglCreateImageKHR(dpy, ctx, EGL_GL_TEXTURE_2D,
268 (EGLClientBuffer) (intptr_t) texture_a,
269 attribs);
270 if (!egl_image) {
271 fprintf(stderr, "failed to create ImageKHR\n");
272 piglit_report_result(PIGLIT_FAIL);
275 /* Create another texture. */
276 GLuint texture_b;
277 glGenTextures(1, &texture_b);
278 glBindTexture(GL_TEXTURE_2D, texture_b);
280 const int none_attr[] = { GL_NONE };
282 /* Specify texture from EGLImage, invalid parameters. */
283 test_invalid_params(egl_image);
285 /* Specify texture from EGLImage, valid params. */
286 glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, egl_image, none_attr);
287 if (!piglit_check_gl_error(GL_NO_ERROR))
288 piglit_report_result(PIGLIT_FAIL);
290 if (!verify_rgbw_texture())
291 piglit_report_result(PIGLIT_FAIL);
293 /* Expected to be immutable. */
294 GLint immutable_format;
295 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT,
296 &immutable_format);
297 if (immutable_format != 1)
298 piglit_report_result(PIGLIT_FAIL);
300 /* If OES_texture_view supported, attempt to create a view. */
301 if (piglit_is_extension_supported("GL_OES_texture_view")) {
302 GLuint texture_c;
303 glGenTextures(1, &texture_c);
304 glTextureViewOES(texture_c, GL_TEXTURE_2D, texture_b, GL_RGBA,
305 0, 1, 0, 1);
306 if (!piglit_check_gl_error(GL_NO_ERROR)) {
307 fprintf(stderr, "failed to create textureview!\n");
308 piglit_report_result(PIGLIT_FAIL);
311 glDeleteTextures(1, &texture_c);
314 glDeleteTextures(1, &texture_a);
315 glDeleteTextures(1, &texture_b);
316 peglDestroyImageKHR(dpy, egl_image);
318 if (!test_invalid_target_dmabuf(dpy)) {
319 fprintf(stderr, "failed to test dma-buf storage\n");
320 piglit_report_result(PIGLIT_FAIL);
323 piglit_report_result(PIGLIT_PASS);