Home | History | Annotate | Download | only in drm
      1 
      2 #include "i915_drm_winsys.h"
      3 #include "util/u_memory.h"
      4 
      5 #include "i915_drm.h"
      6 #include "i915/i915_debug.h"
      7 #include <xf86drm.h>
      8 #include <stdio.h>
      9 
     10 #define BATCH_RESERVED 16
     11 
     12 #define INTEL_DEFAULT_RELOCS 100
     13 #define INTEL_MAX_RELOCS 400
     14 
     15 #define INTEL_BATCH_NO_CLIPRECTS 0x1
     16 #define INTEL_BATCH_CLIPRECTS    0x2
     17 
     18 #undef INTEL_RUN_SYNC
     19 
     20 struct i915_drm_batchbuffer
     21 {
     22    struct i915_winsys_batchbuffer base;
     23 
     24    size_t actual_size;
     25 
     26    drm_intel_bo *bo;
     27 };
     28 
     29 static inline struct i915_drm_batchbuffer *
     30 i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
     31 {
     32    return (struct i915_drm_batchbuffer *)batch;
     33 }
     34 
     35 static void
     36 i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
     37 {
     38    struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
     39 
     40    if (batch->bo)
     41       drm_intel_bo_unreference(batch->bo);
     42    batch->bo = drm_intel_bo_alloc(idws->gem_manager,
     43                                   "gallium3d_batchbuffer",
     44                                   batch->actual_size,
     45                                   4096);
     46 
     47    memset(batch->base.map, 0, batch->actual_size);
     48    batch->base.ptr = batch->base.map;
     49    batch->base.size = batch->actual_size - BATCH_RESERVED;
     50    batch->base.relocs = 0;
     51 }
     52 
     53 static struct i915_winsys_batchbuffer *
     54 i915_drm_batchbuffer_create(struct i915_winsys *iws)
     55 {
     56    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
     57    struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
     58 
     59    batch->actual_size = idws->max_batch_size;
     60 
     61    batch->base.map = MALLOC(batch->actual_size);
     62    batch->base.ptr = NULL;
     63    batch->base.size = 0;
     64 
     65    batch->base.relocs = 0;
     66 
     67    batch->base.iws = iws;
     68 
     69    i915_drm_batchbuffer_reset(batch);
     70 
     71    return &batch->base;
     72 }
     73 
     74 static boolean
     75 i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch,
     76 				      struct i915_winsys_buffer **buffer,
     77 				      int num_of_buffers)
     78 {
     79    struct i915_drm_batchbuffer *drm_batch = i915_drm_batchbuffer(batch);
     80    drm_intel_bo *bos[num_of_buffers + 1];
     81    int i, ret;
     82 
     83    bos[0] = drm_batch->bo;
     84    for (i = 0; i < num_of_buffers; i++)
     85       bos[i+1] = intel_bo(buffer[i]);
     86 
     87    ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers);
     88    if (ret != 0)
     89       return FALSE;
     90 
     91    return TRUE;
     92 }
     93 
     94 static int
     95 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
     96                             struct i915_winsys_buffer *buffer,
     97                             enum i915_winsys_buffer_usage usage,
     98                             unsigned pre_add, boolean fenced)
     99 {
    100    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    101    unsigned write_domain = 0;
    102    unsigned read_domain = 0;
    103    unsigned offset;
    104    int ret = 0;
    105 
    106    switch (usage) {
    107    case I915_USAGE_SAMPLER:
    108       write_domain = 0;
    109       read_domain = I915_GEM_DOMAIN_SAMPLER;
    110       break;
    111    case I915_USAGE_RENDER:
    112       write_domain = I915_GEM_DOMAIN_RENDER;
    113       read_domain = I915_GEM_DOMAIN_RENDER;
    114       break;
    115    case I915_USAGE_2D_TARGET:
    116       write_domain = I915_GEM_DOMAIN_RENDER;
    117       read_domain = I915_GEM_DOMAIN_RENDER;
    118       break;
    119    case I915_USAGE_2D_SOURCE:
    120       write_domain = 0;
    121       read_domain = I915_GEM_DOMAIN_RENDER;
    122       break;
    123    case I915_USAGE_VERTEX:
    124       write_domain = 0;
    125       read_domain = I915_GEM_DOMAIN_VERTEX;
    126       break;
    127    default:
    128       assert(0);
    129       return -1;
    130    }
    131 
    132    offset = (unsigned)(batch->base.ptr - batch->base.map);
    133 
    134    if (fenced)
    135       ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset,
    136 				    intel_bo(buffer), pre_add,
    137 				    read_domain,
    138 				    write_domain);
    139    else
    140       ret = drm_intel_bo_emit_reloc(batch->bo, offset,
    141 				    intel_bo(buffer), pre_add,
    142 				    read_domain,
    143 				    write_domain);
    144 
    145    ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
    146    batch->base.ptr += 4;
    147 
    148    if (!ret)
    149       batch->base.relocs++;
    150 
    151    return ret;
    152 }
    153 
    154 static void
    155 i915_drm_throttle(struct i915_drm_winsys *idws)
    156 {
    157    drmIoctl(idws->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL);
    158 }
    159 
    160 static void
    161 i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
    162                            struct pipe_fence_handle **fence,
    163                            enum i915_winsys_flush_flags flags)
    164 {
    165    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    166    unsigned used;
    167    int ret;
    168 
    169    /* MI_BATCH_BUFFER_END */
    170    i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
    171 
    172    used = batch->base.ptr - batch->base.map;
    173    if (used & 4) {
    174       /* MI_NOOP */
    175       i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
    176       used += 4;
    177    }
    178 
    179    /* Do the sending to HW */
    180    ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
    181    if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd)
    182       ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
    183 
    184    if (flags & I915_FLUSH_END_OF_FRAME)
    185       i915_drm_throttle(i915_drm_winsys(ibatch->iws));
    186 
    187    if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
    188       i915_dump_batchbuffer(ibatch);
    189       assert(ret == 0);
    190    }
    191 
    192    if (i915_drm_winsys(ibatch->iws)->dump_raw_file) {
    193       FILE *file = fopen(i915_drm_winsys(ibatch->iws)->dump_raw_file, "a");
    194       if (file) {
    195 	 fwrite(batch->base.map, used, 1, file);
    196 	 fclose(file);
    197       }
    198    }
    199 
    200 #ifdef INTEL_RUN_SYNC
    201    drm_intel_bo_wait_rendering(batch->bo);
    202 #endif
    203 
    204    if (fence) {
    205       ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
    206 
    207 #ifdef INTEL_RUN_SYNC
    208       /* we run synced to GPU so just pass null */
    209       (*fence) = i915_drm_fence_create(NULL);
    210 #else
    211       (*fence) = i915_drm_fence_create(batch->bo);
    212 #endif
    213    }
    214 
    215    i915_drm_batchbuffer_reset(batch);
    216 }
    217 
    218 static void
    219 i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
    220 {
    221    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    222 
    223    if (batch->bo)
    224       drm_intel_bo_unreference(batch->bo);
    225 
    226    FREE(batch->base.map);
    227    FREE(batch);
    228 }
    229 
    230 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
    231 {
    232    idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
    233    idws->base.validate_buffers = i915_drm_batchbuffer_validate_buffers;
    234    idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
    235    idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
    236    idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
    237 }
    238