1ca86eba8Smrg/*
2ca86eba8Smrg * Copyright 2018  Emmanuele Bassi
3ca86eba8Smrg *
4ca86eba8Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5ca86eba8Smrg * copy of this software and associated documentation files (the "Software"),
6ca86eba8Smrg * to deal in the Software without restriction, including without limitation
7ca86eba8Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8ca86eba8Smrg * and/or sell copies of the Software, and to permit persons to whom the
9ca86eba8Smrg * Software is furnished to do so, subject to the following conditions:
10ca86eba8Smrg *
11ca86eba8Smrg * The above copyright notice and this permission notice (including the next
12ca86eba8Smrg * paragraph) shall be included in all copies or substantial portions of the
13ca86eba8Smrg * Software.
14ca86eba8Smrg *
15ca86eba8Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16ca86eba8Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17ca86eba8Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18ca86eba8Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19ca86eba8Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20ca86eba8Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21ca86eba8Smrg * IN THE SOFTWARE.
22ca86eba8Smrg */
23ca86eba8Smrg
24ca86eba8Smrg/**
25ca86eba8Smrg * @file epoxy_api.c
26ca86eba8Smrg *
27ca86eba8Smrg * Tests the Epoxy API using EGL.
28ca86eba8Smrg */
29ca86eba8Smrg
30ca86eba8Smrg#ifdef __sun
31ca86eba8Smrg#define __EXTENSIONS__
32ca86eba8Smrg#else
33ca86eba8Smrg#define _GNU_SOURCE
34ca86eba8Smrg#endif
35ca86eba8Smrg#include <stdio.h>
36ca86eba8Smrg#include <string.h>
37ca86eba8Smrg#include <stdlib.h>
38ca86eba8Smrg#include <assert.h>
39ca86eba8Smrg#include <err.h>
40ca86eba8Smrg#include "epoxy/gl.h"
41ca86eba8Smrg#include "epoxy/egl.h"
42ca86eba8Smrg
43ca86eba8Smrg#include "egl_common.h"
44ca86eba8Smrg
45ca86eba8Smrgstatic bool
46ca86eba8Smrgmake_egl_current_and_test(EGLDisplay *dpy, EGLContext ctx)
47ca86eba8Smrg{
48ca86eba8Smrg    const char *string;
49ca86eba8Smrg    GLuint shader;
50ca86eba8Smrg    bool pass = true;
51ca86eba8Smrg
52ca86eba8Smrg    eglMakeCurrent(dpy, NULL, NULL, ctx);
53ca86eba8Smrg
54ca86eba8Smrg    if (!epoxy_is_desktop_gl()) {
55ca86eba8Smrg        fputs("Claimed to be desktop\n", stderr);
56ca86eba8Smrg        pass = false;
57ca86eba8Smrg    }
58ca86eba8Smrg
59ca86eba8Smrg    if (epoxy_gl_version() < 20) {
60ca86eba8Smrg        fprintf(stderr, "Claimed to be GL version %d\n",
61ca86eba8Smrg                epoxy_gl_version());
62ca86eba8Smrg        pass = false;
63ca86eba8Smrg    }
64ca86eba8Smrg
65ca86eba8Smrg    if (epoxy_glsl_version() < 100) {
66ca86eba8Smrg        fprintf(stderr, "Claimed to have GLSL version %d\n",
67ca86eba8Smrg                epoxy_glsl_version());
68ca86eba8Smrg        pass = false;
69ca86eba8Smrg    }
70ca86eba8Smrg
71ca86eba8Smrg    string = (const char *)glGetString(GL_VERSION);
72ca86eba8Smrg    printf("GL version: %s - Epoxy: %d\n", string, epoxy_gl_version());
73ca86eba8Smrg
74ca86eba8Smrg    string = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
75ca86eba8Smrg    printf("GLSL version: %s - Epoxy: %d\n", string, epoxy_glsl_version());
76ca86eba8Smrg
77ca86eba8Smrg    shader = glCreateShader(GL_FRAGMENT_SHADER);
78ca86eba8Smrg    pass = glIsShader(shader);
79ca86eba8Smrg
80ca86eba8Smrg    return pass;
81ca86eba8Smrg}
82ca86eba8Smrg
83ca86eba8Smrgstatic void
84ca86eba8Smrginit_egl(EGLDisplay *dpy, EGLContext *out_ctx)
85ca86eba8Smrg{
86ca86eba8Smrg    static const EGLint config_attribs[] = {
87ca86eba8Smrg	EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
88ca86eba8Smrg	EGL_RED_SIZE, 1,
89ca86eba8Smrg	EGL_GREEN_SIZE, 1,
90ca86eba8Smrg	EGL_BLUE_SIZE, 1,
91ca86eba8Smrg	EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
92ca86eba8Smrg	EGL_NONE
93ca86eba8Smrg    };
94ca86eba8Smrg    static const EGLint context_attribs[] = {
95ca86eba8Smrg        EGL_CONTEXT_CLIENT_VERSION, 2,
96ca86eba8Smrg        EGL_NONE
97ca86eba8Smrg    };
98ca86eba8Smrg    EGLContext ctx;
99ca86eba8Smrg    EGLConfig cfg;
100ca86eba8Smrg    EGLint count;
101ca86eba8Smrg
102ca86eba8Smrg    if (!epoxy_has_egl_extension(dpy, "EGL_KHR_surfaceless_context"))
103ca86eba8Smrg        errx(77, "Test requires EGL_KHR_surfaceless_context");
104ca86eba8Smrg
105ca86eba8Smrg    if (!eglBindAPI(EGL_OPENGL_API))
106ca86eba8Smrg        errx(77, "Couldn't initialize EGL with desktop GL\n");
107ca86eba8Smrg
108ca86eba8Smrg    if (!eglChooseConfig(dpy, config_attribs, &cfg, 1, &count))
109ca86eba8Smrg        errx(77, "Couldn't get an EGLConfig\n");
110ca86eba8Smrg
111ca86eba8Smrg    ctx = eglCreateContext(dpy, cfg, NULL, context_attribs);
112ca86eba8Smrg    if (!ctx)
113ca86eba8Smrg        errx(77, "Couldn't create a GL context\n");
114ca86eba8Smrg
115ca86eba8Smrg    *out_ctx = ctx;
116ca86eba8Smrg}
117ca86eba8Smrg
118ca86eba8Smrgint
119ca86eba8Smrgmain(int argc, char **argv)
120ca86eba8Smrg{
121ca86eba8Smrg    bool pass = true;
122ca86eba8Smrg
123ca86eba8Smrg    EGLContext egl_ctx;
124ca86eba8Smrg    EGLDisplay *dpy = get_egl_display_or_skip();
125ca86eba8Smrg    const char *extensions = eglQueryString(dpy, EGL_EXTENSIONS);
126ca86eba8Smrg    char *first_space;
127ca86eba8Smrg    char *an_extension;
128ca86eba8Smrg
129ca86eba8Smrg    /* We don't have any extensions guaranteed by the ABI, so for the
130ca86eba8Smrg     * touch test we just check if the first one is reported to be there.
131ca86eba8Smrg     */
132ca86eba8Smrg    first_space = strstr(extensions, " ");
133ca86eba8Smrg    if (first_space) {
134ca86eba8Smrg        an_extension = strndup(extensions, first_space - extensions);
135ca86eba8Smrg    } else {
136ca86eba8Smrg        an_extension = strdup(extensions);
137ca86eba8Smrg    }
138ca86eba8Smrg
139ca86eba8Smrg    if (!epoxy_extension_in_string(extensions, an_extension))
140ca86eba8Smrg        errx(1, "Implementation reported absence of %s", an_extension);
141ca86eba8Smrg
142ca86eba8Smrg    free(an_extension);
143ca86eba8Smrg
144ca86eba8Smrg    init_egl(dpy, &egl_ctx);
145ca86eba8Smrg    pass = make_egl_current_and_test(dpy, egl_ctx);
146ca86eba8Smrg
147ca86eba8Smrg    return pass != true;
148ca86eba8Smrg}
149