static struct native_display * native_create_display(void *dpy, boolean use_sw) { struct gbm_gallium_drm_device *gbm; int fd; int own_gbm = 0; gbm = dpy; if (gbm == NULL) { fd = open("/dev/dri/card0", O_RDWR); /* FIXME: Use an internal constructor to create a gbm * device with gallium backend directly, without setenv */ setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1); gbm = gbm_gallium_drm_device(gbm_create_device(fd)); own_gbm = 1; } if (gbm == NULL) return NULL; if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 || gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) { if (own_gbm) gbm_device_destroy(&gbm->base.base); return NULL; } return drm_create_display(gbm, own_gbm, drm_event_handler); }
static void gbm_gallium_drm_destroy(struct gbm_device *gbm) { struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); gallium_screen_destroy(gdrm); FREE(gdrm); }
static struct gbm_bo * gbm_gallium_drm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, enum gbm_bo_format format, uint32_t usage) { struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); struct gbm_gallium_drm_bo *bo; struct pipe_resource templ; struct winsys_handle whandle; enum pipe_format pf; bo = CALLOC_STRUCT(gbm_gallium_drm_bo); if (bo == NULL) return NULL; bo->base.base.gbm = gbm; bo->base.base.width = width; bo->base.base.height = height; bo->base.base.format = format; pf = gbm_format_to_gallium(format); if (pf == PIPE_FORMAT_NONE) return NULL; memset(&templ, 0, sizeof(templ)); templ.bind = gbm_usage_to_gallium(usage); templ.format = pf; templ.target = PIPE_TEXTURE_2D; templ.last_level = 0; templ.width0 = width; templ.height0 = height; templ.depth0 = 1; templ.array_size = 1; bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ); if (bo->resource == NULL) { FREE(bo); return NULL; } memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); bo->base.base.handle.u32 = whandle.handle; bo->base.base.stride = whandle.stride; return &bo->base.base; }
static int gbm_gallium_drm_is_format_supported(struct gbm_device *gbm, enum gbm_bo_format format, uint32_t usage) { struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); enum pipe_format pf; pf = gbm_format_to_gallium(format); if (pf == PIPE_FORMAT_NONE) return 0; if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0, gbm_usage_to_gallium(usage))) return 0; if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888) return 0; return 1; }
static struct native_display * native_create_display(void *dpy, boolean use_sw) { struct gbm_gallium_drm_device *gbm; int fd; int own_gbm = 0; gbm = dpy; if (gbm == NULL) { const char *device_name="/dev/dri/card0"; #ifdef O_CLOEXEC fd = open(device_name, O_RDWR | O_CLOEXEC); if (fd == -1 && errno == EINVAL) #endif { fd = open(device_name, O_RDWR); if (fd != -1) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); } /* FIXME: Use an internal constructor to create a gbm * device with gallium backend directly, without setenv */ setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1); gbm = gbm_gallium_drm_device(gbm_create_device(fd)); own_gbm = 1; } if (gbm == NULL) return NULL; if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 || gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) { if (own_gbm) gbm_device_destroy(&gbm->base.base); return NULL; } return drm_create_display(gbm, own_gbm, drm_event_handler); }
static struct gbm_bo * gbm_gallium_drm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t usage) { struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); struct gbm_gallium_drm_bo *bo; struct winsys_handle whandle; struct pipe_resource *resource; switch (type) { #if HAVE_WAYLAND_PLATFORM case GBM_BO_IMPORT_WL_BUFFER: { struct wl_drm_buffer *wb = (struct wl_drm_buffer *) buffer; resource = wb->driver_buffer; break; } #endif case GBM_BO_IMPORT_EGL_IMAGE: if (!gdrm->lookup_egl_image) return NULL; resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data, buffer); if (resource == NULL) return NULL; break; default: return NULL; } bo = CALLOC_STRUCT(gbm_gallium_drm_bo); if (bo == NULL) return NULL; bo->base.base.gbm = gbm; bo->base.base.width = resource->width0; bo->base.base.height = resource->height0; switch (resource->format) { case PIPE_FORMAT_B8G8R8X8_UNORM: bo->base.base.format = GBM_BO_FORMAT_XRGB8888; break; case PIPE_FORMAT_B8G8R8A8_UNORM: bo->base.base.format = GBM_BO_FORMAT_ARGB8888; break; default: FREE(bo); return NULL; } pipe_resource_reference(&bo->resource, resource); memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); bo->base.base.handle.u32 = whandle.handle; bo->base.base.stride = whandle.stride; return &bo->base.base; }