Android: move libdrm settings to top-level Android.common.mk
[mesa.git] / src / gallium / winsys / i915 / drm / i915_drm_batchbuffer.c
index 102f59dc54172b55702a14aa66ddcb3be1668581..93ce6f224fedfa3c556f655e803e45d624d42039 100644 (file)
@@ -3,6 +3,9 @@
 #include "util/u_memory.h"
 
 #include "i915_drm.h"
+#include "i915/i915_debug.h"
+#include <xf86drm.h>
+#include <stdio.h>
 
 #define BATCH_RESERVED 16
 
@@ -13,9 +16,6 @@
 #define INTEL_BATCH_CLIPRECTS    0x2
 
 #undef INTEL_RUN_SYNC
-#undef INTEL_MAP_BATCHBUFFER
-#undef INTEL_MAP_GTT
-#define INTEL_ALWAYS_FLUSH
 
 struct i915_drm_batchbuffer
 {
@@ -26,7 +26,7 @@ struct i915_drm_batchbuffer
    drm_intel_bo *bo;
 };
 
-static INLINE struct i915_drm_batchbuffer *
+static inline struct i915_drm_batchbuffer *
 i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
 {
    return (struct i915_drm_batchbuffer *)batch;
@@ -36,27 +36,14 @@ static void
 i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
 {
    struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
-   int ret;
 
    if (batch->bo)
       drm_intel_bo_unreference(batch->bo);
-   batch->bo = drm_intel_bo_alloc(idws->pools.gem,
+   batch->bo = drm_intel_bo_alloc(idws->gem_manager,
                                   "gallium3d_batchbuffer",
                                   batch->actual_size,
                                   4096);
 
-#ifdef INTEL_MAP_BATCHBUFFER
-#ifdef INTEL_MAP_GTT
-   ret = drm_intel_gem_bo_map_gtt(batch->bo);
-#else
-   ret = drm_intel_bo_map(batch->bo, TRUE);
-#endif
-   assert(ret == 0);
-   batch->base.map = batch->bo->virtual;
-#else
-   (void)ret;
-#endif
-
    memset(batch->base.map, 0, batch->actual_size);
    batch->base.ptr = batch->base.map;
    batch->base.size = batch->actual_size - BATCH_RESERVED;
@@ -71,16 +58,11 @@ i915_drm_batchbuffer_create(struct i915_winsys *iws)
 
    batch->actual_size = idws->max_batch_size;
 
-#ifdef INTEL_MAP_BATCHBUFFER
-   batch->base.map = NULL;
-#else
    batch->base.map = MALLOC(batch->actual_size);
-#endif
    batch->base.ptr = NULL;
    batch->base.size = 0;
 
    batch->base.relocs = 0;
-   batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
 
    batch->base.iws = iws;
 
@@ -89,11 +71,31 @@ i915_drm_batchbuffer_create(struct i915_winsys *iws)
    return &batch->base;
 }
 
+static boolean
+i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch,
+                                     struct i915_winsys_buffer **buffer,
+                                     int num_of_buffers)
+{
+   struct i915_drm_batchbuffer *drm_batch = i915_drm_batchbuffer(batch);
+   drm_intel_bo *bos[num_of_buffers + 1];
+   int i, ret;
+
+   bos[0] = drm_batch->bo;
+   for (i = 0; i < num_of_buffers; i++)
+      bos[i+1] = intel_bo(buffer[i]);
+
+   ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers);
+   if (ret != 0)
+      return FALSE;
+
+   return TRUE;
+}
+
 static int
 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
                             struct i915_winsys_buffer *buffer,
                             enum i915_winsys_buffer_usage usage,
-                            unsigned pre_add)
+                            unsigned pre_add, boolean fenced)
 {
    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    unsigned write_domain = 0;
@@ -101,39 +103,44 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
    unsigned offset;
    int ret = 0;
 
-   assert(batch->base.relocs < batch->base.max_relocs);
-
-   if (usage == I915_USAGE_SAMPLER) {
+   switch (usage) {
+   case I915_USAGE_SAMPLER:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_SAMPLER;
-
-   } else if (usage == I915_USAGE_RENDER) {
+      break;
+   case I915_USAGE_RENDER:
       write_domain = I915_GEM_DOMAIN_RENDER;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_2D_TARGET) {
+      break;
+   case I915_USAGE_2D_TARGET:
       write_domain = I915_GEM_DOMAIN_RENDER;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_2D_SOURCE) {
+      break;
+   case I915_USAGE_2D_SOURCE:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_RENDER;
-
-   } else if (usage == I915_USAGE_VERTEX) {
+      break;
+   case I915_USAGE_VERTEX:
       write_domain = 0;
       read_domain = I915_GEM_DOMAIN_VERTEX;
-
-   } else {
+      break;
+   default:
       assert(0);
       return -1;
    }
 
    offset = (unsigned)(batch->base.ptr - batch->base.map);
 
-   ret = drm_intel_bo_emit_reloc(batch->bo, offset,
-                                 intel_bo(buffer), pre_add,
-                                 read_domain,
-                                 write_domain);
+   if (fenced)
+      ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset,
+                                   intel_bo(buffer), pre_add,
+                                   read_domain,
+                                   write_domain);
+   else
+      ret = drm_intel_bo_emit_reloc(batch->bo, offset,
+                                   intel_bo(buffer), pre_add,
+                                   read_domain,
+                                   write_domain);
 
    ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
    batch->base.ptr += 4;
@@ -144,68 +151,55 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
    return ret;
 }
 
+static void
+i915_drm_throttle(struct i915_drm_winsys *idws)
+{
+   drmIoctl(idws->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL);
+}
+
 static void
 i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
-                            struct pipe_fence_handle **fence)
+                           struct pipe_fence_handle **fence,
+                           enum i915_winsys_flush_flags flags)
 {
    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
-   unsigned used = 0;
-   int ret = 0;
-   int i;
+   unsigned used;
+   int ret;
 
-   assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
+   /* MI_BATCH_BUFFER_END */
+   i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
 
    used = batch->base.ptr - batch->base.map;
-   assert((used & 3) == 0);
-
-
-#ifdef INTEL_ALWAYS_FLUSH
-   /* MI_FLUSH | FLUSH_MAP_CACHE */
-   i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
-   used += 4;
-#endif
-
-   if ((used & 4) == 0) {
+   if (used & 4) {
       /* MI_NOOP */
-      i915_winsys_batchbuffer_dword(ibatch, 0);
+      i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
+      used += 4;
    }
-   /* MI_BATCH_BUFFER_END */
-   i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
-
-   used = batch->base.ptr - batch->base.map;
-   assert((used & 4) == 0);
-
-#ifdef INTEL_MAP_BATCHBUFFER
-#ifdef INTEL_MAP_GTT
-   drm_intel_gem_bo_unmap_gtt(batch->bo);
-#else
-   drm_intel_bo_unmap(batch->bo);
-#endif
-#else
-   drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
-#endif
 
    /* Do the sending to HW */
-   ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
-   assert(ret == 0);
+   ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+   if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd)
+      ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
 
-   if (i915_drm_winsys(ibatch->iws)->dump_cmd) {
-      unsigned *ptr;
-      drm_intel_bo_map(batch->bo, FALSE);
-      ptr = (unsigned*)batch->bo->virtual;
+   if (flags & I915_FLUSH_END_OF_FRAME)
+      i915_drm_throttle(i915_drm_winsys(ibatch->iws));
 
-      debug_printf("%s:\n", __func__);
-      for (i = 0; i < used / 4; i++, ptr++) {
-         debug_printf("\t%08x:    %08x\n", i*4, *ptr);
+   if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
+      i915_dump_batchbuffer(ibatch);
+      assert(ret == 0);
+   }
+
+   if (i915_drm_winsys(ibatch->iws)->dump_raw_file) {
+      FILE *file = fopen(i915_drm_winsys(ibatch->iws)->dump_raw_file, "a");
+      if (file) {
+        fwrite(batch->base.map, used, 1, file);
+        fclose(file);
       }
+   }
 
-      drm_intel_bo_unmap(batch->bo);
-   } else {
 #ifdef INTEL_RUN_SYNC
-      drm_intel_bo_map(batch->bo, FALSE);
-      drm_intel_bo_unmap(batch->bo);
+   drm_intel_bo_wait_rendering(batch->bo);
 #endif
-   }
 
    if (fence) {
       ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
@@ -229,15 +223,14 @@ i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
    if (batch->bo)
       drm_intel_bo_unreference(batch->bo);
 
-#ifndef INTEL_MAP_BATCHBUFFER
    FREE(batch->base.map);
-#endif
    FREE(batch);
 }
 
 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
 {
    idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
+   idws->base.validate_buffers = i915_drm_batchbuffer_validate_buffers;
    idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
    idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
    idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;