Esempio n. 1
0
static struct vl_dri3_buffer *
dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
{
   struct vl_dri3_buffer *buffer;
   xcb_pixmap_t pixmap;
   xcb_sync_fence_t sync_fence;
   struct xshmfence *shm_fence;
   int buffer_fd, fence_fd;
   struct pipe_resource templ;
   struct winsys_handle whandle;
   unsigned usage;

   buffer = CALLOC_STRUCT(vl_dri3_buffer);
   if (!buffer)
      return NULL;

   fence_fd = xshmfence_alloc_shm();
   if (fence_fd < 0)
      goto free_buffer;

   shm_fence = xshmfence_map_shm(fence_fd);
   if (!shm_fence)
      goto close_fd;

   memset(&templ, 0, sizeof(templ));
   templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
                PIPE_BIND_SCANOUT | PIPE_BIND_SHARED;
   templ.format = PIPE_FORMAT_B8G8R8X8_UNORM;
   templ.target = PIPE_TEXTURE_2D;
   templ.last_level = 0;
   templ.width0 = scrn->width;
   templ.height0 = scrn->height;
   templ.depth0 = 1;
   templ.array_size = 1;
   buffer->texture = scrn->base.pscreen->resource_create(scrn->base.pscreen,
                                                         &templ);
   if (!buffer->texture)
      goto unmap_shm;

   memset(&whandle, 0, sizeof(whandle));
   whandle.type= DRM_API_HANDLE_TYPE_FD;
   usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
   scrn->base.pscreen->resource_get_handle(scrn->base.pscreen,
                                           buffer->texture, &whandle,
                                           usage);
   buffer_fd = whandle.handle;
   buffer->pitch = whandle.stride;
   xcb_dri3_pixmap_from_buffer(scrn->conn,
                               (pixmap = xcb_generate_id(scrn->conn)),
                               scrn->drawable,
                               0,
                               scrn->width, scrn->height, buffer->pitch,
                               scrn->depth, 32,
                               buffer_fd);
   xcb_dri3_fence_from_fd(scrn->conn,
                          pixmap,
                          (sync_fence = xcb_generate_id(scrn->conn)),
                          false,
                          fence_fd);

   buffer->pixmap = pixmap;
   buffer->sync_fence = sync_fence;
   buffer->shm_fence = shm_fence;
   buffer->width = scrn->width;
   buffer->height = scrn->height;

   xshmfence_trigger(buffer->shm_fence);

   return buffer;

unmap_shm:
   xshmfence_unmap_shm(shm_fence);
close_fd:
   close(fence_fd);
free_buffer:
   FREE(buffer);
   return NULL;
}
Esempio n. 2
0
static VkResult
x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
               const VkSwapchainCreateInfoKHR *pCreateInfo,
               const VkAllocationCallbacks* pAllocator,
               struct x11_image *image)
{
   xcb_void_cookie_t cookie;
   VkResult result;
   uint32_t row_pitch;
   uint32_t offset;
   uint32_t bpp = 32;
   int fd;
   uint32_t size;

   result = chain->base.image_fns->create_wsi_image(device_h,
                                                    pCreateInfo,
                                                    pAllocator,
                                                    &image->image,
                                                    &image->memory,
                                                    &size,
                                                    &offset,
                                                    &row_pitch,
                                                    &fd);
   if (result != VK_SUCCESS)
      return result;

   image->pixmap = xcb_generate_id(chain->conn);

   cookie =
      xcb_dri3_pixmap_from_buffer_checked(chain->conn,
                                          image->pixmap,
                                          chain->window,
                                          size,
                                          pCreateInfo->imageExtent.width,
                                          pCreateInfo->imageExtent.height,
                                          row_pitch,
                                          chain->depth, bpp, fd);
   xcb_discard_reply(chain->conn, cookie.sequence);

   int fence_fd = xshmfence_alloc_shm();
   if (fence_fd < 0)
      goto fail_pixmap;

   image->shm_fence = xshmfence_map_shm(fence_fd);
   if (image->shm_fence == NULL)
      goto fail_shmfence_alloc;

   image->sync_fence = xcb_generate_id(chain->conn);
   xcb_dri3_fence_from_fd(chain->conn,
                          image->pixmap,
                          image->sync_fence,
                          false,
                          fence_fd);

   image->busy = false;
   xshmfence_trigger(image->shm_fence);

   return VK_SUCCESS;

fail_shmfence_alloc:
   close(fence_fd);

fail_pixmap:
   cookie = xcb_free_pixmap(chain->conn, image->pixmap);
   xcb_discard_reply(chain->conn, cookie.sequence);

   chain->base.image_fns->free_wsi_image(device_h, pAllocator,
                                        image->image, image->memory);

   return result;
}
Esempio n. 3
0
static inline void
dri3_fence_set(struct loader_dri3_buffer *buffer)
{
   xshmfence_trigger(buffer->shm_fence);
}
Esempio n. 4
0
static struct vl_dri3_buffer *
dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
{
   struct vl_dri3_buffer *buffer;
   xcb_pixmap_t pixmap;
   xcb_sync_fence_t sync_fence;
   struct xshmfence *shm_fence;
   int buffer_fd, fence_fd;
   struct pipe_resource templ, *pixmap_buffer_texture;
   struct winsys_handle whandle;
   unsigned usage;

   buffer = CALLOC_STRUCT(vl_dri3_buffer);
   if (!buffer)
      return NULL;

   fence_fd = xshmfence_alloc_shm();
   if (fence_fd < 0)
      goto free_buffer;

   shm_fence = xshmfence_map_shm(fence_fd);
   if (!shm_fence)
      goto close_fd;

   memset(&templ, 0, sizeof(templ));
   templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
   templ.format = vl_dri2_format_for_depth(&scrn->base, scrn->depth);
   templ.target = PIPE_TEXTURE_2D;
   templ.last_level = 0;
   templ.width0 = (scrn->output_texture) ?
                  scrn->output_texture->width0 : scrn->width;
   templ.height0 = (scrn->output_texture) ?
                   scrn->output_texture->height0 : scrn->height;
   templ.depth0 = 1;
   templ.array_size = 1;

   if (scrn->is_different_gpu) {
      buffer->texture = (scrn->output_texture) ? scrn->output_texture :
                        scrn->base.pscreen->resource_create(scrn->base.pscreen, &templ);
      if (!buffer->texture)
         goto unmap_shm;

      templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED |
                    PIPE_BIND_LINEAR;
      buffer->linear_texture =
          scrn->base.pscreen->resource_create(scrn->base.pscreen, &templ);
      pixmap_buffer_texture = buffer->linear_texture;

      if (!buffer->linear_texture)
         goto no_linear_texture;
   } else {
      templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED;
      buffer->texture = (scrn->output_texture) ? scrn->output_texture :
                        scrn->base.pscreen->resource_create(scrn->base.pscreen, &templ);
      if (!buffer->texture)
         goto unmap_shm;
      pixmap_buffer_texture = buffer->texture;
   }
   memset(&whandle, 0, sizeof(whandle));
   whandle.type= WINSYS_HANDLE_TYPE_FD;
   usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
   scrn->base.pscreen->resource_get_handle(scrn->base.pscreen, NULL,
                                           pixmap_buffer_texture, &whandle,
                                           usage);
   buffer_fd = whandle.handle;
   buffer->pitch = whandle.stride;
   buffer->width = templ.width0;
   buffer->height = templ.height0;

   xcb_dri3_pixmap_from_buffer(scrn->conn,
                               (pixmap = xcb_generate_id(scrn->conn)),
                               scrn->drawable,
                               0,
                               buffer->width, buffer->height, buffer->pitch,
                               scrn->depth, 32,
                               buffer_fd);
   xcb_dri3_fence_from_fd(scrn->conn,
                          pixmap,
                          (sync_fence = xcb_generate_id(scrn->conn)),
                          false,
                          fence_fd);

   buffer->pixmap = pixmap;
   buffer->sync_fence = sync_fence;
   buffer->shm_fence = shm_fence;

   xshmfence_trigger(buffer->shm_fence);

   return buffer;

no_linear_texture:
   pipe_resource_reference(&buffer->texture, NULL);
unmap_shm:
   xshmfence_unmap_shm(shm_fence);
close_fd:
   close(fence_fd);
free_buffer:
   FREE(buffer);
   return NULL;
}