swapchain_t device_create_swapchain(device_t device, struct gs_init_data *info) { struct gs_swap_chain *swap = bmalloc(sizeof(struct gs_swap_chain)); memset(swap, 0, sizeof(struct gs_swap_chain)); swap->device = device; swap->info = *info; swap->wi = gl_windowinfo_create(info); if (!swap->wi) { blog(LOG_ERROR, "device_create_swapchain (GL) failed"); swapchain_destroy(swap); return NULL; } return swap; }
gs_swapchain_t device_swapchain_create(gs_device_t device, struct gs_init_data *info) { struct gs_swap_chain *swap = bzalloc(sizeof(struct gs_swap_chain)); swap->device = device; swap->info = *info; swap->wi = gl_windowinfo_create(info); if (!swap->wi) { blog(LOG_ERROR, "device_swapchain_create (GL) failed"); gs_swapchain_destroy(swap); return NULL; } if (!gl_platform_init_swapchain(swap)) { blog(LOG_ERROR, "gl_platform_init_swapchain failed"); gs_swapchain_destroy(swap); return NULL; } return swap; }
struct gl_platform *gl_platform_create(device_t device, struct gs_init_data *info) { int num_configs = 0; int error_base = 0, event_base = 0; Display *display = XOpenDisplay(NULL); /* Open default screen */ struct gl_platform *plat = bmalloc(sizeof(struct gl_platform)); GLXFBConfig* configs; print_info_stuff(info); memset(plat, 0, sizeof(struct gl_platform)); if (!display) { blog(LOG_ERROR, "Unable to find display. DISPLAY variable may not be set correctly."); goto fail0; } if (!glx_LoadFunctions(display, DefaultScreen(display))) { blog(LOG_ERROR, "Unable to load GLX entry functions."); goto fail0; } if (!glXQueryExtension(display, &error_base, &event_base)) { blog(LOG_ERROR, "GLX not supported."); goto fail0; } /* We require glX version 1.4 */ { int major = 0, minor = 0; glXQueryVersion(display, &major, &minor); if (major < 1 || minor < 4) { blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: 1.4", major, minor); goto fail0; } } if (!glx_ext_ARB_create_context) { blog(LOG_ERROR, "ARB_GLX_create_context not supported!"); goto fail0; } configs = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs, &num_configs); if(!configs) { blog(LOG_ERROR, "Attribute list or screen is invalid."); goto fail0; } if(num_configs == 0) { blog(LOG_ERROR, "No framebuffer configurations found."); goto fail1; } /* We just use the first configuration found... as it does everything we want at the very least. */ plat->context = glXCreateContextAttribsARB(display, configs[0], NULL, True, ctx_attribs); if(!plat->context) { blog(LOG_ERROR, "Failed to create OpenGL context."); goto fail1; } if(!glXMakeCurrent(display, info->window.id, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail2; } if (!ogl_LoadFunctions()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail2; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); plat->swap.device = device; plat->swap.info = *info; plat->swap.wi = gl_windowinfo_create(info); plat->swap.wi->display = display; XFree(configs); XSync(display, False); return plat; fail2: glXMakeCurrent(display, None, NULL); glXDestroyContext(display, plat->context); fail1: XFree(configs); fail0: bfree(plat); return NULL; }
struct gl_platform *gl_platform_create(device_t device, struct gs_init_data *info) { int num_configs = 0; int error_base = 0, event_base = 0; Display *display = info->window.display; struct gl_platform *plat = bzalloc(sizeof(struct gl_platform)); GLXFBConfig* configs; XWindowAttributes attrs; int screen; int major = 0, minor = 0; print_info_stuff(info); if (!display) { blog(LOG_ERROR, "Unable to find display. DISPLAY variable " "may not be set correctly."); goto fail0; } if (!XGetWindowAttributes(display, info->window.id, &attrs)) { blog(LOG_ERROR, "Failed getting window attributes"); goto fail0; } screen = XScreenNumberOfScreen(attrs.screen); if (!gladLoadGLX(display, screen)) { blog(LOG_ERROR, "Unable to load GLX entry functions."); goto fail0; } if (!glXQueryExtension(display, &error_base, &event_base)) { blog(LOG_ERROR, "GLX not supported."); goto fail0; } /* We require glX version 1.3 */ glXQueryVersion(display, &major, &minor); if (major < 1 || (major == 1 && minor < 3)) { blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: " "1.3", major, minor); goto fail0; } if (!GLAD_GLX_ARB_create_context) { blog(LOG_ERROR, "ARB_GLX_create_context not supported!"); goto fail0; } configs = glXChooseFBConfig(display, screen, fb_attribs, &num_configs); if (!configs) { blog(LOG_ERROR, "Attribute list or screen is invalid."); goto fail0; } if (num_configs == 0) { XFree(configs); blog(LOG_ERROR, "No framebuffer configurations found."); goto fail0; } plat->fbcfg = configs[0]; XFree(configs); handle_x_error(display, NULL); /* We just use the first configuration found... as it does everything * we want at the very least. */ plat->context = glXCreateContextAttribsARB(display, plat->fbcfg, NULL, true, ctx_attribs); if (!plat->context) { blog(LOG_ERROR, "Failed to create OpenGL context."); goto fail0; } if (handle_x_error(display, "Failed to create OpenGL context.")) goto fail2; device->plat = plat; plat->swap.device = device; plat->swap.info.window.id = info->window.id; plat->swap.info.window.display = display; plat->swap.info.format = GS_RGBA; plat->swap.info.zsformat = GS_Z24_S8; plat->swap.info.num_backbuffers = 1; plat->swap.info.adapter = info->adapter; plat->swap.info.cx = attrs.width; plat->swap.info.cy = attrs.height; plat->swap.wi = gl_windowinfo_create(info); if (!gl_platform_init_swapchain(&plat->swap)) goto fail2; if (!glXMakeCurrent(display, plat->swap.wi->glxid, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail2; } if (!gladLoadGL()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail2; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); /* We assume later that cur_swap is already set. */ device->cur_swap = &plat->swap; XSync(display, false); blog(LOG_INFO, "Created new platform data"); return plat; fail2: glXMakeCurrent(display, None, NULL); glXDestroyContext(display, plat->context); gl_platform_cleanup_swapchain(&plat->swap); fail0: bfree(plat); device->plat = 0; return NULL; }
extern struct gl_platform *gl_platform_create(gs_device_t *device, const struct gs_init_data *info) { /* There's some trickery here... we're mixing libX11, xcb, and GLX For an explanation see here: http://xcb.freedesktop.org/MixingCalls/ Essentially, GLX requires Xlib. Everything else we use xcb. */ struct gl_windowinfo *wi = gl_windowinfo_create(info); struct gl_platform * plat = bmalloc(sizeof(struct gl_platform)); Display * display; print_info_stuff(info); if (!wi) { blog(LOG_ERROR, "Failed to create window info!"); goto fail_wi_create; } display = XOpenDisplay(XDisplayString(info->window.display)); if (!display) { blog(LOG_ERROR, "Unable to open new X connection!"); goto fail_display_open; } XSetEventQueueOwner(display, XCBOwnsEventQueue); XSetErrorHandler(x_error_handler); /* We assume later that cur_swap is already set. */ device->cur_swap = &plat->swap; device->plat = plat; plat->display = display; plat->swap.device = device; plat->swap.info = *info; plat->swap.wi = wi; if (!gl_platform_init_swapchain(&plat->swap)) { blog(LOG_ERROR, "Failed to initialize swap chain!"); goto fail_init_swapchain; } if (!gl_context_create(plat)) { blog(LOG_ERROR, "Failed to create context!"); goto fail_context_create; } if (!glXMakeCurrent(plat->display, wi->window, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail_make_current; } if (!gladLoadGL()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail_load_gl; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); goto success; fail_make_current: gl_context_destroy(plat); fail_context_create: fail_load_gl: fail_init_swapchain: XCloseDisplay(display); fail_display_open: fail_wi_create: gl_windowinfo_destroy(wi); free(plat); plat = NULL; success: return plat; }