2 * Copyright © 2020 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
21 * DEALINGS IN THE SOFTWARE.
24 * Eleni Maria Stea <estea@igalia.com>
27 #include <piglit-util-gl.h>
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config
.supports_gl_compat_version
= 30;
35 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
36 config
.khr_no_error_support
= PIGLIT_HAS_ERRORS
;
38 PIGLIT_GL_TEST_CONFIG_END
40 static const char vs
[] =
42 "in vec4 piglit_vertex;\n"
43 "in vec2 piglit_texcoord;\n"
44 "out vec2 tex_coords;\n"
47 " gl_Position = piglit_vertex;\n"
48 " tex_coords = piglit_texcoord;\n"
51 static const char fs
[] =
53 "in vec2 tex_coords;\n"
54 "uniform sampler2D tex; \n"
58 " color = texture(tex, tex_coords);\n"
61 static const char vs_overwrite
[] =
63 "in vec4 piglit_vertex;\n"
66 " gl_Position = piglit_vertex;\n"
69 static const char fs_overwrite
[] =
72 "const vec4 colors[] = vec4[] (\n"
73 " vec4(1.0, 0.0, 0.0, 1.0),\n"
74 " vec4(0.0, 1.0, 0.0, 1.0),\n"
75 " vec4(0.0, 0.0, 1.0, 1.0),\n"
76 " vec4(1.0, 1.0, 1.0, 1.0),\n"
77 " vec4(1.0, 0.0, 1.0, 1.0),\n"
78 " vec4(0.0, 1.0, 1.0, 1.0));\n"
81 " int band = int(gl_FragCoord.x * 6.0 / 160.0);\n"
82 " color = colors[band];\n"
92 VkFormat color_format
,
93 VkFormat depth_format
,
94 VkImageTiling color_tiling
,
95 VkImageTiling depth_tiling
,
96 VkImageLayout color_in_layout
,
97 VkImageLayout depth_in_layout
,
98 VkImageLayout color_end_layout
,
99 VkImageLayout depth_end_layout
);
113 static struct vk_ctx vk_core
;
114 static struct vk_image_att vk_color_att
;
115 static struct vk_image_att vk_depth_att
;
116 static struct vk_renderer vk_rnd
;
117 static struct vk_buf vk_bo
;
119 static GLenum gl_target
= GL_TEXTURE_2D
;
120 static GLenum gl_tex_storage_format
= GL_RGBA32F
;
121 static GLuint gl_tex
;
122 static GLint gl_prog
;
123 static GLint gl_prog_overwrite
;
124 static GLuint gl_mem_obj
;
126 static GLuint gl_fbo
;
127 static GLuint gl_disp_tex
;
129 static struct gl_ext_semaphores gl_sem
;
130 static struct vk_semaphores vk_sem
;
132 static float vk_fb_color
[4] = { 1.0, 1.0, 1.0, 1.0 };
135 void piglit_init(int argc
, char **argv
)
137 piglit_require_extension("GL_ARB_texture_storage");
138 piglit_require_extension("GL_EXT_memory_object");
139 piglit_require_extension("GL_EXT_memory_object_fd");
140 piglit_require_extension("GL_EXT_semaphore");
141 piglit_require_extension("GL_EXT_semaphore_fd");
148 if (!vk_init(w
, h
, d
, num_samples
, num_levels
, num_layers
,
149 color_format
, depth_format
,
150 color_tiling
, depth_tiling
,
151 color_in_layout
, depth_in_layout
,
152 color_end_layout
, depth_end_layout
)) {
153 fprintf(stderr
, "Failed to initialize Vulkan, skipping the test.\n");
154 piglit_report_result(PIGLIT_SKIP
);
157 if (!gl_create_mem_obj_from_vk_mem(&vk_core
, &vk_color_att
.obj
.mobj
,
159 fprintf(stderr
, "Failed to create GL memory object from Vulkan memory.\n");
160 piglit_report_result(PIGLIT_FAIL
);
163 if (!gl_gen_tex_from_mem_obj(&vk_color_att
.props
,
164 gl_tex_storage_format
,
165 gl_mem_obj
, 0, &gl_tex
)) {
166 fprintf(stderr
, "Failed to create texture from GL memory object.\n");
167 piglit_report_result(PIGLIT_FAIL
);
170 if (!gl_create_semaphores_from_vk(&vk_core
, &vk_sem
, &gl_sem
)) {
171 fprintf(stderr
, "Failed to import semaphores from Vulkan.\n");
172 piglit_report_result(PIGLIT_FAIL
);
176 fprintf(stderr
, "Failed to initialize structs for GL rendering.\n");
177 piglit_report_result(PIGLIT_FAIL
);
184 enum piglit_result res
= PIGLIT_PASS
;
186 bool vk_sem_has_wait
= true;
187 bool vk_sem_has_signal
= true;
188 float colors
[6][4] = {
189 {1.0, 0.0, 0.0, 1.0},
190 {0.0, 1.0, 0.0, 1.0},
191 {0.0, 0.0, 1.0, 1.0},
192 {1.0, 1.0, 1.0, 1.0},
193 {1.0, 0.0, 1.0, 1.0},
196 GLuint layout
= gl_get_layout_from_vk(color_in_layout
);
198 if (vk_sem_has_wait
) {
199 glSignalSemaphoreEXT(gl_sem
.gl_frame_ready
, 0, 0, 1,
204 struct vk_image_att images
[] = { vk_color_att
, vk_depth_att
};
206 vk_draw(&vk_core
, 0, &vk_rnd
, vk_fb_color
, 4, &vk_sem
,
207 vk_sem_has_wait
, vk_sem_has_signal
, images
, ARRAY_SIZE(images
),
210 layout
= gl_get_layout_from_vk(color_end_layout
);
211 if (vk_sem_has_signal
) {
212 glWaitSemaphoreEXT(gl_sem
.vk_frame_done
, 0, 0, 1,
216 /* OpenGL overwrites the image */
217 glBindTexture(gl_target
, gl_tex
);
218 glBindFramebuffer(GL_FRAMEBUFFER
, gl_fbo
);
219 glUseProgram(gl_prog_overwrite
);
220 piglit_draw_rect(-1, -1, 2, 2);
221 glBindFramebuffer(GL_FRAMEBUFFER
, 0);
224 vk_copy_image_to_buffer(&vk_core
, &vk_color_att
, &vk_bo
, w
, h
);
225 if (vkMapMemory(vk_core
.dev
, vk_bo
.mobj
.mem
, 0,
226 vk_bo
.mobj
.mem_sz
, 0, &pixels
) != VK_SUCCESS
) {
227 fprintf(stderr
, "Failed to map Vulkan image memory.\n");
228 piglit_report_result(PIGLIT_FAIL
);
231 /* Because we can't render using Vulkan on piglit, we use the
232 * pixels we've just read from Vulkan memory as texture data
233 * in a new OpenGL texture */
234 glBindTexture(gl_target
, gl_disp_tex
);
235 glTexSubImage2D(gl_target
, 0, 0, 0, w
, h
, GL_RGBA
, GL_FLOAT
, pixels
);
238 vkUnmapMemory(vk_core
.dev
, vk_bo
.mobj
.mem
);
240 /* OpenGL renders the Vulkan image pixels we've just read
243 glUseProgram(gl_prog
);
244 glBindTexture(gl_target
, gl_disp_tex
);
245 piglit_draw_rect_tex(-1, -1,
250 const float y
= (float)piglit_height
/ 2.0;
251 for (i
= 0; i
< 6; i
++) {
252 float x
= i
* (float)piglit_width
/ 6.0 + (float)piglit_width
/ 12.0;
254 if (!piglit_probe_pixel_rgba(x
, y
, colors
[i
])) {
260 piglit_present_results();
269 uint32_t num_samples
,
272 VkFormat color_format
,
273 VkFormat depth_format
,
274 VkImageTiling color_tiling
,
275 VkImageTiling depth_tiling
,
276 VkImageLayout color_in_layout
,
277 VkImageLayout depth_in_layout
,
278 VkImageLayout color_end_layout
,
279 VkImageLayout depth_end_layout
)
286 if (!vk_init_ctx_for_rendering(&vk_core
)) {
287 fprintf(stderr
, "Failed to create Vulkan context.\n");
291 if (!vk_check_gl_compatibility(&vk_core
)) {
292 fprintf(stderr
, "Mismatch in driver/device UUID\n");
296 /* creating external images */
298 if (!vk_fill_ext_image_props(&vk_core
,
308 &vk_color_att
.props
)) {
309 fprintf(stderr
, "Unsupported color image properties.\n");
312 if (!vk_create_ext_image(&vk_core
, &vk_color_att
.props
, &vk_color_att
.obj
)) {
313 fprintf(stderr
, "Failed to create color image.\n");
318 if (!vk_fill_ext_image_props(&vk_core
,
328 &vk_depth_att
.props
)) {
329 fprintf(stderr
, "Unsupported depth image properties.\n");
333 if (!vk_create_ext_image(&vk_core
, &vk_depth_att
.props
, &vk_depth_att
.obj
)) {
334 fprintf(stderr
, "Failed to create depth image.\n");
338 if (!(vs_src
= load_shader(VK_BANDS_VERT
, &vs_sz
)))
341 if (!(fs_src
= load_shader(VK_BANDS_FRAG
, &fs_sz
)))
344 if (!vk_create_renderer(&vk_core
, vs_src
, vs_sz
, fs_src
, fs_sz
,
346 &vk_color_att
, &vk_depth_att
, 0, &vk_rnd
)) {
347 fprintf(stderr
, "Failed to create Vulkan renderer.\n");
351 if (!vk_create_semaphores(&vk_core
, &vk_sem
)) {
352 fprintf(stderr
, "Failed to create semaphores.\n");
356 if (!vk_create_buffer(&vk_core
, false, w
* h
* 4 * sizeof(float), VK_BUFFER_USAGE_TRANSFER_DST_BIT
, 0, &vk_bo
)) {
357 fprintf(stderr
, "Failed to create buffer.\n");
376 vk_destroy_ext_image(&vk_core
, &vk_color_att
.obj
);
377 vk_destroy_ext_image(&vk_core
, &vk_depth_att
.obj
);
379 vk_destroy_renderer(&vk_core
, &vk_rnd
);
380 vk_destroy_semaphores(&vk_core
, &vk_sem
);
382 vk_destroy_buffer(&vk_core
, &vk_bo
);
384 vk_cleanup_ctx(&vk_core
);
397 gl_prog
= piglit_build_simple_program(vs
, fs
);
398 gl_prog_overwrite
= piglit_build_simple_program(vs_overwrite
,
401 glGenFramebuffers(1, &gl_fbo
);
403 glBindTexture(gl_target
, gl_tex
);
404 glBindFramebuffer(GL_FRAMEBUFFER
, gl_fbo
);
406 glFramebufferTexture2D(GL_FRAMEBUFFER
,
407 GL_COLOR_ATTACHMENT0
,
408 gl_target
, gl_tex
, 0);
410 if (!check_bound_fbo_status())
413 glClearColor(1.0, 1.0, 0.0, 1.0);
414 glClear(GL_COLOR_BUFFER_BIT
);
416 glBindFramebuffer(GL_FRAMEBUFFER
, 0);
417 glBindTexture(gl_target
, 0);
418 glGenTextures(1, &gl_disp_tex
);
419 glBindTexture(gl_target
, gl_disp_tex
);
420 glTexParameteri(gl_target
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
421 glTexParameteri(gl_target
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
422 glTexImage2D(gl_target
, 0, gl_tex_storage_format
, w
, h
, 0, GL_RGBA
, GL_FLOAT
, 0);
423 glBindTexture(gl_target
, 0);
425 glClearColor(0.1, 0.1, 0.1, 1.0);
426 glClear(GL_COLOR_BUFFER_BIT
);
427 return glGetError() == GL_NO_ERROR
;
433 glBindTexture(gl_target
, 0);
435 glDeleteTextures(1, &gl_tex
);
436 glDeleteProgram(gl_prog
);
438 glDeleteSemaphoresEXT(1, &gl_sem
.gl_frame_ready
);
439 glDeleteSemaphoresEXT(1, &gl_sem
.vk_frame_done
);
441 glDeleteFramebuffers(1, &gl_fbo
);
443 glDeleteMemoryObjectsEXT(1, &gl_mem_obj
);