You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
7.3 KiB
311 lines
7.3 KiB
/**************************************************************************
|
|
*
|
|
* Copyright 2020 Google LLC
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
**************************************************************************/
|
|
|
|
/*
|
|
* basic library initialisation, teardown, reset
|
|
* and context creation tests.
|
|
*/
|
|
|
|
#include <check.h>
|
|
#include <errno.h>
|
|
#include <poll.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <virglrenderer.h>
|
|
|
|
#include "testvirgl.h"
|
|
|
|
START_TEST(virgl_fence_create)
|
|
{
|
|
int ret;
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
testvirgl_reset_fence();
|
|
ret = virgl_renderer_create_fence(1, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
START_TEST(virgl_fence_poll)
|
|
{
|
|
const int target_seqno = 50;
|
|
int ret;
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
testvirgl_reset_fence();
|
|
ret = virgl_renderer_create_fence(target_seqno, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
do {
|
|
int seqno;
|
|
|
|
virgl_renderer_poll();
|
|
seqno = testvirgl_get_last_fence();
|
|
if (seqno == target_seqno)
|
|
break;
|
|
|
|
ck_assert_int_eq(seqno, 0);
|
|
usleep(1000);
|
|
} while(1);
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
START_TEST(virgl_fence_poll_many)
|
|
{
|
|
const int fence_count = 100;
|
|
const int base_seqno = 50;
|
|
const int target_seqno = base_seqno + fence_count - 1;
|
|
int last_seqno;
|
|
int ret;
|
|
int i;
|
|
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
testvirgl_reset_fence();
|
|
last_seqno = 0;
|
|
|
|
for (i = 0; i < fence_count; i++) {
|
|
ret = virgl_renderer_create_fence(base_seqno + i, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
}
|
|
|
|
do {
|
|
int seqno;
|
|
|
|
virgl_renderer_poll();
|
|
seqno = testvirgl_get_last_fence();
|
|
if (seqno == target_seqno)
|
|
break;
|
|
|
|
ck_assert(seqno == 0 || (seqno >= base_seqno && seqno < target_seqno));
|
|
|
|
/* monotonic increasing */
|
|
ck_assert_int_ge(seqno, last_seqno);
|
|
last_seqno = seqno;
|
|
|
|
usleep(1000);
|
|
} while(1);
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
static int
|
|
wait_sync_fd(int fd, int timeout)
|
|
{
|
|
struct pollfd pollfd = {
|
|
.fd = fd,
|
|
.events = POLLIN,
|
|
};
|
|
int ret;
|
|
do {
|
|
ret = poll(&pollfd, 1, timeout);
|
|
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
|
|
|
|
if (ret < 0)
|
|
return -errno;
|
|
else if (ret > 0 && !(pollfd.revents & POLLIN))
|
|
return -EINVAL;
|
|
|
|
return ret ? 0 : -ETIME;
|
|
}
|
|
|
|
START_TEST(virgl_fence_export)
|
|
{
|
|
const int target_seqno = 50;
|
|
int fd;
|
|
int ret;
|
|
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
testvirgl_reset_fence();
|
|
ret = virgl_renderer_create_fence(target_seqno, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
ret = virgl_renderer_export_fence(target_seqno, &fd);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
ret = wait_sync_fd(fd, -1);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
virgl_renderer_poll();
|
|
ck_assert_int_eq(testvirgl_get_last_fence(), target_seqno);
|
|
|
|
close(fd);
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
START_TEST(virgl_fence_export_signaled)
|
|
{
|
|
const int target_seqno = 50;
|
|
const int test_range = 10;
|
|
int fd;
|
|
int ret;
|
|
int i;
|
|
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
/* when there is no active fence, a signaled fd is always returned */
|
|
for (i = 0; i < test_range; i++) {
|
|
ret = virgl_renderer_export_fence(target_seqno + 1 + i, &fd);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
ret = wait_sync_fd(fd, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
close(fd);
|
|
}
|
|
|
|
ret = virgl_renderer_create_fence(target_seqno, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
/* when there is any active fence, a signaled fd is returned when the
|
|
* requested seqno is smaller than the first active fence
|
|
*/
|
|
for (i = 0; i < test_range; i++) {
|
|
ret = virgl_renderer_export_fence(target_seqno - 1 - i, &fd);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
ret = wait_sync_fd(fd, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
close(fd);
|
|
}
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
START_TEST(virgl_fence_export_invalid)
|
|
{
|
|
const int target_seqno = 50;
|
|
const int target_seqno2 = 55;
|
|
int seqno;
|
|
int fd;
|
|
int ret;
|
|
|
|
ret = testvirgl_init_single_ctx();
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
ret = virgl_renderer_create_fence(target_seqno, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
ret = virgl_renderer_create_fence(target_seqno2, 0);
|
|
ck_assert_int_eq(ret, 0);
|
|
|
|
for (seqno = target_seqno; seqno <= target_seqno2 + 1; seqno++) {
|
|
ret = virgl_renderer_export_fence(seqno, &fd);
|
|
if (seqno == target_seqno || seqno == target_seqno2) {
|
|
ck_assert_int_eq(ret, 0);
|
|
close(fd);
|
|
} else {
|
|
ck_assert_int_eq(ret, -EINVAL);
|
|
}
|
|
}
|
|
|
|
testvirgl_fini_single_ctx();
|
|
}
|
|
END_TEST
|
|
|
|
static Suite *virgl_init_suite(bool include_fence_export)
|
|
{
|
|
Suite *s;
|
|
TCase *tc_core;
|
|
|
|
s = suite_create("virgl_fence");
|
|
tc_core = tcase_create("fence");
|
|
|
|
tcase_add_test(tc_core, virgl_fence_create);
|
|
tcase_add_test(tc_core, virgl_fence_poll);
|
|
tcase_add_test(tc_core, virgl_fence_poll_many);
|
|
|
|
if (include_fence_export) {
|
|
tcase_add_test(tc_core, virgl_fence_export);
|
|
tcase_add_test(tc_core, virgl_fence_export_signaled);
|
|
tcase_add_test(tc_core, virgl_fence_export_invalid);
|
|
}
|
|
|
|
suite_add_tcase(s, tc_core);
|
|
|
|
return s;
|
|
}
|
|
|
|
static bool detect_fence_export_support(void)
|
|
{
|
|
int dummy_cookie;
|
|
struct virgl_renderer_callbacks dummy_cbs;
|
|
int fd;
|
|
int ret;
|
|
|
|
memset(&dummy_cbs, 0, sizeof(dummy_cbs));
|
|
dummy_cbs.version = 1;
|
|
|
|
ret = virgl_renderer_init(&dummy_cookie, context_flags, &dummy_cbs);
|
|
if (ret)
|
|
return false;
|
|
|
|
ret = virgl_renderer_export_fence(0, &fd);
|
|
if (ret) {
|
|
virgl_renderer_cleanup(&dummy_cookie);
|
|
return false;
|
|
}
|
|
|
|
close(fd);
|
|
virgl_renderer_cleanup(&dummy_cookie);
|
|
return true;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
Suite *s;
|
|
SRunner *sr;
|
|
int number_failed;
|
|
bool include_fence_export = false;
|
|
|
|
if (getenv("VRENDTEST_USE_EGL_SURFACELESS"))
|
|
context_flags |= VIRGL_RENDERER_USE_SURFACELESS;
|
|
if (getenv("VRENDTEST_USE_EGL_GLES")) {
|
|
context_flags |= VIRGL_RENDERER_USE_GLES;
|
|
include_fence_export = detect_fence_export_support();
|
|
}
|
|
|
|
s = virgl_init_suite(include_fence_export);
|
|
sr = srunner_create(s);
|
|
|
|
srunner_run_all(sr, CK_NORMAL);
|
|
number_failed = srunner_ntests_failed(sr);
|
|
srunner_free(sr);
|
|
|
|
return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|
|
|