mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2024-11-24 19:29:14 +08:00
205 lines
8.2 KiB
C
205 lines
8.2 KiB
C
/* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
|
|
Display *display;
|
|
int screen;
|
|
Window win = 0;
|
|
|
|
void error_exit(const char *format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
vfprintf(stderr, format, args);
|
|
va_end(args);
|
|
exit(1);
|
|
}
|
|
|
|
#include <EGL/egl.h>
|
|
#include <EGL/eglext.h>
|
|
|
|
#define GET_GLERROR(ret) \
|
|
{ \
|
|
GLenum err = glGetError(); \
|
|
if (err != GL_NO_ERROR) { \
|
|
fprintf(stderr, "[%s line %d] OpenGL Error: 0x%x\n", __FILE__, __LINE__, \
|
|
err); \
|
|
fflush(stderr); \
|
|
\
|
|
switch (err) { \
|
|
case GL_INVALID_ENUM: \
|
|
printf("GL_INVALID_ENUM\n"); \
|
|
break; \
|
|
case GL_INVALID_VALUE: \
|
|
printf("GL_INVALID_VALUE\n"); \
|
|
break; \
|
|
case GL_INVALID_OPERATION: \
|
|
printf("GL_INVALID_OPERATION\n"); \
|
|
break; \
|
|
case GL_OUT_OF_MEMORY: \
|
|
printf("GL_OUT_OF_MEMORY\n"); \
|
|
break; \
|
|
case GL_INVALID_FRAMEBUFFER_OPERATION: \
|
|
printf("GL_INVALID_FRAMEBUFFER_OPERATION\n"); \
|
|
break; \
|
|
default: \
|
|
printf("UKNOWN OPENGL ERROR CODE 0x%x\n", err); \
|
|
}; \
|
|
} \
|
|
}
|
|
|
|
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
|
|
EGLSurface eglSurface = EGL_NO_SURFACE;
|
|
EGLContext eglContext = EGL_NO_CONTEXT;
|
|
|
|
int graphics_setup_window(int xpos, int ypos, int width, int height,
|
|
const char *windowname) {
|
|
EGLint configAttrs[] = {
|
|
EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 16,
|
|
EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, 0,
|
|
// EGL_CONFORMANT, EGL_OPENGL_BIT,
|
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // 3_BIT_KHR,
|
|
EGL_NONE};
|
|
EGLint contextAttrs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
|
|
|
|
EGLConfig *configList = NULL;
|
|
EGLint configCount;
|
|
|
|
display = XOpenDisplay(NULL);
|
|
if (!display) error_exit("Error opening X display.\n");
|
|
|
|
screen = DefaultScreen(display);
|
|
|
|
eglDisplay = eglGetDisplay(0);
|
|
|
|
if (eglDisplay == EGL_NO_DISPLAY)
|
|
error_exit("EGL failed to obtain display\n");
|
|
|
|
if (!eglInitialize(eglDisplay, 0, 0))
|
|
error_exit("EGL failed to initialize\n");
|
|
|
|
if (!eglChooseConfig(eglDisplay, configAttrs, NULL, 0, &configCount) ||
|
|
!configCount)
|
|
error_exit("EGL failed to return any matching configurations\n");
|
|
|
|
configList = (EGLConfig *)malloc(configCount * sizeof(EGLConfig));
|
|
|
|
if (!eglChooseConfig(eglDisplay, configAttrs, configList, configCount,
|
|
&configCount) ||
|
|
!configCount)
|
|
error_exit("EGL failed to populate configuration list\n");
|
|
|
|
Window xRootWindow = DefaultRootWindow(display);
|
|
XSetWindowAttributes xCreateWindowAttributes;
|
|
xCreateWindowAttributes.event_mask = ExposureMask;
|
|
win = XCreateWindow(display, xRootWindow, 0, 0, width, height, 0,
|
|
CopyFromParent, InputOutput, CopyFromParent, CWEventMask,
|
|
&xCreateWindowAttributes);
|
|
XMapWindow(display, win);
|
|
|
|
Atom netWmStateAtom = XInternAtom(display, "_NET_WM_STATE", false);
|
|
XEvent xEvent;
|
|
memset(&xEvent, 0, sizeof(xEvent));
|
|
xEvent.type = ClientMessage;
|
|
xEvent.xclient.window = win;
|
|
xEvent.xclient.message_type = netWmStateAtom;
|
|
xEvent.xclient.format = 32;
|
|
xEvent.xclient.data.l[0] = 1;
|
|
xEvent.xclient.data.l[1] = false;
|
|
XSendEvent(display, xRootWindow, false, SubstructureNotifyMask, &xEvent);
|
|
|
|
XStoreName(display, win, windowname);
|
|
|
|
XSelectInput(display, win,
|
|
ExposureMask | KeyPressMask | ButtonPressMask |
|
|
ButtonReleaseMask | KeyReleaseMask | VisibilityChangeMask |
|
|
PointerMotionMask);
|
|
|
|
EGLint windowAttrs[] = {EGL_NONE};
|
|
|
|
eglSurface = eglCreateWindowSurface(eglDisplay, configList[0],
|
|
(EGLNativeWindowType)win, windowAttrs);
|
|
|
|
if (!eglSurface) error_exit("EGL couldn't create window\n");
|
|
|
|
eglBindAPI(EGL_OPENGL_ES_API);
|
|
|
|
eglContext = eglCreateContext(eglDisplay, configList[0], NULL, contextAttrs);
|
|
if (!eglContext) error_exit("EGL couldn't create context\n");
|
|
|
|
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext))
|
|
error_exit("EGL couldn't make context/surface current\n");
|
|
|
|
EGLint Context_RendererType;
|
|
eglQueryContext(eglDisplay, eglContext, EGL_CONTEXT_CLIENT_TYPE,
|
|
&Context_RendererType);
|
|
|
|
switch (Context_RendererType) {
|
|
case EGL_OPENGL_API:
|
|
printf("Using OpenGL API is not supported\n");
|
|
exit(EXIT_FAILURE);
|
|
break;
|
|
case EGL_OPENGL_ES_API:
|
|
printf("Using OpenGL ES API\n");
|
|
break;
|
|
case EGL_OPENVG_API:
|
|
error_exit("Context Query Returned OpenVG. This is Unsupported\n");
|
|
default:
|
|
error_exit("Unknown Context Type. %04X\n", Context_RendererType);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void graphics_set_windowtitle(const char *windowname) {
|
|
XStoreName(display, win, windowname);
|
|
}
|
|
|
|
void graphics_swap_buffers() { eglSwapBuffers(eglDisplay, eglSurface); }
|
|
|
|
void graphics_close_window() {
|
|
if (eglDisplay != EGL_NO_DISPLAY) {
|
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
|
|
if (eglContext != EGL_NO_CONTEXT) eglDestroyContext(eglDisplay, eglContext);
|
|
|
|
if (eglSurface != EGL_NO_SURFACE) eglDestroySurface(eglDisplay, eglSurface);
|
|
|
|
eglTerminate(eglDisplay);
|
|
}
|
|
|
|
if (display) {
|
|
if (win) XDestroyWindow(display, win);
|
|
|
|
XCloseDisplay(display);
|
|
}
|
|
}
|