Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "state_tracker/drm_driver.h"
  2. #include "i915_drm_winsys.h"
  3. #include "util/u_memory.h"
  4.  
  5. #include "i915_drm.h"
  6.  
  7. static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type)
  8. {
  9.    char *name;
  10.  
  11.    if (type == I915_NEW_TEXTURE) {
  12.       name = "gallium3d_texture";
  13.    } else if (type == I915_NEW_VERTEX) {
  14.       name = "gallium3d_vertex";
  15.    } else if (type == I915_NEW_SCANOUT) {
  16.       name = "gallium3d_scanout";
  17.    } else {
  18.       assert(0);
  19.       name = "gallium3d_unknown";
  20.    }
  21.  
  22.    return name;
  23. }
  24.  
  25. static struct i915_winsys_buffer *
  26. i915_drm_buffer_create(struct i915_winsys *iws,
  27.                         unsigned size,
  28.                         enum i915_winsys_buffer_type type)
  29. {
  30.    struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
  31.    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
  32.  
  33.    if (!buf)
  34.       return NULL;
  35.  
  36.    buf->magic = 0xDEAD1337;
  37.    buf->flinked = FALSE;
  38.    buf->flink = 0;
  39.  
  40.    buf->bo = drm_intel_bo_alloc(idws->gem_manager,
  41.                                 i915_drm_type_to_name(type), size, 0);
  42.  
  43.    if (!buf->bo)
  44.       goto err;
  45.  
  46.    return (struct i915_winsys_buffer *)buf;
  47.  
  48. err:
  49.    assert(0);
  50.    FREE(buf);
  51.    return NULL;
  52. }
  53.  
  54. static struct i915_winsys_buffer *
  55. i915_drm_buffer_create_tiled(struct i915_winsys *iws,
  56.                              unsigned *stride, unsigned height,
  57.                              enum i915_winsys_buffer_tile *tiling,
  58.                              enum i915_winsys_buffer_type type)
  59. {
  60.    struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
  61.    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
  62.    unsigned long pitch = 0;
  63.    uint32_t tiling_mode = *tiling;
  64.  
  65.    if (!buf)
  66.       return NULL;
  67.  
  68.    buf->magic = 0xDEAD1337;
  69.    buf->flinked = FALSE;
  70.    buf->flink = 0;
  71.  
  72.    buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager,
  73.                                       i915_drm_type_to_name(type),
  74.                                       *stride, height, 1,
  75.                                       &tiling_mode, &pitch, 0);
  76.  
  77.    if (!buf->bo)
  78.       goto err;
  79.  
  80.    *stride = pitch;
  81.    *tiling = tiling_mode;
  82.    return (struct i915_winsys_buffer *)buf;
  83.  
  84. err:
  85.    assert(0);
  86.    FREE(buf);
  87.    return NULL;
  88. }
  89.  
  90. static struct i915_winsys_buffer *
  91. i915_drm_buffer_from_handle(struct i915_winsys *iws,
  92.                             struct winsys_handle *whandle,
  93.                             unsigned height,
  94.                             enum i915_winsys_buffer_tile *tiling,
  95.                             unsigned *stride)
  96. {
  97.    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
  98.    struct i915_drm_buffer *buf;
  99.    uint32_t tile = 0, swizzle = 0;
  100.  
  101.    if ((whandle->type != DRM_API_HANDLE_TYPE_SHARED) && (whandle->type != DRM_API_HANDLE_TYPE_FD))
  102.       return NULL;
  103.  
  104.    buf = CALLOC_STRUCT(i915_drm_buffer);
  105.    if (!buf)
  106.       return NULL;
  107.  
  108.    buf->magic = 0xDEAD1337;
  109.  
  110.    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
  111.        buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle);
  112.    else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
  113.        int fd = (int) whandle->handle;
  114.        buf->bo = drm_intel_bo_gem_create_from_prime(idws->gem_manager, fd, height * whandle->stride);
  115.    }
  116.  
  117.    buf->flinked = TRUE;
  118.    buf->flink = whandle->handle;
  119.  
  120.    if (!buf->bo)
  121.       goto err;
  122.  
  123.    drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
  124.  
  125.    *stride = whandle->stride;
  126.    *tiling = tile;
  127.  
  128.    return (struct i915_winsys_buffer *)buf;
  129.  
  130. err:
  131.    FREE(buf);
  132.    return NULL;
  133. }
  134.  
  135. static boolean
  136. i915_drm_buffer_get_handle(struct i915_winsys *iws,
  137.                             struct i915_winsys_buffer *buffer,
  138.                             struct winsys_handle *whandle,
  139.                             unsigned stride)
  140. {
  141.    struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
  142.  
  143.    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
  144.       if (!buf->flinked) {
  145.          if (drm_intel_bo_flink(buf->bo, &buf->flink))
  146.             return FALSE;
  147.          buf->flinked = TRUE;
  148.       }
  149.  
  150.       whandle->handle = buf->flink;
  151.    } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
  152.       whandle->handle = buf->bo->handle;
  153.    } else {
  154.       assert(!"unknown usage");
  155.       return FALSE;
  156.    }
  157.  
  158.    whandle->stride = stride;
  159.    return TRUE;
  160. }
  161.  
  162. static void *
  163. i915_drm_buffer_map(struct i915_winsys *iws,
  164.                      struct i915_winsys_buffer *buffer,
  165.                      boolean write)
  166. {
  167.    struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
  168.    drm_intel_bo *bo = intel_bo(buffer);
  169.    int ret = 0;
  170.  
  171.    assert(bo);
  172.  
  173.    if (buf->map_count)
  174.       goto out;
  175.  
  176.    ret = drm_intel_gem_bo_map_gtt(bo);
  177.  
  178.    buf->ptr = bo->virtual;
  179.  
  180.    assert(ret == 0);
  181. out:
  182.    if (ret)
  183.       return NULL;
  184.  
  185.    buf->map_count++;
  186.    return buf->ptr;
  187. }
  188.  
  189. static void
  190. i915_drm_buffer_unmap(struct i915_winsys *iws,
  191.                        struct i915_winsys_buffer *buffer)
  192. {
  193.    struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
  194.  
  195.    if (--buf->map_count)
  196.       return;
  197.  
  198.    drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
  199. }
  200.  
  201. static int
  202. i915_drm_buffer_write(struct i915_winsys *iws,
  203.                        struct i915_winsys_buffer *buffer,
  204.                        size_t offset,
  205.                        size_t size,
  206.                        const void *data)
  207. {
  208.    struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
  209.  
  210.    return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
  211. }
  212.  
  213. static void
  214. i915_drm_buffer_destroy(struct i915_winsys *iws,
  215.                          struct i915_winsys_buffer *buffer)
  216. {
  217.    drm_intel_bo_unreference(intel_bo(buffer));
  218.  
  219. #ifdef DEBUG
  220.    i915_drm_buffer(buffer)->magic = 0;
  221.    i915_drm_buffer(buffer)->bo = NULL;
  222. #endif
  223.  
  224.    FREE(buffer);
  225. }
  226.  
  227. static boolean
  228. i915_drm_buffer_is_busy(struct i915_winsys *iws,
  229.                         struct i915_winsys_buffer *buffer)
  230. {
  231.    struct i915_drm_buffer* i915_buffer = i915_drm_buffer(buffer);
  232.    if (!i915_buffer)
  233.       return FALSE;
  234.    return drm_intel_bo_busy(i915_buffer->bo);
  235. }
  236.  
  237.  
  238. void
  239. i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
  240. {
  241.    idws->base.buffer_create = i915_drm_buffer_create;
  242.    idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled;
  243.    idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
  244.    idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
  245.    idws->base.buffer_map = i915_drm_buffer_map;
  246.    idws->base.buffer_unmap = i915_drm_buffer_unmap;
  247.    idws->base.buffer_write = i915_drm_buffer_write;
  248.    idws->base.buffer_destroy = i915_drm_buffer_destroy;
  249.    idws->base.buffer_is_busy = i915_drm_buffer_is_busy;
  250. }
  251.