Skip to content
Snippets Groups Projects
Commit eaa5e546 authored by Jeremy Whiting's avatar Jeremy Whiting
Browse files

Add check-gl draw a triangle test.

Just as with check-vulkan use --visible to see the triangle window
otherwise application draws a few frames and reports any gl errors
found or does exit 0 on success.
parent 2503e8bd
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !83. Comments created here will be created in the context of that merge request.
/*
* Copyright © 2019 Collabora Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <set>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
extern "C" {
#include <getopt.h>
};
const int WIDTH = 200;
const int HEIGHT = 200;
static const char *argv0;
class HelloTriangleGLApplication {
public:
HelloTriangleGLApplication(bool visible)
: m_visible(visible),
m_display(nullptr),
m_window(0),
m_context(0),
m_visualID(0)
{
}
void run() {
initGL();
mainLoop();
cleanup();
}
private:
bool m_visible;
Display *m_display;
Window m_window;
GLXContext m_context;
VisualID m_visualID;
void initGL() {
m_display = XOpenDisplay(nullptr);
if (!m_display)
{
throw std::runtime_error("Unable to open display");
}
makeWindow();
if (m_visible)
XMapWindow(m_display, m_window);
glXMakeCurrent(m_display, m_window, m_context);
}
void drawTriangle()
{
//clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Make it red
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-0.8f,-0.8f,0.0f);
glVertex3f(0.8f,-0.8f, 0.0f);
glVertex3f(0.0f, 0.6f,0.0f);
glEnd();
glEndList();
glEnable(GL_NORMALIZE);
}
void makeWindow()
{
int attribs[64];
int i = 0;
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
XVisualInfo *visinfo;
/* Singleton attributes. */
attribs[i++] = GLX_RGBA;
attribs[i++] = GLX_DOUBLEBUFFER;
/* Key/value attributes. */
attribs[i++] = GLX_RED_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_GREEN_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_BLUE_SIZE;
attribs[i++] = 1;
attribs[i++] = GLX_DEPTH_SIZE;
attribs[i++] = 1;
attribs[i++] = None;
scrnum = DefaultScreen(m_display);
root = RootWindow(m_display, scrnum);
visinfo = glXChooseVisual(m_display, scrnum, attribs);
if (!visinfo)
{
throw std::runtime_error("Error: couldn't get an RGB, Double-buffered visual");
exit(1);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(m_display, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
m_window = XCreateWindow( m_display, root, 0, 0, WIDTH, HEIGHT,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = 0;
sizehints.y = 0;
sizehints.width = WIDTH;
sizehints.height = HEIGHT;
sizehints.flags = USSize | USPosition;
XSetNormalHints(m_display, m_window, &sizehints);
XSetStandardProperties(m_display, m_window, "check-gl", "check-gl",
None, (char **)NULL, 0, &sizehints);
}
m_context = glXCreateContext(m_display, visinfo, NULL, True );
if (!m_context)
{
throw std::runtime_error("Error: glXCreateContext failed");
}
XFree(visinfo);
}
void mainLoop() {
for (int i = 0; i < (m_visible ? 10000 : 10); ++i) {
drawFrame();
}
}
void cleanup() {
if (m_display) {
glXMakeCurrent(m_display, None, nullptr);
if (m_context) {
glXDestroyContext(m_display, m_context);
}
if (m_window) {
XDestroyWindow(m_display, m_window);
}
XCloseDisplay(m_display);
}
}
void drawFrame() {
drawTriangle();
glXSwapBuffers(m_display, m_window);
}
};
enum {
OPTION_HELP = 1,
OPTION_VERSION,
OPTION_VISIBLE,
};
static struct option long_options[] = {
{ "help", no_argument, NULL, OPTION_HELP },
{ "version", no_argument, NULL, OPTION_VERSION },
{ "visible", no_argument, NULL, OPTION_VISIBLE },
{ NULL, 0, NULL, 0 }
};
static void usage(int code) __attribute__((__noreturn__));
static void usage(int code) {
std::ostream& stream = (code == EXIT_SUCCESS ? std::cout : std::cerr);
stream << "Usage: " << argv0 << " [OPTIONS]" << std::endl;
stream << "Options:" << std::endl;
stream << "--help\t\tShow this help and exit" << std::endl;
stream << "--visible\tMake test window visible" << std::endl;
stream << "--version\tShow version and exit" << std::endl;
std::exit(code);
}
int main(int argc, char** argv) {
int opt;
bool visible = false;
argv0 = argv[0];
while ((opt = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
switch (opt) {
case OPTION_HELP:
usage(0);
break; // not reached
case OPTION_VERSION:
/* Output version number as YAML for machine-readability,
* inspired by `ostree --version` and `docker version` */
std::cout << argv[0] << ":" << std::endl
<< " Package: steam-runtime-tools" << std::endl
<< " Version: " << VERSION << std::endl;
return EXIT_SUCCESS;
case OPTION_VISIBLE:
visible = true;
break;
case '?':
default:
usage(2);
break; // not reached
}
}
HelloTriangleGLApplication app(visible);
try {
app.run();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
......@@ -67,7 +67,7 @@ executable(
# Deliberately no RPATH/RUNPATH here: we want to determine whether
# a game with no special linking would be able to use libvulkan
# and its associated drivers successfully.
)
)
custom_target(
'frag.spv',
......@@ -109,4 +109,16 @@ custom_target(
)
)
executable(
multiarch + '-check-gl',
'check-gl.cpp',
dependencies : [xlib, gl],
include_directories : project_include_dirs,
install : true,
install_dir : join_paths(
get_option('libexecdir'),
'steam-runtime-tools-' + api_major,
)
)
# vim:set sw=2 sts=2 et:
......@@ -190,6 +190,14 @@ xcb = dependency(
'xcb',
)
gl = dependency(
'gl'
)
xlib = dependency(
'x11'
)
libdl = c_compiler.find_library('dl', required : false)
project_include_dirs = include_directories('.')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment