- gc = __glXGetCurrentContext();
-
- dri3_flush(psc, pdraw, __DRI2_FLUSH_DRAWABLE, __DRI2_THROTTLE_FLUSHFRONT);
-
- dri3_wait_gl(gc);
-}
-
-static uint32_t
-dri3_cpp_for_format(uint32_t format) {
- switch (format) {
- case __DRI_IMAGE_FORMAT_R8:
- return 1;
- case __DRI_IMAGE_FORMAT_RGB565:
- case __DRI_IMAGE_FORMAT_GR88:
- return 2;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- case __DRI_IMAGE_FORMAT_ARGB8888:
- case __DRI_IMAGE_FORMAT_ABGR8888:
- case __DRI_IMAGE_FORMAT_XBGR8888:
- case __DRI_IMAGE_FORMAT_XRGB2101010:
- case __DRI_IMAGE_FORMAT_ARGB2101010:
- case __DRI_IMAGE_FORMAT_SARGB8:
- return 4;
- case __DRI_IMAGE_FORMAT_NONE:
- default:
- return 0;
- }
-}
-
-
-/** dri3_alloc_render_buffer
- *
- * Use the driver createImage function to construct a __DRIimage, then
- * get a file descriptor for that and create an X pixmap from that
- *
- * Allocate an xshmfence for synchronization
- */
-static struct dri3_buffer *
-dri3_alloc_render_buffer(struct glx_screen *glx_screen, Drawable draw,
- unsigned int format, int width, int height, int depth)
-{
- struct dri3_screen *psc = (struct dri3_screen *) glx_screen;
- Display *dpy = glx_screen->dpy;
- struct dri3_buffer *buffer;
- __DRIimage *pixmap_buffer;
- xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_pixmap_t pixmap;
- xcb_sync_fence_t sync_fence;
- struct xshmfence *shm_fence;
- int buffer_fd, fence_fd;
- int stride;
-
- /* Create an xshmfence object and
- * prepare to send that to the X server
- */
-
- fence_fd = xshmfence_alloc_shm();
- if (fence_fd < 0) {
- ErrorMessageF("DRI3 Fence object allocation failure %s\n", strerror(errno));
- return NULL;
- }
- shm_fence = xshmfence_map_shm(fence_fd);
- if (shm_fence == NULL) {
- ErrorMessageF("DRI3 Fence object map failure %s\n", strerror(errno));
- goto no_shm_fence;
- }
-
- /* Allocate the image from the driver
- */
- buffer = calloc(1, sizeof (struct dri3_buffer));
- if (!buffer)
- goto no_buffer;
-
- buffer->cpp = dri3_cpp_for_format(format);
- if (!buffer->cpp) {
- ErrorMessageF("DRI3 buffer format %d invalid\n", format);
- goto no_image;
- }
-
- if (!psc->is_different_gpu) {
- buffer->image = (*psc->image->createImage) (psc->driScreen,
- width, height,
- format,
- __DRI_IMAGE_USE_SHARE |
- __DRI_IMAGE_USE_SCANOUT,
- buffer);
- pixmap_buffer = buffer->image;
-
- if (!buffer->image) {
- ErrorMessageF("DRI3 gpu image creation failure\n");
- goto no_image;
- }
- } else {
- buffer->image = (*psc->image->createImage) (psc->driScreen,
- width, height,
- format,
- 0,
- buffer);
-
- if (!buffer->image) {
- ErrorMessageF("DRI3 other gpu image creation failure\n");
- goto no_image;
- }
-
- buffer->linear_buffer = (*psc->image->createImage) (psc->driScreen,
- width, height,
- format,
- __DRI_IMAGE_USE_SHARE |
- __DRI_IMAGE_USE_LINEAR,
- buffer);
- pixmap_buffer = buffer->linear_buffer;
-
- if (!buffer->linear_buffer) {
- ErrorMessageF("DRI3 gpu linear image creation failure\n");
- goto no_linear_buffer;
- }
- }
-
- /* X wants the stride, so ask the image for it
- */
- if (!(*psc->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE, &stride)) {
- ErrorMessageF("DRI3 get image stride failed\n");
- goto no_buffer_attrib;
- }
-
- buffer->pitch = stride;
-
- if (!(*psc->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD, &buffer_fd)) {
- ErrorMessageF("DRI3 get image FD failed\n");
- goto no_buffer_attrib;
- }
-
- xcb_dri3_pixmap_from_buffer(c,
- (pixmap = xcb_generate_id(c)),
- draw,
- buffer->size,
- width, height, buffer->pitch,
- depth, buffer->cpp * 8,
- buffer_fd);
-
- xcb_dri3_fence_from_fd(c,
- pixmap,
- (sync_fence = xcb_generate_id(c)),
- false,
- fence_fd);
-
- buffer->pixmap = pixmap;
- buffer->own_pixmap = true;
- buffer->sync_fence = sync_fence;
- buffer->shm_fence = shm_fence;
- buffer->width = width;
- buffer->height = height;
-
- /* Mark the buffer as idle
- */
- dri3_fence_set(buffer);
-
- return buffer;
-
-no_buffer_attrib:
- (*psc->image->destroyImage)(pixmap_buffer);
-no_linear_buffer:
- if (psc->is_different_gpu)
- (*psc->image->destroyImage)(buffer->image);
-no_image:
- free(buffer);
-no_buffer:
- xshmfence_unmap_shm(shm_fence);
-no_shm_fence:
- close(fence_fd);
- ErrorMessageF("DRI3 alloc_render_buffer failed\n");
- return NULL;
-}