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