Subversion Repositories Kolibri OS

Rev

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

  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.