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
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
24 #include "piglit-util-egl.h"
25 #include "piglit-util-gl.h"
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
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
58 float *g
= expect
+ color_stride
;
59 float *b
= expect
+ 2 * box
;
60 float *w
= b
+ color_stride
;
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
;
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
);
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");
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
);
136 piglit_loge("failed to create EGLImage\n");
139 glDeleteTextures(1, &tex
);
141 PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC dmabuf_query
;
142 PFNEGLEXPORTDMABUFIMAGEMESAPROC dmabuf_export
;
145 (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC
) eglGetProcAddress(
146 "eglExportDMABUFImageQueryMESA");
148 (PFNEGLEXPORTDMABUFIMAGEMESAPROC
) eglGetProcAddress(
149 "eglExportDMABUFImageMESA");
151 if (!dmabuf_query
|| !dmabuf_export
) {
152 piglit_loge("could not find extension entrypoints\n");
158 EGLuint64KHR modifier
;
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");
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");
177 eglDestroyImage(dpy
, img
);
179 const EGLAttrib attrs
[] = {
180 EGL_IMAGE_PRESERVED
, EGL_TRUE
,
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,
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");
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
);
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
);
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
};
250 eglCreateContext(dpy
, EGL_NO_CONFIG_KHR
, EGL_NO_CONTEXT
,
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,
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
,
271 fprintf(stderr
, "failed to create ImageKHR\n");
272 piglit_report_result(PIGLIT_FAIL
);
275 /* Create another texture. */
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
,
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")) {
303 glGenTextures(1, &texture_c
);
304 glTextureViewOES(texture_c
, GL_TEXTURE_2D
, texture_b
, GL_RGBA
,
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
);