Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19.  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20.  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Benjamin Franzke <benjaminfranzke@googlemail.com>
  26.  */
  27.  
  28. #include "util/u_memory.h"
  29. #include "util/u_inlines.h"
  30.  
  31. #include "state_tracker/drm_driver.h"
  32.  
  33. #include <unistd.h>
  34. #include <sys/types.h>
  35.  
  36. #include "gbm_gallium_drmint.h"
  37.  
  38. /* For importing wl_buffer */
  39. #if HAVE_WAYLAND_PLATFORM
  40. #include "../../../egl/wayland/wayland-drm/wayland-drm.h"
  41. #endif
  42.  
  43. static INLINE enum pipe_format
  44. gbm_format_to_gallium(enum gbm_bo_format format)
  45. {
  46.    switch (format) {
  47.    case GBM_BO_FORMAT_XRGB8888:
  48.       return PIPE_FORMAT_BGRX8888_UNORM;
  49.    case GBM_BO_FORMAT_ARGB8888:
  50.       return PIPE_FORMAT_BGRA8888_UNORM;
  51.    default:
  52.       return PIPE_FORMAT_NONE;
  53.    }
  54.  
  55.    return PIPE_FORMAT_NONE;
  56. }
  57.  
  58. static INLINE uint
  59. gbm_usage_to_gallium(uint usage)
  60. {
  61.    uint resource_usage = 0;
  62.  
  63.    if (usage & GBM_BO_USE_SCANOUT)
  64.       resource_usage |= PIPE_BIND_SCANOUT;
  65.  
  66.    if (usage & GBM_BO_USE_RENDERING)
  67.       resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
  68.  
  69.    if (usage & GBM_BO_USE_CURSOR_64X64)
  70.       resource_usage |= PIPE_BIND_CURSOR;
  71.  
  72.    return resource_usage;
  73. }
  74.  
  75. static int
  76. gbm_gallium_drm_is_format_supported(struct gbm_device *gbm,
  77.                                     enum gbm_bo_format format,
  78.                                     uint32_t usage)
  79. {
  80.    struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
  81.    enum pipe_format pf;
  82.  
  83.    pf = gbm_format_to_gallium(format);
  84.    if (pf == PIPE_FORMAT_NONE)
  85.       return 0;
  86.  
  87.    if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0,
  88.                                           gbm_usage_to_gallium(usage)))
  89.       return 0;
  90.  
  91.    if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888)
  92.       return 0;
  93.  
  94.    return 1;
  95. }
  96.  
  97. static void
  98. gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo)
  99. {
  100.    struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo);
  101.  
  102.    pipe_resource_reference(&bo->resource, NULL);
  103.    free(bo);
  104. }
  105.  
  106. static struct gbm_bo *
  107. gbm_gallium_drm_bo_import(struct gbm_device *gbm,
  108.                           uint32_t type, void *buffer, uint32_t usage)
  109. {
  110.    struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
  111.    struct gbm_gallium_drm_bo *bo;
  112.    struct winsys_handle whandle;
  113.    struct pipe_resource *resource;
  114.  
  115.    switch (type) {
  116. #if HAVE_WAYLAND_PLATFORM
  117.    case GBM_BO_IMPORT_WL_BUFFER:
  118.    {
  119.       struct wl_drm_buffer *wb = (struct wl_drm_buffer *) buffer;
  120.  
  121.       resource = wb->driver_buffer;
  122.       break;
  123.    }
  124. #endif
  125.  
  126.    case GBM_BO_IMPORT_EGL_IMAGE:
  127.       if (!gdrm->lookup_egl_image)
  128.          return NULL;
  129.  
  130.       resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data, buffer);
  131.       if (resource == NULL)
  132.          return NULL;
  133.       break;
  134.  
  135.    default:
  136.       return NULL;
  137.    }
  138.  
  139.    bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
  140.    if (bo == NULL)
  141.       return NULL;
  142.  
  143.    bo->base.base.gbm = gbm;
  144.    bo->base.base.width = resource->width0;
  145.    bo->base.base.height = resource->height0;
  146.  
  147.    switch (resource->format) {
  148.    case PIPE_FORMAT_BGRX8888_UNORM:
  149.       bo->base.base.format = GBM_BO_FORMAT_XRGB8888;
  150.       break;
  151.    case PIPE_FORMAT_BGRA8888_UNORM:
  152.       bo->base.base.format = GBM_BO_FORMAT_ARGB8888;
  153.       break;
  154.    default:
  155.       FREE(bo);
  156.       return NULL;
  157.    }
  158.  
  159.    pipe_resource_reference(&bo->resource, resource);
  160.  
  161.    memset(&whandle, 0, sizeof(whandle));
  162.    whandle.type = DRM_API_HANDLE_TYPE_KMS;
  163.    gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
  164.  
  165.    bo->base.base.handle.u32 = whandle.handle;
  166.    bo->base.base.stride      = whandle.stride;
  167.  
  168.    return &bo->base.base;
  169. }
  170.  
  171. static struct gbm_bo *
  172. gbm_gallium_drm_bo_create(struct gbm_device *gbm,
  173.                           uint32_t width, uint32_t height,
  174.                           enum gbm_bo_format format, uint32_t usage)
  175. {
  176.    struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
  177.    struct gbm_gallium_drm_bo *bo;
  178.    struct pipe_resource templ;
  179.    struct winsys_handle whandle;
  180.    enum pipe_format pf;
  181.  
  182.    bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
  183.    if (bo == NULL)
  184.       return NULL;
  185.  
  186.    bo->base.base.gbm = gbm;
  187.    bo->base.base.width = width;
  188.    bo->base.base.height = height;
  189.    bo->base.base.format = format;
  190.  
  191.    pf = gbm_format_to_gallium(format);
  192.    if (pf == PIPE_FORMAT_NONE)
  193.       return NULL;
  194.  
  195.    memset(&templ, 0, sizeof(templ));
  196.    templ.bind = gbm_usage_to_gallium(usage);
  197.    templ.format = pf;
  198.    templ.target = PIPE_TEXTURE_2D;
  199.    templ.last_level = 0;
  200.    templ.width0 = width;
  201.    templ.height0 = height;
  202.    templ.depth0 = 1;
  203.    templ.array_size = 1;
  204.  
  205.    bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ);
  206.    if (bo->resource == NULL) {
  207.       FREE(bo);
  208.       return NULL;
  209.    }
  210.  
  211.    memset(&whandle, 0, sizeof(whandle));
  212.    whandle.type = DRM_API_HANDLE_TYPE_KMS;
  213.    gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
  214.  
  215.    bo->base.base.handle.u32 = whandle.handle;
  216.    bo->base.base.stride      = whandle.stride;
  217.  
  218.    return &bo->base.base;
  219. }
  220.  
  221. static void
  222. gbm_gallium_drm_destroy(struct gbm_device *gbm)
  223. {
  224.    struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
  225.  
  226.    gallium_screen_destroy(gdrm);
  227.    FREE(gdrm);
  228. }
  229.  
  230. struct gbm_device *
  231. gbm_gallium_drm_device_create(int fd)
  232. {
  233.    struct gbm_gallium_drm_device *gdrm;
  234.    int ret;
  235.  
  236.    gdrm = calloc(1, sizeof *gdrm);
  237.  
  238.    gdrm->base.base.fd = fd;
  239.    gdrm->base.base.bo_create = gbm_gallium_drm_bo_create;
  240.    gdrm->base.base.bo_import = gbm_gallium_drm_bo_import;
  241.    gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy;
  242.    gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported;
  243.    gdrm->base.base.destroy = gbm_gallium_drm_destroy;
  244.  
  245.    gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM;
  246.    gdrm->base.base.name = "drm";
  247.  
  248.    ret = gallium_screen_create(gdrm);
  249.    if (ret) {
  250.       free(gdrm);
  251.       return NULL;
  252.    }
  253.  
  254.    return &gdrm->base.base;
  255. }
  256.