Subversion Repositories Kolibri OS

Rev

Rev 5068 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright © 2007 Red Hat Inc.
  4.  * Copyright © 2007-2012 Intel Corporation
  5.  * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the
  10.  * "Software"), to deal in the Software without restriction, including
  11.  * without limitation the rights to use, copy, modify, merge, publish,
  12.  * distribute, sub license, and/or sell copies of the Software, and to
  13.  * permit persons to whom the Software is furnished to do so, subject to
  14.  * the following conditions:
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  19.  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * The above copyright notice and this permission notice (including the
  25.  * next paragraph) shall be included in all copies or substantial portions
  26.  * of the Software.
  27.  *
  28.  *
  29.  **************************************************************************/
  30. /*
  31.  * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  32.  *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
  33.  *          Eric Anholt <eric@anholt.net>
  34.  *          Dave Airlie <airlied@linux.ie>
  35.  */
  36.  
  37. #ifdef HAVE_CONFIG_H
  38. #include "config.h"
  39. #endif
  40.  
  41. #include <xf86drm.h>
  42. #include <xf86atomic.h>
  43. #include <fcntl.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <unistd.h>
  48. #include <assert.h>
  49. //#include <pthread.h>
  50. #include <stdbool.h>
  51.  
  52. #include "errno.h"
  53. #ifndef ETIME
  54. #define ETIME ETIMEDOUT
  55. #endif
  56. #include "libdrm_lists.h"
  57. #include "intel_bufmgr.h"
  58. #include "intel_bufmgr_priv.h"
  59. #include "intel_chipset.h"
  60. #include "intel_aub.h"
  61. #include "string.h"
  62.  
  63. #include "i915_drm.h"
  64.  
  65. #ifdef HAVE_VALGRIND
  66. #include <valgrind.h>
  67. #include <memcheck.h>
  68. #define VG(x) x
  69. #else
  70. #define VG(x)
  71. #endif
  72.  
  73. #define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
  74.  
  75. #if 0
  76. #define DBG(...) do {                                   \
  77.         if (bufmgr_gem->bufmgr.debug)                   \
  78.                 fprintf(stderr, __VA_ARGS__);           \
  79. } while (0)
  80. #endif
  81.  
  82. //#define DBG(...) fprintf(stderr, __VA_ARGS__)
  83. #define DBG(...)
  84.  
  85. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  86.  
  87. typedef struct _drm_intel_bo_gem drm_intel_bo_gem;
  88.  
  89. struct drm_intel_gem_bo_bucket {
  90.         drmMMListHead head;
  91.         unsigned long size;
  92. };
  93.  
  94. typedef struct _drm_intel_bufmgr_gem {
  95.         drm_intel_bufmgr bufmgr;
  96.  
  97.         int fd;
  98.  
  99.         int max_relocs;
  100.  
  101. //      pthread_mutex_t lock;
  102.  
  103.         struct drm_i915_gem_exec_object *exec_objects;
  104.         struct drm_i915_gem_exec_object2 *exec2_objects;
  105.         drm_intel_bo **exec_bos;
  106.         int exec_size;
  107.         int exec_count;
  108.  
  109.         /** Array of lists of cached gem objects of power-of-two sizes */
  110.         struct drm_intel_gem_bo_bucket cache_bucket[14 * 4];
  111.         int num_buckets;
  112.         time_t time;
  113.  
  114.         drmMMListHead named;
  115.         drmMMListHead vma_cache;
  116.         int vma_count, vma_open, vma_max;
  117.  
  118.         uint64_t gtt_size;
  119.         int available_fences;
  120.         int pci_device;
  121.         int gen;
  122.         unsigned int has_bsd : 1;
  123.         unsigned int has_blt : 1;
  124.         unsigned int has_relaxed_fencing : 1;
  125.         unsigned int has_llc : 1;
  126.         unsigned int has_wait_timeout : 1;
  127.         unsigned int bo_reuse : 1;
  128.         unsigned int no_exec : 1;
  129.         unsigned int has_vebox : 1;
  130.         bool fenced_relocs;
  131.  
  132.         char *aub_filename;
  133.         FILE *aub_file;
  134.         uint32_t aub_offset;
  135. } drm_intel_bufmgr_gem;
  136.  
  137. #define DRM_INTEL_RELOC_FENCE (1<<0)
  138.  
  139. typedef struct _drm_intel_reloc_target_info {
  140.         drm_intel_bo *bo;
  141.         int flags;
  142. } drm_intel_reloc_target;
  143.  
  144. struct _drm_intel_bo_gem {
  145.         drm_intel_bo bo;
  146.  
  147.         atomic_t refcount;
  148.         uint32_t gem_handle;
  149.         const char *name;
  150.  
  151.         /**
  152.          * Kenel-assigned global name for this object
  153.          *
  154.          * List contains both flink named and prime fd'd objects
  155.          */
  156.         unsigned int global_name;
  157.         drmMMListHead name_list;
  158.  
  159.         /**
  160.          * Index of the buffer within the validation list while preparing a
  161.          * batchbuffer execution.
  162.          */
  163.         int validate_index;
  164.  
  165.         /**
  166.          * Current tiling mode
  167.          */
  168.         uint32_t tiling_mode;
  169.         uint32_t swizzle_mode;
  170.         unsigned long stride;
  171.  
  172.         time_t free_time;
  173.  
  174.         /** Array passed to the DRM containing relocation information. */
  175.         struct drm_i915_gem_relocation_entry *relocs;
  176.         /**
  177.          * Array of info structs corresponding to relocs[i].target_handle etc
  178.          */
  179.         drm_intel_reloc_target *reloc_target_info;
  180.         /** Number of entries in relocs */
  181.         int reloc_count;
  182.         /** Mapped address for the buffer, saved across map/unmap cycles */
  183.         void *mem_virtual;
  184.         /** GTT virtual address for the buffer, saved across map/unmap cycles */
  185.         void *gtt_virtual;
  186.         int map_count;
  187.         drmMMListHead vma_list;
  188.  
  189.         /** BO cache list */
  190.         drmMMListHead head;
  191.  
  192.         /**
  193.          * Boolean of whether this BO and its children have been included in
  194.          * the current drm_intel_bufmgr_check_aperture_space() total.
  195.          */
  196.         bool included_in_check_aperture;
  197.  
  198.         /**
  199.          * Boolean of whether this buffer has been used as a relocation
  200.          * target and had its size accounted for, and thus can't have any
  201.          * further relocations added to it.
  202.          */
  203.         bool used_as_reloc_target;
  204.  
  205.         /**
  206.          * Boolean of whether we have encountered an error whilst building the relocation tree.
  207.          */
  208.         bool has_error;
  209.  
  210.         /**
  211.          * Boolean of whether this buffer can be re-used
  212.          */
  213.         bool reusable;
  214.  
  215.         /**
  216.          * Size in bytes of this buffer and its relocation descendents.
  217.          *
  218.          * Used to avoid costly tree walking in
  219.          * drm_intel_bufmgr_check_aperture in the common case.
  220.          */
  221.         int reloc_tree_size;
  222.  
  223.         /**
  224.          * Number of potential fence registers required by this buffer and its
  225.          * relocations.
  226.          */
  227.         int reloc_tree_fences;
  228.  
  229.         /** Flags that we may need to do the SW_FINSIH ioctl on unmap. */
  230.         bool mapped_cpu_write;
  231.  
  232.         uint32_t aub_offset;
  233.  
  234.         drm_intel_aub_annotation *aub_annotations;
  235.         unsigned aub_annotation_count;
  236. };
  237.  
  238. static unsigned int
  239. drm_intel_gem_estimate_batch_space(drm_intel_bo ** bo_array, int count);
  240.  
  241. static unsigned int
  242. drm_intel_gem_compute_batch_space(drm_intel_bo ** bo_array, int count);
  243.  
  244. static int
  245. drm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
  246.                             uint32_t * swizzle_mode);
  247.  
  248. static int
  249. drm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
  250.                                      uint32_t tiling_mode,
  251.                                      uint32_t stride);
  252.  
  253. static void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo,
  254.                                                       time_t time);
  255.  
  256. static void drm_intel_gem_bo_unreference(drm_intel_bo *bo);
  257.  
  258. static void drm_intel_gem_bo_free(drm_intel_bo *bo);
  259.  
  260. static unsigned long
  261. drm_intel_gem_bo_tile_size(drm_intel_bufmgr_gem *bufmgr_gem, unsigned long size,
  262.                            uint32_t *tiling_mode)
  263. {
  264.         unsigned long min_size, max_size;
  265.         unsigned long i;
  266.  
  267.         if (*tiling_mode == I915_TILING_NONE)
  268.                 return size;
  269.  
  270.         /* 965+ just need multiples of page size for tiling */
  271.         if (bufmgr_gem->gen >= 4)
  272.                 return ROUND_UP_TO(size, 4096);
  273.  
  274.         /* Older chips need powers of two, of at least 512k or 1M */
  275.         if (bufmgr_gem->gen == 3) {
  276.                 min_size = 1024*1024;
  277.                 max_size = 128*1024*1024;
  278.         } else {
  279.                 min_size = 512*1024;
  280.                 max_size = 64*1024*1024;
  281.         }
  282.  
  283.         if (size > max_size) {
  284.                 *tiling_mode = I915_TILING_NONE;
  285.                 return size;
  286.         }
  287.  
  288.         /* Do we need to allocate every page for the fence? */
  289.         if (bufmgr_gem->has_relaxed_fencing)
  290.                 return ROUND_UP_TO(size, 4096);
  291.  
  292.         for (i = min_size; i < size; i <<= 1)
  293.                 ;
  294.  
  295.         return i;
  296. }
  297.  
  298. /*
  299.  * Round a given pitch up to the minimum required for X tiling on a
  300.  * given chip.  We use 512 as the minimum to allow for a later tiling
  301.  * change.
  302.  */
  303. static unsigned long
  304. drm_intel_gem_bo_tile_pitch(drm_intel_bufmgr_gem *bufmgr_gem,
  305.                             unsigned long pitch, uint32_t *tiling_mode)
  306. {
  307.         unsigned long tile_width;
  308.         unsigned long i;
  309.  
  310.         /* If untiled, then just align it so that we can do rendering
  311.          * to it with the 3D engine.
  312.          */
  313.         if (*tiling_mode == I915_TILING_NONE)
  314.                 return ALIGN(pitch, 64);
  315.  
  316.         if (*tiling_mode == I915_TILING_X
  317.                         || (IS_915(bufmgr_gem->pci_device)
  318.                             && *tiling_mode == I915_TILING_Y))
  319.                 tile_width = 512;
  320.         else
  321.                 tile_width = 128;
  322.  
  323.         /* 965 is flexible */
  324.         if (bufmgr_gem->gen >= 4)
  325.                 return ROUND_UP_TO(pitch, tile_width);
  326.  
  327.         /* The older hardware has a maximum pitch of 8192 with tiled
  328.          * surfaces, so fallback to untiled if it's too large.
  329.          */
  330.         if (pitch > 8192) {
  331.                 *tiling_mode = I915_TILING_NONE;
  332.                 return ALIGN(pitch, 64);
  333.         }
  334.  
  335.         /* Pre-965 needs power of two tile width */
  336.         for (i = tile_width; i < pitch; i <<= 1)
  337.                 ;
  338.  
  339.         return i;
  340. }
  341.  
  342. static struct drm_intel_gem_bo_bucket *
  343. drm_intel_gem_bo_bucket_for_size(drm_intel_bufmgr_gem *bufmgr_gem,
  344.                                  unsigned long size)
  345. {
  346.         int i;
  347.  
  348.         for (i = 0; i < bufmgr_gem->num_buckets; i++) {
  349.                 struct drm_intel_gem_bo_bucket *bucket =
  350.                     &bufmgr_gem->cache_bucket[i];
  351.                 if (bucket->size >= size) {
  352.                         return bucket;
  353.                 }
  354.         }
  355.  
  356.         return NULL;
  357. }
  358.  
  359. static void
  360. drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
  361. {
  362.         int i, j;
  363.  
  364.         for (i = 0; i < bufmgr_gem->exec_count; i++) {
  365.                 drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
  366.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  367.  
  368.                 if (bo_gem->relocs == NULL) {
  369.                         DBG("%2d: %d (%s)\n", i, bo_gem->gem_handle,
  370.                             bo_gem->name);
  371.                         continue;
  372.                 }
  373.  
  374.                 for (j = 0; j < bo_gem->reloc_count; j++) {
  375.                         drm_intel_bo *target_bo = bo_gem->reloc_target_info[j].bo;
  376.                         drm_intel_bo_gem *target_gem =
  377.                             (drm_intel_bo_gem *) target_bo;
  378.  
  379.                         DBG("%2d: %d (%s)@0x%08llx -> "
  380.                             "%d (%s)@0x%08lx + 0x%08x\n",
  381.                             i,
  382.                             bo_gem->gem_handle, bo_gem->name,
  383.                             (unsigned long long)bo_gem->relocs[j].offset,
  384.                             target_gem->gem_handle,
  385.                             target_gem->name,
  386.                             target_bo->offset,
  387.                             bo_gem->relocs[j].delta);
  388.                 }
  389.         }
  390. }
  391.  
  392. static inline void
  393. drm_intel_gem_bo_reference(drm_intel_bo *bo)
  394. {
  395.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  396.  
  397.         atomic_inc(&bo_gem->refcount);
  398. }
  399.  
  400. /**
  401.  * Adds the given buffer to the list of buffers to be validated (moved into the
  402.  * appropriate memory type) with the next batch submission.
  403.  *
  404.  * If a buffer is validated multiple times in a batch submission, it ends up
  405.  * with the intersection of the memory type flags and the union of the
  406.  * access flags.
  407.  */
  408. static void
  409. drm_intel_add_validate_buffer(drm_intel_bo *bo)
  410. {
  411.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  412.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  413.         int index;
  414.  
  415.         if (bo_gem->validate_index != -1)
  416.                 return;
  417.  
  418.         /* Extend the array of validation entries as necessary. */
  419.         if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
  420.                 int new_size = bufmgr_gem->exec_size * 2;
  421.  
  422.                 if (new_size == 0)
  423.                         new_size = 5;
  424.  
  425.                 bufmgr_gem->exec_objects =
  426.                     realloc(bufmgr_gem->exec_objects,
  427.                             sizeof(*bufmgr_gem->exec_objects) * new_size);
  428.                 bufmgr_gem->exec_bos =
  429.                     realloc(bufmgr_gem->exec_bos,
  430.                             sizeof(*bufmgr_gem->exec_bos) * new_size);
  431.                 bufmgr_gem->exec_size = new_size;
  432.         }
  433.  
  434.         index = bufmgr_gem->exec_count;
  435.         bo_gem->validate_index = index;
  436.         /* Fill in array entry */
  437.         bufmgr_gem->exec_objects[index].handle = bo_gem->gem_handle;
  438.         bufmgr_gem->exec_objects[index].relocation_count = bo_gem->reloc_count;
  439.         bufmgr_gem->exec_objects[index].relocs_ptr = (uintptr_t) bo_gem->relocs;
  440.         bufmgr_gem->exec_objects[index].alignment = 0;
  441.         bufmgr_gem->exec_objects[index].offset = 0;
  442.         bufmgr_gem->exec_bos[index] = bo;
  443.         bufmgr_gem->exec_count++;
  444. }
  445.  
  446. static void
  447. drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
  448. {
  449.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
  450.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
  451.         int index;
  452.  
  453.         if (bo_gem->validate_index != -1) {
  454.                 if (need_fence)
  455.                         bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
  456.                                 EXEC_OBJECT_NEEDS_FENCE;
  457.                 return;
  458.         }
  459.  
  460.         /* Extend the array of validation entries as necessary. */
  461.         if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
  462.                 int new_size = bufmgr_gem->exec_size * 2;
  463.  
  464.                 if (new_size == 0)
  465.                         new_size = 5;
  466.  
  467.                 bufmgr_gem->exec2_objects =
  468.                         realloc(bufmgr_gem->exec2_objects,
  469.                                 sizeof(*bufmgr_gem->exec2_objects) * new_size);
  470.                 bufmgr_gem->exec_bos =
  471.                         realloc(bufmgr_gem->exec_bos,
  472.                                 sizeof(*bufmgr_gem->exec_bos) * new_size);
  473.                 bufmgr_gem->exec_size = new_size;
  474.         }
  475.  
  476.         index = bufmgr_gem->exec_count;
  477.         bo_gem->validate_index = index;
  478.         /* Fill in array entry */
  479.         bufmgr_gem->exec2_objects[index].handle = bo_gem->gem_handle;
  480.         bufmgr_gem->exec2_objects[index].relocation_count = bo_gem->reloc_count;
  481.         bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
  482.         bufmgr_gem->exec2_objects[index].alignment = 0;
  483.         bufmgr_gem->exec2_objects[index].offset = 0;
  484.         bufmgr_gem->exec_bos[index] = bo;
  485.         bufmgr_gem->exec2_objects[index].flags = 0;
  486.         bufmgr_gem->exec2_objects[index].rsvd1 = 0;
  487.         bufmgr_gem->exec2_objects[index].rsvd2 = 0;
  488.         if (need_fence) {
  489.                 bufmgr_gem->exec2_objects[index].flags |=
  490.                         EXEC_OBJECT_NEEDS_FENCE;
  491.         }
  492.         bufmgr_gem->exec_count++;
  493. }
  494.  
  495. #define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * \
  496.         sizeof(uint32_t))
  497.  
  498. static void
  499. drm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem,
  500.                                       drm_intel_bo_gem *bo_gem)
  501. {
  502.         int size;
  503.  
  504.         assert(!bo_gem->used_as_reloc_target);
  505.  
  506.         /* The older chipsets are far-less flexible in terms of tiling,
  507.          * and require tiled buffer to be size aligned in the aperture.
  508.          * This means that in the worst possible case we will need a hole
  509.          * twice as large as the object in order for it to fit into the
  510.          * aperture. Optimal packing is for wimps.
  511.          */
  512.         size = bo_gem->bo.size;
  513.         if (bufmgr_gem->gen < 4 && bo_gem->tiling_mode != I915_TILING_NONE) {
  514.                 int min_size;
  515.  
  516.                 if (bufmgr_gem->has_relaxed_fencing) {
  517.                         if (bufmgr_gem->gen == 3)
  518.                                 min_size = 1024*1024;
  519.                         else
  520.                                 min_size = 512*1024;
  521.  
  522.                         while (min_size < size)
  523.                                 min_size *= 2;
  524.                 } else
  525.                         min_size = size;
  526.  
  527.                 /* Account for worst-case alignment. */
  528.                 size = 2 * min_size;
  529.         }
  530.  
  531.         bo_gem->reloc_tree_size = size;
  532. }
  533.  
  534. static int
  535. drm_intel_setup_reloc_list(drm_intel_bo *bo)
  536. {
  537.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  538.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  539.         unsigned int max_relocs = bufmgr_gem->max_relocs;
  540.  
  541.         if (bo->size / 4 < max_relocs)
  542.                 max_relocs = bo->size / 4;
  543.  
  544.         bo_gem->relocs = malloc(max_relocs *
  545.                                 sizeof(struct drm_i915_gem_relocation_entry));
  546.         bo_gem->reloc_target_info = malloc(max_relocs *
  547.                                            sizeof(drm_intel_reloc_target));
  548.         if (bo_gem->relocs == NULL || bo_gem->reloc_target_info == NULL) {
  549.                 bo_gem->has_error = true;
  550.  
  551.                 free (bo_gem->relocs);
  552.                 bo_gem->relocs = NULL;
  553.  
  554.                 free (bo_gem->reloc_target_info);
  555.                 bo_gem->reloc_target_info = NULL;
  556.  
  557.                 return 1;
  558.         }
  559.  
  560.         return 0;
  561. }
  562.  
  563. static int
  564. drm_intel_gem_bo_busy(drm_intel_bo *bo)
  565. {
  566.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  567.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  568.         struct drm_i915_gem_busy busy;
  569.         int ret;
  570.  
  571.         VG_CLEAR(busy);
  572.         busy.handle = bo_gem->gem_handle;
  573.  
  574.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
  575.  
  576.         return (ret == 0 && busy.busy);
  577. }
  578.  
  579. static int
  580. drm_intel_gem_bo_madvise_internal(drm_intel_bufmgr_gem *bufmgr_gem,
  581.                                   drm_intel_bo_gem *bo_gem, int state)
  582. {
  583.         struct drm_i915_gem_madvise madv;
  584.  
  585.         VG_CLEAR(madv);
  586.         madv.handle = bo_gem->gem_handle;
  587.         madv.madv = state;
  588.         madv.retained = 1;
  589. //      drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
  590.  
  591.         return madv.retained;
  592. }
  593.  
  594. static int
  595. drm_intel_gem_bo_madvise(drm_intel_bo *bo, int madv)
  596. {
  597.         return drm_intel_gem_bo_madvise_internal
  598.                 ((drm_intel_bufmgr_gem *) bo->bufmgr,
  599.                  (drm_intel_bo_gem *) bo,
  600.                  madv);
  601. }
  602.  
  603. /* drop the oldest entries that have been purged by the kernel */
  604. static void
  605. drm_intel_gem_bo_cache_purge_bucket(drm_intel_bufmgr_gem *bufmgr_gem,
  606.                                     struct drm_intel_gem_bo_bucket *bucket)
  607. {
  608.         while (!DRMLISTEMPTY(&bucket->head)) {
  609.                 drm_intel_bo_gem *bo_gem;
  610.  
  611.                 bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  612.                                       bucket->head.next, head);
  613.                 if (drm_intel_gem_bo_madvise_internal
  614.                     (bufmgr_gem, bo_gem, I915_MADV_DONTNEED))
  615.                         break;
  616.  
  617.                 DRMLISTDEL(&bo_gem->head);
  618.                 drm_intel_gem_bo_free(&bo_gem->bo);
  619.         }
  620. }
  621.  
  622. static drm_intel_bo *
  623. drm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr,
  624.                                 const char *name,
  625.                                 unsigned long size,
  626.                                 unsigned long flags,
  627.                                 uint32_t tiling_mode,
  628.                                 unsigned long stride)
  629. {
  630.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  631.         drm_intel_bo_gem *bo_gem;
  632.         unsigned int page_size = 4096;
  633.         int ret;
  634.         struct drm_intel_gem_bo_bucket *bucket;
  635.         bool alloc_from_cache;
  636.         unsigned long bo_size;
  637.         bool for_render = false;
  638.  
  639.         if (flags & BO_ALLOC_FOR_RENDER)
  640.                 for_render = true;
  641.  
  642.         /* Round the allocated size up to a power of two number of pages. */
  643.         bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, size);
  644.  
  645.         /* If we don't have caching at this size, don't actually round the
  646.          * allocation up.
  647.          */
  648.         if (bucket == NULL) {
  649.                 bo_size = size;
  650.                 if (bo_size < page_size)
  651.                         bo_size = page_size;
  652.         } else {
  653.                 bo_size = bucket->size;
  654.         }
  655.  
  656. //      pthread_mutex_lock(&bufmgr_gem->lock);
  657.         /* Get a buffer out of the cache if available */
  658. retry:
  659.         alloc_from_cache = false;
  660.         if (bucket != NULL && !DRMLISTEMPTY(&bucket->head)) {
  661.                 if (for_render) {
  662.                         /* Allocate new render-target BOs from the tail (MRU)
  663.                          * of the list, as it will likely be hot in the GPU
  664.                          * cache and in the aperture for us.
  665.                          */
  666.                         bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  667.                                               bucket->head.prev, head);
  668.                         DRMLISTDEL(&bo_gem->head);
  669.                         alloc_from_cache = true;
  670.                 } else {
  671.                         /* For non-render-target BOs (where we're probably
  672.                          * going to map it first thing in order to fill it
  673.                          * with data), check if the last BO in the cache is
  674.                          * unbusy, and only reuse in that case. Otherwise,
  675.                          * allocating a new buffer is probably faster than
  676.                          * waiting for the GPU to finish.
  677.                          */
  678.                         bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  679.                                               bucket->head.next, head);
  680.                         if (!drm_intel_gem_bo_busy(&bo_gem->bo)) {
  681.                                 alloc_from_cache = true;
  682.                                 DRMLISTDEL(&bo_gem->head);
  683.                         }
  684.                 }
  685.  
  686.                 if (alloc_from_cache) {
  687.                         if (!drm_intel_gem_bo_madvise_internal
  688.                             (bufmgr_gem, bo_gem, I915_MADV_WILLNEED)) {
  689.                                 drm_intel_gem_bo_free(&bo_gem->bo);
  690.                                 drm_intel_gem_bo_cache_purge_bucket(bufmgr_gem,
  691.                                                                     bucket);
  692.                                 goto retry;
  693.                         }
  694.  
  695.                         if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
  696.                                                                  tiling_mode,
  697.                                                                  stride)) {
  698.                                 drm_intel_gem_bo_free(&bo_gem->bo);
  699.                                 goto retry;
  700.                         }
  701.                 }
  702.         }
  703. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  704.  
  705.         if (!alloc_from_cache) {
  706.                 struct drm_i915_gem_create create;
  707.  
  708.                 bo_gem = calloc(1, sizeof(*bo_gem));
  709.                 if (!bo_gem)
  710.                         return NULL;
  711.  
  712.                 bo_gem->bo.size = bo_size;
  713.  
  714.                 VG_CLEAR(create);
  715.                 create.size = bo_size;
  716.  
  717.                 ret = drmIoctl(bufmgr_gem->fd,
  718.                                DRM_IOCTL_I915_GEM_CREATE,
  719.                                &create);
  720.                 bo_gem->gem_handle = create.handle;
  721.                 bo_gem->bo.handle = bo_gem->gem_handle;
  722.                 if (ret != 0) {
  723.                         free(bo_gem);
  724.                         return NULL;
  725.                 }
  726.                 bo_gem->bo.bufmgr = bufmgr;
  727.  
  728.                 bo_gem->tiling_mode = I915_TILING_NONE;
  729.                 bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  730.                 bo_gem->stride = 0;
  731.  
  732.                 if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
  733.                                                          tiling_mode,
  734.                                                          stride)) {
  735.                     drm_intel_gem_bo_free(&bo_gem->bo);
  736.                     return NULL;
  737.                 }
  738.  
  739.                 DRMINITLISTHEAD(&bo_gem->name_list);
  740.                 DRMINITLISTHEAD(&bo_gem->vma_list);
  741.         }
  742.  
  743.         bo_gem->name = name;
  744.         atomic_set(&bo_gem->refcount, 1);
  745.         bo_gem->validate_index = -1;
  746.         bo_gem->reloc_tree_fences = 0;
  747.         bo_gem->used_as_reloc_target = false;
  748.         bo_gem->has_error = false;
  749.         bo_gem->reusable = true;
  750.         bo_gem->aub_annotations = NULL;
  751.         bo_gem->aub_annotation_count = 0;
  752.  
  753.         drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
  754.  
  755.         DBG("bo_create: buf %d (%s) %ldb\n",
  756.             bo_gem->gem_handle, bo_gem->name, size);
  757.  
  758.         return &bo_gem->bo;
  759. }
  760.  
  761. static drm_intel_bo *
  762. drm_intel_gem_bo_alloc_for_render(drm_intel_bufmgr *bufmgr,
  763.                                   const char *name,
  764.                                   unsigned long size,
  765.                                   unsigned int alignment)
  766. {
  767.         return drm_intel_gem_bo_alloc_internal(bufmgr, name, size,
  768.                                                BO_ALLOC_FOR_RENDER,
  769.                                                I915_TILING_NONE, 0);
  770. }
  771.  
  772. static drm_intel_bo *
  773. drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr,
  774.                        const char *name,
  775.                        unsigned long size,
  776.                        unsigned int alignment)
  777. {
  778.         return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0,
  779.                                                I915_TILING_NONE, 0);
  780. }
  781.  
  782. static drm_intel_bo *
  783. drm_intel_gem_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
  784.                              int x, int y, int cpp, uint32_t *tiling_mode,
  785.                              unsigned long *pitch, unsigned long flags)
  786. {
  787.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  788.         unsigned long size, stride;
  789.         uint32_t tiling;
  790.  
  791.         do {
  792.                 unsigned long aligned_y, height_alignment;
  793.  
  794.                 tiling = *tiling_mode;
  795.  
  796.                 /* If we're tiled, our allocations are in 8 or 32-row blocks,
  797.                  * so failure to align our height means that we won't allocate
  798.                  * enough pages.
  799.                  *
  800.                  * If we're untiled, we still have to align to 2 rows high
  801.                  * because the data port accesses 2x2 blocks even if the
  802.                  * bottom row isn't to be rendered, so failure to align means
  803.                  * we could walk off the end of the GTT and fault.  This is
  804.                  * documented on 965, and may be the case on older chipsets
  805.                  * too so we try to be careful.
  806.                  */
  807.                 aligned_y = y;
  808.                 height_alignment = 2;
  809.  
  810.                 if ((bufmgr_gem->gen == 2) && tiling != I915_TILING_NONE)
  811.                         height_alignment = 16;
  812.                 else if (tiling == I915_TILING_X
  813.                         || (IS_915(bufmgr_gem->pci_device)
  814.                             && tiling == I915_TILING_Y))
  815.                         height_alignment = 8;
  816.                 else if (tiling == I915_TILING_Y)
  817.                         height_alignment = 32;
  818.                 aligned_y = ALIGN(y, height_alignment);
  819.  
  820.                 stride = x * cpp;
  821.                 stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, tiling_mode);
  822.                 size = stride * aligned_y;
  823.                 size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
  824.         } while (*tiling_mode != tiling);
  825.         *pitch = stride;
  826.  
  827.         if (tiling == I915_TILING_NONE)
  828.                 stride = 0;
  829.  
  830.         return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags,
  831.                                                tiling, stride);
  832. }
  833.  
  834. /**
  835.  * Returns a drm_intel_bo wrapping the given buffer object handle.
  836.  *
  837.  * This can be used when one application needs to pass a buffer object
  838.  * to another.
  839.  */
  840. drm_intel_bo *
  841. drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
  842.                                   const char *name,
  843.                                   unsigned int handle)
  844. {
  845.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  846.         drm_intel_bo_gem *bo_gem;
  847.         int ret;
  848.         struct drm_gem_open open_arg;
  849.         struct drm_i915_gem_get_tiling get_tiling;
  850.         drmMMListHead *list;
  851.  
  852.         /* At the moment most applications only have a few named bo.
  853.          * For instance, in a DRI client only the render buffers passed
  854.          * between X and the client are named. And since X returns the
  855.          * alternating names for the front/back buffer a linear search
  856.          * provides a sufficiently fast match.
  857.          */
  858.         for (list = bufmgr_gem->named.next;
  859.              list != &bufmgr_gem->named;
  860.              list = list->next) {
  861.                 bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
  862.                 if (bo_gem->global_name == handle) {
  863.                         drm_intel_gem_bo_reference(&bo_gem->bo);
  864.                         return &bo_gem->bo;
  865.                 }
  866.         }
  867.  
  868.         bo_gem = calloc(1, sizeof(*bo_gem));
  869.         if (!bo_gem)
  870.                 return NULL;
  871.  
  872.         VG_CLEAR(open_arg);
  873.         open_arg.name = handle;
  874.         ret = drmIoctl(bufmgr_gem->fd,
  875.                        DRM_IOCTL_GEM_OPEN,
  876.                        &open_arg);
  877.         if (ret != 0) {
  878.                 DBG("Couldn't reference %s handle 0x%08x: %s\n",
  879.                     name, handle, strerror(errno));
  880.                 free(bo_gem);
  881.                 return NULL;
  882.         }
  883.         bo_gem->bo.size = open_arg.size;
  884.         bo_gem->bo.offset = 0;
  885.         bo_gem->bo.virtual = NULL;
  886.         bo_gem->bo.bufmgr = bufmgr;
  887.         bo_gem->name = name;
  888.         atomic_set(&bo_gem->refcount, 1);
  889.         bo_gem->validate_index = -1;
  890.         bo_gem->gem_handle = open_arg.handle;
  891.         bo_gem->bo.handle = open_arg.handle;
  892.         bo_gem->global_name = handle;
  893.         bo_gem->reusable = false;
  894.  
  895.         VG_CLEAR(get_tiling);
  896.         get_tiling.handle = bo_gem->gem_handle;
  897.         ret = drmIoctl(bufmgr_gem->fd,
  898.                        DRM_IOCTL_I915_GEM_GET_TILING,
  899.                        &get_tiling);
  900.         if (ret != 0) {
  901.                 drm_intel_gem_bo_unreference(&bo_gem->bo);
  902.                 return NULL;
  903.         }
  904.         bo_gem->tiling_mode = get_tiling.tiling_mode;
  905.         bo_gem->swizzle_mode = get_tiling.swizzle_mode;
  906.         /* XXX stride is unknown */
  907.         drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
  908.  
  909.         DRMINITLISTHEAD(&bo_gem->vma_list);
  910.         DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
  911.         DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name);
  912.  
  913.         return &bo_gem->bo;
  914. }
  915.  
  916. static void
  917. drm_intel_gem_bo_free(drm_intel_bo *bo)
  918. {
  919.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  920.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  921.         struct drm_gem_close close;
  922.         int ret;
  923.  
  924.         DRMLISTDEL(&bo_gem->vma_list);
  925.         if (bo_gem->mem_virtual) {
  926.                 VG(VALGRIND_FREELIKE_BLOCK(bo_gem->mem_virtual, 0));
  927.                 bufmgr_gem->vma_count--;
  928.         }
  929.         if (bo_gem->gtt_virtual) {
  930.                 bufmgr_gem->vma_count--;
  931.         }
  932.  
  933.         /* Close this object */
  934.         VG_CLEAR(close);
  935.         close.handle = bo_gem->gem_handle;
  936.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
  937.         if (ret != 0) {
  938.                 DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
  939.                     bo_gem->gem_handle, bo_gem->name, strerror(errno));
  940.         }
  941.         free(bo_gem->aub_annotations);
  942.         free(bo);
  943. }
  944.  
  945. static void
  946. drm_intel_gem_bo_mark_mmaps_incoherent(drm_intel_bo *bo)
  947. {
  948. #if HAVE_VALGRIND
  949.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  950.  
  951.         if (bo_gem->mem_virtual)
  952.                 VALGRIND_MAKE_MEM_NOACCESS(bo_gem->mem_virtual, bo->size);
  953.  
  954.         if (bo_gem->gtt_virtual)
  955.                 VALGRIND_MAKE_MEM_NOACCESS(bo_gem->gtt_virtual, bo->size);
  956. #endif
  957. }
  958.  
  959. /** Frees all cached buffers significantly older than @time. */
  960. static void
  961. drm_intel_gem_cleanup_bo_cache(drm_intel_bufmgr_gem *bufmgr_gem, time_t time)
  962. {
  963.         int i;
  964.  
  965.         if (bufmgr_gem->time == time)
  966.                 return;
  967.  
  968.         for (i = 0; i < bufmgr_gem->num_buckets; i++) {
  969.                 struct drm_intel_gem_bo_bucket *bucket =
  970.                     &bufmgr_gem->cache_bucket[i];
  971.  
  972.                 while (!DRMLISTEMPTY(&bucket->head)) {
  973.                         drm_intel_bo_gem *bo_gem;
  974.  
  975.                         bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  976.                                               bucket->head.next, head);
  977.                         if (time - bo_gem->free_time <= 1)
  978.                                 break;
  979.  
  980.                         DRMLISTDEL(&bo_gem->head);
  981.  
  982.                         drm_intel_gem_bo_free(&bo_gem->bo);
  983.                 }
  984.         }
  985.  
  986.         bufmgr_gem->time = time;
  987. }
  988.  
  989. static void drm_intel_gem_bo_purge_vma_cache(drm_intel_bufmgr_gem *bufmgr_gem)
  990. {
  991.         int limit;
  992.  
  993.         DBG("%s: cached=%d, open=%d, limit=%d\n", __FUNCTION__,
  994.             bufmgr_gem->vma_count, bufmgr_gem->vma_open, bufmgr_gem->vma_max);
  995.  
  996.         if (bufmgr_gem->vma_max < 0)
  997.                 return;
  998.  
  999.         /* We may need to evict a few entries in order to create new mmaps */
  1000.         limit = bufmgr_gem->vma_max - 2*bufmgr_gem->vma_open;
  1001.         if (limit < 0)
  1002.                 limit = 0;
  1003.  
  1004.         while (bufmgr_gem->vma_count > limit) {
  1005.                 drm_intel_bo_gem *bo_gem;
  1006.  
  1007.                 bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  1008.                                       bufmgr_gem->vma_cache.next,
  1009.                                       vma_list);
  1010.                 assert(bo_gem->map_count == 0);
  1011.                 DRMLISTDELINIT(&bo_gem->vma_list);
  1012.  
  1013.                 if (bo_gem->mem_virtual) {
  1014. //                      munmap(bo_gem->mem_virtual, bo_gem->bo.size);
  1015.                         bo_gem->mem_virtual = NULL;
  1016.                         bufmgr_gem->vma_count--;
  1017.                 }
  1018.                 if (bo_gem->gtt_virtual) {
  1019. //                      munmap(bo_gem->gtt_virtual, bo_gem->bo.size);
  1020.                         bo_gem->gtt_virtual = NULL;
  1021.                         bufmgr_gem->vma_count--;
  1022.                 }
  1023.         }
  1024. }
  1025.  
  1026. static void drm_intel_gem_bo_close_vma(drm_intel_bufmgr_gem *bufmgr_gem,
  1027.                                        drm_intel_bo_gem *bo_gem)
  1028. {
  1029.         bufmgr_gem->vma_open--;
  1030.         DRMLISTADDTAIL(&bo_gem->vma_list, &bufmgr_gem->vma_cache);
  1031.         if (bo_gem->mem_virtual)
  1032.                 bufmgr_gem->vma_count++;
  1033.         if (bo_gem->gtt_virtual)
  1034.                 bufmgr_gem->vma_count++;
  1035.         drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
  1036. }
  1037.  
  1038. static void drm_intel_gem_bo_open_vma(drm_intel_bufmgr_gem *bufmgr_gem,
  1039.                                       drm_intel_bo_gem *bo_gem)
  1040. {
  1041.         bufmgr_gem->vma_open++;
  1042.         DRMLISTDEL(&bo_gem->vma_list);
  1043.         if (bo_gem->mem_virtual)
  1044.                 bufmgr_gem->vma_count--;
  1045.         if (bo_gem->gtt_virtual)
  1046.                 bufmgr_gem->vma_count--;
  1047.         drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
  1048. }
  1049.  
  1050. static void
  1051. drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time)
  1052. {
  1053.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1054.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1055.         struct drm_intel_gem_bo_bucket *bucket;
  1056.         int i;
  1057.  
  1058.         /* Unreference all the target buffers */
  1059.         for (i = 0; i < bo_gem->reloc_count; i++) {
  1060.                 if (bo_gem->reloc_target_info[i].bo != bo) {
  1061.                         drm_intel_gem_bo_unreference_locked_timed(bo_gem->
  1062.                                                                   reloc_target_info[i].bo,
  1063.                                                                   time);
  1064.                 }
  1065.         }
  1066.         bo_gem->reloc_count = 0;
  1067.         bo_gem->used_as_reloc_target = false;
  1068.  
  1069.         DBG("bo_unreference final: %d (%s)\n",
  1070.             bo_gem->gem_handle, bo_gem->name);
  1071.  
  1072.         /* release memory associated with this object */
  1073.         if (bo_gem->reloc_target_info) {
  1074.                 free(bo_gem->reloc_target_info);
  1075.                 bo_gem->reloc_target_info = NULL;
  1076.         }
  1077.         if (bo_gem->relocs) {
  1078.                 free(bo_gem->relocs);
  1079.                 bo_gem->relocs = NULL;
  1080.         }
  1081.  
  1082.         /* Clear any left-over mappings */
  1083.         if (bo_gem->map_count) {
  1084.                 DBG("bo freed with non-zero map-count %d\n", bo_gem->map_count);
  1085.                 bo_gem->map_count = 0;
  1086.                 drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
  1087.                 drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1088.         }
  1089.  
  1090.         DRMLISTDEL(&bo_gem->name_list);
  1091.  
  1092.         bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
  1093.         /* Put the buffer into our internal cache for reuse if we can. */
  1094.         if (bufmgr_gem->bo_reuse && bo_gem->reusable && bucket != NULL &&
  1095.             drm_intel_gem_bo_madvise_internal(bufmgr_gem, bo_gem,
  1096.                                               I915_MADV_DONTNEED)) {
  1097.                 bo_gem->free_time = time;
  1098.  
  1099.                 bo_gem->name = NULL;
  1100.                 bo_gem->validate_index = -1;
  1101.  
  1102.                 DRMLISTADDTAIL(&bo_gem->head, &bucket->head);
  1103.         } else {
  1104.                 drm_intel_gem_bo_free(bo);
  1105.         }
  1106. }
  1107.  
  1108. static void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo,
  1109.                                                       time_t time)
  1110. {
  1111.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1112.  
  1113.         assert(atomic_read(&bo_gem->refcount) > 0);
  1114.         if (atomic_dec_and_test(&bo_gem->refcount))
  1115.                 drm_intel_gem_bo_unreference_final(bo, time);
  1116. }
  1117.  
  1118. static void drm_intel_gem_bo_unreference(drm_intel_bo *bo)
  1119. {
  1120.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1121.  
  1122.         assert(atomic_read(&bo_gem->refcount) > 0);
  1123.         if (atomic_dec_and_test(&bo_gem->refcount)) {
  1124.                 drm_intel_bufmgr_gem *bufmgr_gem =
  1125.                     (drm_intel_bufmgr_gem *) bo->bufmgr;
  1126. //              struct timespec time;
  1127.  
  1128. //              clock_gettime(CLOCK_MONOTONIC, &time);
  1129.  
  1130. //              pthread_mutex_lock(&bufmgr_gem->lock);
  1131.                 drm_intel_gem_bo_unreference_final(bo, 0);
  1132.                 drm_intel_gem_cleanup_bo_cache(bufmgr_gem, 0);
  1133. //              pthread_mutex_unlock(&bufmgr_gem->lock);
  1134.         }
  1135. }
  1136.  
  1137. static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
  1138. {
  1139.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1140.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1141.         struct drm_i915_gem_set_domain set_domain;
  1142.         int ret;
  1143.  
  1144. //      pthread_mutex_lock(&bufmgr_gem->lock);
  1145.  
  1146.         if (bo_gem->map_count++ == 0)
  1147.                 drm_intel_gem_bo_open_vma(bufmgr_gem, bo_gem);
  1148.  
  1149.         if (!bo_gem->mem_virtual) {
  1150.                 struct drm_i915_gem_mmap mmap_arg;
  1151.  
  1152.                 DBG("bo_map: %d (%s), map_count=%d\n",
  1153.                     bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
  1154.  
  1155.                 VG_CLEAR(mmap_arg);
  1156.                 mmap_arg.handle = bo_gem->gem_handle;
  1157.                 mmap_arg.offset = 0;
  1158.                 mmap_arg.size = bo->size;
  1159.                 ret = drmIoctl(bufmgr_gem->fd,
  1160.                                DRM_IOCTL_I915_GEM_MMAP,
  1161.                                &mmap_arg);
  1162.                 if (ret != 0) {
  1163.                         ret = -errno;
  1164.                         DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
  1165.                             __FILE__, __LINE__, bo_gem->gem_handle,
  1166.                             bo_gem->name, strerror(errno));
  1167.                         if (--bo_gem->map_count == 0)
  1168.                                 drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
  1169. //                      pthread_mutex_unlock(&bufmgr_gem->lock);
  1170.                         return ret;
  1171.                 }
  1172.                 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
  1173.                 bo_gem->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
  1174.         }
  1175.         DBG("bo_map: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
  1176.             bo_gem->mem_virtual);
  1177.         bo->virtual = bo_gem->mem_virtual;
  1178.  
  1179.         VG_CLEAR(set_domain);
  1180.         set_domain.handle = bo_gem->gem_handle;
  1181.         set_domain.read_domains = I915_GEM_DOMAIN_CPU;
  1182.         if (write_enable)
  1183.                 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
  1184.         else
  1185.                 set_domain.write_domain = 0;
  1186.         ret = drmIoctl(bufmgr_gem->fd,
  1187.                        DRM_IOCTL_I915_GEM_SET_DOMAIN,
  1188.                        &set_domain);
  1189.         if (ret != 0) {
  1190.                 DBG("%s:%d: Error setting to CPU domain %d: %s\n",
  1191.                     __FILE__, __LINE__, bo_gem->gem_handle,
  1192.                     strerror(errno));
  1193.         }
  1194.  
  1195.         if (write_enable)
  1196.                 bo_gem->mapped_cpu_write = true;
  1197.  
  1198.         drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1199.         VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->mem_virtual, bo->size));
  1200. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  1201.  
  1202.         return 0;
  1203. }
  1204.  
  1205. static int
  1206. map_gtt(drm_intel_bo *bo)
  1207. {
  1208.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1209.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1210.         int ret;
  1211.  
  1212.         if (bo_gem->map_count++ == 0)
  1213.                 drm_intel_gem_bo_open_vma(bufmgr_gem, bo_gem);
  1214.  
  1215.         /* Get a mapping of the buffer if we haven't before. */
  1216.         if (bo_gem->gtt_virtual == NULL) {
  1217.                 struct drm_i915_gem_mmap_gtt mmap_arg;
  1218.  
  1219.                 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
  1220.                     bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
  1221.  
  1222.                 VG_CLEAR(mmap_arg);
  1223.                 mmap_arg.handle = bo_gem->gem_handle;
  1224.                 mmap_arg.offset = 0;
  1225.  
  1226.                 /* Get the fake offset back... */
  1227.                 ret = drmIoctl(bufmgr_gem->fd,
  1228.                                DRM_IOCTL_I915_GEM_MMAP_GTT,
  1229.                                &mmap_arg);
  1230.                 if (ret != 0) {
  1231.                         ret = -errno;
  1232.                         DBG("%s:%d: Error preparing buffer map %d (%s): %s .\n",
  1233.                             __FILE__, __LINE__,
  1234.                             bo_gem->gem_handle, bo_gem->name,
  1235.                             strerror(errno));
  1236.                         if (--bo_gem->map_count == 0)
  1237.                                 drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
  1238.                         return ret;
  1239.                 }
  1240.  
  1241.                 /* and mmap it */
  1242.                 bo_gem->gtt_virtual = mmap_arg.offset;
  1243.                 if (bo_gem->gtt_virtual == 0) {
  1244.                         bo_gem->gtt_virtual = NULL;
  1245.                         ret = -errno;
  1246.                         DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
  1247.                             __FILE__, __LINE__,
  1248.                             bo_gem->gem_handle, bo_gem->name,
  1249.                             strerror(errno));
  1250.                         if (--bo_gem->map_count == 0)
  1251.                                 drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
  1252.                         return ret;
  1253.                 }
  1254.         }
  1255.  
  1256.         bo->virtual = bo_gem->gtt_virtual;
  1257.  
  1258.         DBG("bo_map_gtt: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
  1259.             bo_gem->gtt_virtual);
  1260.  
  1261.         return 0;
  1262. }
  1263.  
  1264. int drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
  1265. {
  1266.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1267.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1268.         struct drm_i915_gem_set_domain set_domain;
  1269.         int ret;
  1270.  
  1271. //      pthread_mutex_lock(&bufmgr_gem->lock);
  1272.  
  1273.         ret = map_gtt(bo);
  1274.         if (ret) {
  1275. //              pthread_mutex_unlock(&bufmgr_gem->lock);
  1276.                 return ret;
  1277.         }
  1278.  
  1279.         /* Now move it to the GTT domain so that the GPU and CPU
  1280.          * caches are flushed and the GPU isn't actively using the
  1281.          * buffer.
  1282.          *
  1283.          * The pagefault handler does this domain change for us when
  1284.          * it has unbound the BO from the GTT, but it's up to us to
  1285.          * tell it when we're about to use things if we had done
  1286.          * rendering and it still happens to be bound to the GTT.
  1287.          */
  1288.         VG_CLEAR(set_domain);
  1289.         set_domain.handle = bo_gem->gem_handle;
  1290.         set_domain.read_domains = I915_GEM_DOMAIN_GTT;
  1291.         set_domain.write_domain = I915_GEM_DOMAIN_GTT;
  1292.         ret = drmIoctl(bufmgr_gem->fd,
  1293.                        DRM_IOCTL_I915_GEM_SET_DOMAIN,
  1294.                        &set_domain);
  1295.         if (ret != 0) {
  1296.                 DBG("%s:%d: Error setting domain %d: %s\n",
  1297.                     __FILE__, __LINE__, bo_gem->gem_handle,
  1298.                     strerror(errno));
  1299.         }
  1300.  
  1301.         drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1302.         VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
  1303. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  1304.  
  1305.         return 0;
  1306. }
  1307.  
  1308. /**
  1309.  * Performs a mapping of the buffer object like the normal GTT
  1310.  * mapping, but avoids waiting for the GPU to be done reading from or
  1311.  * rendering to the buffer.
  1312.  *
  1313.  * This is used in the implementation of GL_ARB_map_buffer_range: The
  1314.  * user asks to create a buffer, then does a mapping, fills some
  1315.  * space, runs a drawing command, then asks to map it again without
  1316.  * synchronizing because it guarantees that it won't write over the
  1317.  * data that the GPU is busy using (or, more specifically, that if it
  1318.  * does write over the data, it acknowledges that rendering is
  1319.  * undefined).
  1320.  */
  1321.  
  1322. int drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
  1323. {
  1324.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1325.         int ret;
  1326.  
  1327.         /* If the CPU cache isn't coherent with the GTT, then use a
  1328.          * regular synchronized mapping.  The problem is that we don't
  1329.          * track where the buffer was last used on the CPU side in
  1330.          * terms of drm_intel_bo_map vs drm_intel_gem_bo_map_gtt, so
  1331.          * we would potentially corrupt the buffer even when the user
  1332.          * does reasonable things.
  1333.          */
  1334.         if (!bufmgr_gem->has_llc)
  1335.                 return drm_intel_gem_bo_map_gtt(bo);
  1336.  
  1337. //      pthread_mutex_lock(&bufmgr_gem->lock);
  1338.         ret = map_gtt(bo);
  1339. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  1340.  
  1341.         return ret;
  1342. }
  1343.  
  1344. static int drm_intel_gem_bo_unmap(drm_intel_bo *bo)
  1345. {
  1346.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1347.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1348.         int ret = 0;
  1349.  
  1350.         if (bo == NULL)
  1351.                 return 0;
  1352.  
  1353. //      pthread_mutex_lock(&bufmgr_gem->lock);
  1354.  
  1355.         if (bo_gem->map_count <= 0) {
  1356.                 DBG("attempted to unmap an unmapped bo\n");
  1357. //              pthread_mutex_unlock(&bufmgr_gem->lock);
  1358.                 /* Preserve the old behaviour of just treating this as a
  1359.                  * no-op rather than reporting the error.
  1360.                  */
  1361.                 return 0;
  1362.         }
  1363.  
  1364.         if (bo_gem->mapped_cpu_write) {
  1365.                 struct drm_i915_gem_sw_finish sw_finish;
  1366.  
  1367.                 /* Cause a flush to happen if the buffer's pinned for
  1368.                  * scanout, so the results show up in a timely manner.
  1369.                  * Unlike GTT set domains, this only does work if the
  1370.                  * buffer should be scanout-related.
  1371.                  */
  1372.  
  1373.                 bo_gem->mapped_cpu_write = false;
  1374.         }
  1375.  
  1376.         /* We need to unmap after every innovation as we cannot track
  1377.          * an open vma for every bo as that will exhaasut the system
  1378.          * limits and cause later failures.
  1379.          */
  1380.         if (--bo_gem->map_count == 0) {
  1381.                 drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
  1382.                 drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1383.                 bo->virtual = NULL;
  1384.         }
  1385. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  1386.  
  1387.         return ret;
  1388. }
  1389.  
  1390. int drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
  1391. {
  1392.         return drm_intel_gem_bo_unmap(bo);
  1393. }
  1394.  
  1395. static int
  1396. drm_intel_gem_bo_subdata(drm_intel_bo *bo, unsigned long offset,
  1397.                          unsigned long size, const void *data)
  1398. {
  1399.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1400.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1401.         struct drm_i915_gem_pwrite pwrite;
  1402.         int ret;
  1403.  
  1404.         VG_CLEAR(pwrite);
  1405.         pwrite.handle = bo_gem->gem_handle;
  1406.         pwrite.offset = offset;
  1407.         pwrite.size = size;
  1408.         pwrite.data_ptr = (uint64_t) (uintptr_t) data;
  1409.         ret = drmIoctl(bufmgr_gem->fd,
  1410.                        DRM_IOCTL_I915_GEM_PWRITE,
  1411.                        &pwrite);
  1412.         if (ret != 0) {
  1413.                 ret = -errno;
  1414.                 DBG("%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
  1415.                     __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
  1416.                     (int)size, strerror(errno));
  1417.         }
  1418.  
  1419.         return ret;
  1420. }
  1421.  
  1422. #if 0
  1423. static int
  1424. drm_intel_gem_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
  1425. {
  1426.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  1427.         struct drm_i915_get_pipe_from_crtc_id get_pipe_from_crtc_id;
  1428.         int ret;
  1429.  
  1430.         VG_CLEAR(get_pipe_from_crtc_id);
  1431.         get_pipe_from_crtc_id.crtc_id = crtc_id;
  1432.         ret = drmIoctl(bufmgr_gem->fd,
  1433.                        DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
  1434.                        &get_pipe_from_crtc_id);
  1435.         if (ret != 0) {
  1436.                 /* We return -1 here to signal that we don't
  1437.                  * know which pipe is associated with this crtc.
  1438.                  * This lets the caller know that this information
  1439.                  * isn't available; using the wrong pipe for
  1440.                  * vblank waiting can cause the chipset to lock up
  1441.                  */
  1442.                 return -1;
  1443.         }
  1444.  
  1445.         return get_pipe_from_crtc_id.pipe;
  1446. }
  1447.  
  1448. static int
  1449. drm_intel_gem_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
  1450.                              unsigned long size, void *data)
  1451. {
  1452.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1453.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1454.         struct drm_i915_gem_pread pread;
  1455.         int ret;
  1456.  
  1457.         VG_CLEAR(pread);
  1458.         pread.handle = bo_gem->gem_handle;
  1459.         pread.offset = offset;
  1460.         pread.size = size;
  1461.         pread.data_ptr = (uint64_t) (uintptr_t) data;
  1462.         ret = drmIoctl(bufmgr_gem->fd,
  1463.                        DRM_IOCTL_I915_GEM_PREAD,
  1464.                        &pread);
  1465.         if (ret != 0) {
  1466.                 ret = -errno;
  1467.                 DBG("%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
  1468.                     __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
  1469.                     (int)size, strerror(errno));
  1470.         }
  1471.  
  1472.         return ret;
  1473. }
  1474.  
  1475. #endif
  1476.  
  1477. /** Waits for all GPU rendering with the object to have completed. */
  1478. static void
  1479. drm_intel_gem_bo_wait_rendering(drm_intel_bo *bo)
  1480. {
  1481.         drm_intel_gem_bo_start_gtt_access(bo, 1);
  1482. }
  1483.  
  1484. /**
  1485.  * Waits on a BO for the given amount of time.
  1486.  *
  1487.  * @bo: buffer object to wait for
  1488.  * @timeout_ns: amount of time to wait in nanoseconds.
  1489.  *   If value is less than 0, an infinite wait will occur.
  1490.  *
  1491.  * Returns 0 if the wait was successful ie. the last batch referencing the
  1492.  * object has completed within the allotted time. Otherwise some negative return
  1493.  * value describes the error. Of particular interest is -ETIME when the wait has
  1494.  * failed to yield the desired result.
  1495.  *
  1496.  * Similar to drm_intel_gem_bo_wait_rendering except a timeout parameter allows
  1497.  * the operation to give up after a certain amount of time. Another subtle
  1498.  * difference is the internal locking semantics are different (this variant does
  1499.  * not hold the lock for the duration of the wait). This makes the wait subject
  1500.  * to a larger userspace race window.
  1501.  *
  1502.  * The implementation shall wait until the object is no longer actively
  1503.  * referenced within a batch buffer at the time of the call. The wait will
  1504.  * not guarantee that the buffer is re-issued via another thread, or an flinked
  1505.  * handle. Userspace must make sure this race does not occur if such precision
  1506.  * is important.
  1507.  */
  1508. int drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
  1509. {
  1510.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1511.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1512.         struct drm_i915_gem_wait wait;
  1513.         int ret;
  1514.  
  1515.         if (!bufmgr_gem->has_wait_timeout) {
  1516.                 DBG("%s:%d: Timed wait is not supported. Falling back to "
  1517.                     "infinite wait\n", __FILE__, __LINE__);
  1518.                 if (timeout_ns) {
  1519.                         drm_intel_gem_bo_wait_rendering(bo);
  1520.                         return 0;
  1521.                 } else {
  1522.                         return drm_intel_gem_bo_busy(bo) ? -1 : 0;
  1523.                 }
  1524.         }
  1525.  
  1526.         wait.bo_handle = bo_gem->gem_handle;
  1527.         wait.timeout_ns = timeout_ns;
  1528.         wait.flags = 0;
  1529.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
  1530.         if (ret == -1)
  1531.                 return -errno;
  1532.  
  1533.         return ret;
  1534. }
  1535.  
  1536. /**
  1537.  * Sets the object to the GTT read and possibly write domain, used by the X
  1538.  * 2D driver in the absence of kernel support to do drm_intel_gem_bo_map_gtt().
  1539.  *
  1540.  * In combination with drm_intel_gem_bo_pin() and manual fence management, we
  1541.  * can do tiled pixmaps this way.
  1542.  */
  1543. void
  1544. drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
  1545. {
  1546.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1547.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1548.         struct drm_i915_gem_set_domain set_domain;
  1549.         int ret;
  1550.  
  1551.         VG_CLEAR(set_domain);
  1552.         set_domain.handle = bo_gem->gem_handle;
  1553.         set_domain.read_domains = I915_GEM_DOMAIN_GTT;
  1554.         set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
  1555.         ret = drmIoctl(bufmgr_gem->fd,
  1556.                        DRM_IOCTL_I915_GEM_SET_DOMAIN,
  1557.                        &set_domain);
  1558.         if (ret != 0) {
  1559.                 DBG("%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
  1560.                     __FILE__, __LINE__, bo_gem->gem_handle,
  1561.                     set_domain.read_domains, set_domain.write_domain,
  1562.                     strerror(errno));
  1563.         }
  1564. }
  1565.  
  1566. static void
  1567. drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
  1568. {
  1569.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  1570.         int i;
  1571.  
  1572.         free(bufmgr_gem->exec2_objects);
  1573.         free(bufmgr_gem->exec_objects);
  1574.         free(bufmgr_gem->exec_bos);
  1575.         free(bufmgr_gem->aub_filename);
  1576.  
  1577. //      pthread_mutex_destroy(&bufmgr_gem->lock);
  1578.  
  1579.         /* Free any cached buffer objects we were going to reuse */
  1580.         for (i = 0; i < bufmgr_gem->num_buckets; i++) {
  1581.                 struct drm_intel_gem_bo_bucket *bucket =
  1582.                     &bufmgr_gem->cache_bucket[i];
  1583.                 drm_intel_bo_gem *bo_gem;
  1584.  
  1585.                 while (!DRMLISTEMPTY(&bucket->head)) {
  1586.                         bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
  1587.                                               bucket->head.next, head);
  1588.                         DRMLISTDEL(&bo_gem->head);
  1589.  
  1590.                         drm_intel_gem_bo_free(&bo_gem->bo);
  1591.                 }
  1592.         }
  1593.  
  1594.         free(bufmgr);
  1595. }
  1596.  
  1597. /**
  1598.  * Adds the target buffer to the validation list and adds the relocation
  1599.  * to the reloc_buffer's relocation list.
  1600.  *
  1601.  * The relocation entry at the given offset must already contain the
  1602.  * precomputed relocation value, because the kernel will optimize out
  1603.  * the relocation entry write when the buffer hasn't moved from the
  1604.  * last known offset in target_bo.
  1605.  */
  1606. static int
  1607. do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
  1608.                  drm_intel_bo *target_bo, uint32_t target_offset,
  1609.                  uint32_t read_domains, uint32_t write_domain,
  1610.                  bool need_fence)
  1611. {
  1612.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1613.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1614.         drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
  1615.         bool fenced_command;
  1616.  
  1617.         if (bo_gem->has_error)
  1618.                 return -ENOMEM;
  1619.  
  1620.         if (target_bo_gem->has_error) {
  1621.                 bo_gem->has_error = true;
  1622.                 return -ENOMEM;
  1623.         }
  1624.  
  1625.         /* We never use HW fences for rendering on 965+ */
  1626.         if (bufmgr_gem->gen >= 4)
  1627.                 need_fence = false;
  1628.  
  1629.         fenced_command = need_fence;
  1630.         if (target_bo_gem->tiling_mode == I915_TILING_NONE)
  1631.                 need_fence = false;
  1632.  
  1633.         /* Create a new relocation list if needed */
  1634.         if (bo_gem->relocs == NULL && drm_intel_setup_reloc_list(bo))
  1635.                 return -ENOMEM;
  1636.  
  1637.         /* Check overflow */
  1638.         assert(bo_gem->reloc_count < bufmgr_gem->max_relocs);
  1639.  
  1640.         /* Check args */
  1641.         assert(offset <= bo->size - 4);
  1642.         assert((write_domain & (write_domain - 1)) == 0);
  1643.  
  1644.         /* Make sure that we're not adding a reloc to something whose size has
  1645.          * already been accounted for.
  1646.          */
  1647.         assert(!bo_gem->used_as_reloc_target);
  1648.         if (target_bo_gem != bo_gem) {
  1649.                 target_bo_gem->used_as_reloc_target = true;
  1650.                 bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size;
  1651.         }
  1652.         /* An object needing a fence is a tiled buffer, so it won't have
  1653.          * relocs to other buffers.
  1654.          */
  1655.         if (need_fence)
  1656.                 target_bo_gem->reloc_tree_fences = 1;
  1657.         bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences;
  1658.  
  1659.         bo_gem->relocs[bo_gem->reloc_count].offset = offset;
  1660.         bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
  1661.         bo_gem->relocs[bo_gem->reloc_count].target_handle =
  1662.             target_bo_gem->gem_handle;
  1663.         bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
  1664.         bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
  1665.         bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
  1666.  
  1667.         bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
  1668.         if (target_bo != bo)
  1669.                 drm_intel_gem_bo_reference(target_bo);
  1670.         if (fenced_command)
  1671.                 bo_gem->reloc_target_info[bo_gem->reloc_count].flags =
  1672.                         DRM_INTEL_RELOC_FENCE;
  1673.         else
  1674.                 bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0;
  1675.  
  1676.         bo_gem->reloc_count++;
  1677.  
  1678.         return 0;
  1679. }
  1680.  
  1681. static int
  1682. drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
  1683.                             drm_intel_bo *target_bo, uint32_t target_offset,
  1684.                             uint32_t read_domains, uint32_t write_domain)
  1685. {
  1686.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
  1687.  
  1688.         return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
  1689.                                 read_domains, write_domain,
  1690.                                 !bufmgr_gem->fenced_relocs);
  1691. }
  1692.  
  1693. static int
  1694. drm_intel_gem_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
  1695.                                   drm_intel_bo *target_bo,
  1696.                                   uint32_t target_offset,
  1697.                                   uint32_t read_domains, uint32_t write_domain)
  1698. {
  1699.         return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
  1700.                                 read_domains, write_domain, true);
  1701. }
  1702.  
  1703. int
  1704. drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
  1705. {
  1706.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1707.  
  1708.         return bo_gem->reloc_count;
  1709. }
  1710.  
  1711. /**
  1712.  * Removes existing relocation entries in the BO after "start".
  1713.  *
  1714.  * This allows a user to avoid a two-step process for state setup with
  1715.  * counting up all the buffer objects and doing a
  1716.  * drm_intel_bufmgr_check_aperture_space() before emitting any of the
  1717.  * relocations for the state setup.  Instead, save the state of the
  1718.  * batchbuffer including drm_intel_gem_get_reloc_count(), emit all the
  1719.  * state, and then check if it still fits in the aperture.
  1720.  *
  1721.  * Any further drm_intel_bufmgr_check_aperture_space() queries
  1722.  * involving this buffer in the tree are undefined after this call.
  1723.  */
  1724. void
  1725. drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
  1726. {
  1727.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1728.         int i;
  1729. //      struct timespec time;
  1730.  
  1731. //      clock_gettime(CLOCK_MONOTONIC, &time);
  1732.  
  1733.         assert(bo_gem->reloc_count >= start);
  1734.         /* Unreference the cleared target buffers */
  1735.         for (i = start; i < bo_gem->reloc_count; i++) {
  1736.                 drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) bo_gem->reloc_target_info[i].bo;
  1737.                 if (&target_bo_gem->bo != bo) {
  1738.                         bo_gem->reloc_tree_fences -= target_bo_gem->reloc_tree_fences;
  1739.                         drm_intel_gem_bo_unreference_locked_timed(&target_bo_gem->bo,
  1740.                                                                   0);
  1741.                 }
  1742.         }
  1743.         bo_gem->reloc_count = start;
  1744. }
  1745.  
  1746. /**
  1747.  * Walk the tree of relocations rooted at BO and accumulate the list of
  1748.  * validations to be performed and update the relocation buffers with
  1749.  * index values into the validation list.
  1750.  */
  1751. static void
  1752. drm_intel_gem_bo_process_reloc(drm_intel_bo *bo)
  1753. {
  1754.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1755.         int i;
  1756.  
  1757.         if (bo_gem->relocs == NULL)
  1758.                 return;
  1759.  
  1760.         for (i = 0; i < bo_gem->reloc_count; i++) {
  1761.                 drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
  1762.  
  1763.                 if (target_bo == bo)
  1764.                         continue;
  1765.  
  1766.                 drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1767.  
  1768.                 /* Continue walking the tree depth-first. */
  1769.                 drm_intel_gem_bo_process_reloc(target_bo);
  1770.  
  1771.                 /* Add the target to the validate list */
  1772.                 drm_intel_add_validate_buffer(target_bo);
  1773.         }
  1774. }
  1775.  
  1776. static void
  1777. drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
  1778. {
  1779.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
  1780.         int i;
  1781.  
  1782.         if (bo_gem->relocs == NULL)
  1783.                 return;
  1784.  
  1785.         for (i = 0; i < bo_gem->reloc_count; i++) {
  1786.                 drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
  1787.                 int need_fence;
  1788.  
  1789.                 if (target_bo == bo)
  1790.                         continue;
  1791.  
  1792.                 drm_intel_gem_bo_mark_mmaps_incoherent(bo);
  1793.  
  1794.                 /* Continue walking the tree depth-first. */
  1795.                 drm_intel_gem_bo_process_reloc2(target_bo);
  1796.  
  1797.                 need_fence = (bo_gem->reloc_target_info[i].flags &
  1798.                               DRM_INTEL_RELOC_FENCE);
  1799.  
  1800.                 /* Add the target to the validate list */
  1801.                 drm_intel_add_validate_buffer2(target_bo, need_fence);
  1802.         }
  1803. }
  1804.  
  1805.  
  1806. static void
  1807. drm_intel_update_buffer_offsets(drm_intel_bufmgr_gem *bufmgr_gem)
  1808. {
  1809.         int i;
  1810.  
  1811.         for (i = 0; i < bufmgr_gem->exec_count; i++) {
  1812.                 drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
  1813.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1814.  
  1815.                 /* Update the buffer offset */
  1816.                 if (bufmgr_gem->exec_objects[i].offset != bo->offset) {
  1817.                         DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
  1818.                             bo_gem->gem_handle, bo_gem->name, bo->offset,
  1819.                             (unsigned long long)bufmgr_gem->exec_objects[i].
  1820.                             offset);
  1821.                         bo->offset = bufmgr_gem->exec_objects[i].offset;
  1822.                 }
  1823.         }
  1824. }
  1825.  
  1826. static void
  1827. drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
  1828. {
  1829.         int i;
  1830.  
  1831.         for (i = 0; i < bufmgr_gem->exec_count; i++) {
  1832.                 drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
  1833.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
  1834.  
  1835.                 /* Update the buffer offset */
  1836.                 if (bufmgr_gem->exec2_objects[i].offset != bo->offset) {
  1837.                         DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
  1838.                             bo_gem->gem_handle, bo_gem->name, bo->offset,
  1839.                             (unsigned long long)bufmgr_gem->exec2_objects[i].offset);
  1840.                         bo->offset = bufmgr_gem->exec2_objects[i].offset;
  1841.                 }
  1842.         }
  1843. }
  1844.  
  1845. static void
  1846. aub_out(drm_intel_bufmgr_gem *bufmgr_gem, uint32_t data)
  1847. {
  1848.         fwrite(&data, 1, 4, bufmgr_gem->aub_file);
  1849. }
  1850.  
  1851. static void
  1852. aub_out_data(drm_intel_bufmgr_gem *bufmgr_gem, void *data, size_t size)
  1853. {
  1854.         fwrite(data, 1, size, bufmgr_gem->aub_file);
  1855. }
  1856.  
  1857. static void
  1858. aub_write_bo_data(drm_intel_bo *bo, uint32_t offset, uint32_t size)
  1859. {
  1860.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1861.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1862.         uint32_t *data;
  1863.         unsigned int i;
  1864.  
  1865.         data = malloc(bo->size);
  1866.         drm_intel_bo_get_subdata(bo, offset, size, data);
  1867.  
  1868.         /* Easy mode: write out bo with no relocations */
  1869.         if (!bo_gem->reloc_count) {
  1870.                 aub_out_data(bufmgr_gem, data, size);
  1871.                 free(data);
  1872.                 return;
  1873.         }
  1874.  
  1875.         /* Otherwise, handle the relocations while writing. */
  1876.         for (i = 0; i < size / 4; i++) {
  1877.                 int r;
  1878.                 for (r = 0; r < bo_gem->reloc_count; r++) {
  1879.                         struct drm_i915_gem_relocation_entry *reloc;
  1880.                         drm_intel_reloc_target *info;
  1881.  
  1882.                         reloc = &bo_gem->relocs[r];
  1883.                         info = &bo_gem->reloc_target_info[r];
  1884.  
  1885.                         if (reloc->offset == offset + i * 4) {
  1886.                                 drm_intel_bo_gem *target_gem;
  1887.                                 uint32_t val;
  1888.  
  1889.                                 target_gem = (drm_intel_bo_gem *)info->bo;
  1890.  
  1891.                                 val = reloc->delta;
  1892.                                 val += target_gem->aub_offset;
  1893.  
  1894.                                 aub_out(bufmgr_gem, val);
  1895.                                 data[i] = val;
  1896.                                 break;
  1897.                         }
  1898.                 }
  1899.                 if (r == bo_gem->reloc_count) {
  1900.                         /* no relocation, just the data */
  1901.                         aub_out(bufmgr_gem, data[i]);
  1902.                 }
  1903.         }
  1904.  
  1905.         free(data);
  1906. }
  1907.  
  1908. static void
  1909. aub_bo_get_address(drm_intel_bo *bo)
  1910. {
  1911.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1912.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1913.  
  1914.         /* Give the object a graphics address in the AUB file.  We
  1915.          * don't just use the GEM object address because we do AUB
  1916.          * dumping before execution -- we want to successfully log
  1917.          * when the hardware might hang, and we might even want to aub
  1918.          * capture for a driver trying to execute on a different
  1919.          * generation of hardware by disabling the actual kernel exec
  1920.          * call.
  1921.          */
  1922.         bo_gem->aub_offset = bufmgr_gem->aub_offset;
  1923.         bufmgr_gem->aub_offset += bo->size;
  1924.         /* XXX: Handle aperture overflow. */
  1925.         assert(bufmgr_gem->aub_offset < 256 * 1024 * 1024);
  1926. }
  1927.  
  1928. static void
  1929. aub_write_trace_block(drm_intel_bo *bo, uint32_t type, uint32_t subtype,
  1930.                       uint32_t offset, uint32_t size)
  1931. {
  1932.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  1933.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1934.  
  1935.         aub_out(bufmgr_gem,
  1936.                 CMD_AUB_TRACE_HEADER_BLOCK |
  1937.                 ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
  1938.         aub_out(bufmgr_gem,
  1939.                 AUB_TRACE_MEMTYPE_GTT | type | AUB_TRACE_OP_DATA_WRITE);
  1940.         aub_out(bufmgr_gem, subtype);
  1941.         aub_out(bufmgr_gem, bo_gem->aub_offset + offset);
  1942.         aub_out(bufmgr_gem, size);
  1943.         if (bufmgr_gem->gen >= 8)
  1944.                 aub_out(bufmgr_gem, 0);
  1945.         aub_write_bo_data(bo, offset, size);
  1946. }
  1947.  
  1948. /**
  1949.  * Break up large objects into multiple writes.  Otherwise a 128kb VBO
  1950.  * would overflow the 16 bits of size field in the packet header and
  1951.  * everything goes badly after that.
  1952.  */
  1953. static void
  1954. aub_write_large_trace_block(drm_intel_bo *bo, uint32_t type, uint32_t subtype,
  1955.                             uint32_t offset, uint32_t size)
  1956. {
  1957.         uint32_t block_size;
  1958.         uint32_t sub_offset;
  1959.  
  1960.         for (sub_offset = 0; sub_offset < size; sub_offset += block_size) {
  1961.                 block_size = size - sub_offset;
  1962.  
  1963.                 if (block_size > 8 * 4096)
  1964.                         block_size = 8 * 4096;
  1965.  
  1966.                 aub_write_trace_block(bo, type, subtype, offset + sub_offset,
  1967.                                       block_size);
  1968.         }
  1969. }
  1970.  
  1971. static void
  1972. aub_write_bo(drm_intel_bo *bo)
  1973. {
  1974.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  1975.         uint32_t offset = 0;
  1976.         unsigned i;
  1977.  
  1978.         aub_bo_get_address(bo);
  1979.  
  1980.         /* Write out each annotated section separately. */
  1981.         for (i = 0; i < bo_gem->aub_annotation_count; ++i) {
  1982.                 drm_intel_aub_annotation *annotation =
  1983.                         &bo_gem->aub_annotations[i];
  1984.                 uint32_t ending_offset = annotation->ending_offset;
  1985.                 if (ending_offset > bo->size)
  1986.                         ending_offset = bo->size;
  1987.                 if (ending_offset > offset) {
  1988.                         aub_write_large_trace_block(bo, annotation->type,
  1989.                                                     annotation->subtype,
  1990.                                                     offset,
  1991.                                                     ending_offset - offset);
  1992.                         offset = ending_offset;
  1993.                 }
  1994.         }
  1995.  
  1996.         /* Write out any remaining unannotated data */
  1997.         if (offset < bo->size) {
  1998.                 aub_write_large_trace_block(bo, AUB_TRACE_TYPE_NOTYPE, 0,
  1999.                                             offset, bo->size - offset);
  2000.         }
  2001. }
  2002.  
  2003. /*
  2004.  * Make a ringbuffer on fly and dump it
  2005.  */
  2006. static void
  2007. aub_build_dump_ringbuffer(drm_intel_bufmgr_gem *bufmgr_gem,
  2008.                           uint32_t batch_buffer, int ring_flag)
  2009. {
  2010.         uint32_t ringbuffer[4096];
  2011.         int ring = AUB_TRACE_TYPE_RING_PRB0; /* The default ring */
  2012.         int ring_count = 0;
  2013.  
  2014.         if (ring_flag == I915_EXEC_BSD)
  2015.                 ring = AUB_TRACE_TYPE_RING_PRB1;
  2016.         else if (ring_flag == I915_EXEC_BLT)
  2017.                 ring = AUB_TRACE_TYPE_RING_PRB2;
  2018.  
  2019.         /* Make a ring buffer to execute our batchbuffer. */
  2020.         memset(ringbuffer, 0, sizeof(ringbuffer));
  2021.         if (bufmgr_gem->gen >= 8) {
  2022.                 ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2);
  2023.                 ringbuffer[ring_count++] = batch_buffer;
  2024.                 ringbuffer[ring_count++] = 0;
  2025.         } else {
  2026.         ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
  2027.         ringbuffer[ring_count++] = batch_buffer;
  2028.         }
  2029.  
  2030.         /* Write out the ring.  This appears to trigger execution of
  2031.          * the ring in the simulator.
  2032.          */
  2033.         aub_out(bufmgr_gem,
  2034.                 CMD_AUB_TRACE_HEADER_BLOCK |
  2035.                 ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
  2036.         aub_out(bufmgr_gem,
  2037.                 AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE);
  2038.         aub_out(bufmgr_gem, 0); /* general/surface subtype */
  2039.         aub_out(bufmgr_gem, bufmgr_gem->aub_offset);
  2040.         aub_out(bufmgr_gem, ring_count * 4);
  2041.         if (bufmgr_gem->gen >= 8)
  2042.                 aub_out(bufmgr_gem, 0);
  2043.  
  2044.         /* FIXME: Need some flush operations here? */
  2045.         aub_out_data(bufmgr_gem, ringbuffer, ring_count * 4);
  2046.  
  2047.         /* Update offset pointer */
  2048.         bufmgr_gem->aub_offset += 4096;
  2049. }
  2050.  
  2051. void
  2052. drm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo,
  2053.                               int x1, int y1, int width, int height,
  2054.                               enum aub_dump_bmp_format format,
  2055.                               int pitch, int offset)
  2056. {
  2057.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2058.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
  2059.         uint32_t cpp;
  2060.  
  2061.         switch (format) {
  2062.         case AUB_DUMP_BMP_FORMAT_8BIT:
  2063.                 cpp = 1;
  2064.                 break;
  2065.         case AUB_DUMP_BMP_FORMAT_ARGB_4444:
  2066.                 cpp = 2;
  2067.                 break;
  2068.         case AUB_DUMP_BMP_FORMAT_ARGB_0888:
  2069.         case AUB_DUMP_BMP_FORMAT_ARGB_8888:
  2070.                 cpp = 4;
  2071.                 break;
  2072.         default:
  2073.                 printf("Unknown AUB dump format %d\n", format);
  2074.                 return;
  2075.         }
  2076.  
  2077.         if (!bufmgr_gem->aub_file)
  2078.                 return;
  2079.  
  2080.         aub_out(bufmgr_gem, CMD_AUB_DUMP_BMP | 4);
  2081.         aub_out(bufmgr_gem, (y1 << 16) | x1);
  2082.         aub_out(bufmgr_gem,
  2083.                 (format << 24) |
  2084.                 (cpp << 19) |
  2085.                 pitch / 4);
  2086.         aub_out(bufmgr_gem, (height << 16) | width);
  2087.         aub_out(bufmgr_gem, bo_gem->aub_offset + offset);
  2088.         aub_out(bufmgr_gem,
  2089.                 ((bo_gem->tiling_mode != I915_TILING_NONE) ? (1 << 2) : 0) |
  2090.                 ((bo_gem->tiling_mode == I915_TILING_Y) ? (1 << 3) : 0));
  2091. }
  2092.  
  2093. static void
  2094. aub_exec(drm_intel_bo *bo, int ring_flag, int used)
  2095. {
  2096.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2097.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2098.         int i;
  2099.         bool batch_buffer_needs_annotations;
  2100.  
  2101.         if (!bufmgr_gem->aub_file)
  2102.                 return;
  2103.  
  2104.         /* If batch buffer is not annotated, annotate it the best we
  2105.          * can.
  2106.          */
  2107.         batch_buffer_needs_annotations = bo_gem->aub_annotation_count == 0;
  2108.         if (batch_buffer_needs_annotations) {
  2109.                 drm_intel_aub_annotation annotations[2] = {
  2110.                         { AUB_TRACE_TYPE_BATCH, 0, used },
  2111.                         { AUB_TRACE_TYPE_NOTYPE, 0, bo->size }
  2112.                 };
  2113.                 drm_intel_bufmgr_gem_set_aub_annotations(bo, annotations, 2);
  2114.         }
  2115.  
  2116.         /* Write out all buffers to AUB memory */
  2117.         for (i = 0; i < bufmgr_gem->exec_count; i++) {
  2118.                 aub_write_bo(bufmgr_gem->exec_bos[i]);
  2119.         }
  2120.  
  2121.         /* Remove any annotations we added */
  2122.         if (batch_buffer_needs_annotations)
  2123.                 drm_intel_bufmgr_gem_set_aub_annotations(bo, NULL, 0);
  2124.  
  2125.         /* Dump ring buffer */
  2126.         aub_build_dump_ringbuffer(bufmgr_gem, bo_gem->aub_offset, ring_flag);
  2127.  
  2128.         fflush(bufmgr_gem->aub_file);
  2129.  
  2130.         /*
  2131.          * One frame has been dumped. So reset the aub_offset for the next frame.
  2132.          *
  2133.          * FIXME: Can we do this?
  2134.          */
  2135.         bufmgr_gem->aub_offset = 0x10000;
  2136. }
  2137.  
  2138.  
  2139. static int
  2140. do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
  2141.          drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
  2142.          unsigned int flags)
  2143. {
  2144.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
  2145.         struct drm_i915_gem_execbuffer2 execbuf;
  2146.         int ret = 0;
  2147.         int i;
  2148.  
  2149.         switch (flags & 0x7) {
  2150.         default:
  2151.                 return -EINVAL;
  2152.         case I915_EXEC_BLT:
  2153.                 if (!bufmgr_gem->has_blt)
  2154.                         return -EINVAL;
  2155.                 break;
  2156.         case I915_EXEC_BSD:
  2157.                 if (!bufmgr_gem->has_bsd)
  2158.                         return -EINVAL;
  2159.                 break;
  2160.         case I915_EXEC_VEBOX:
  2161.                 if (!bufmgr_gem->has_vebox)
  2162.                         return -EINVAL;
  2163.                 break;
  2164.         case I915_EXEC_RENDER:
  2165.         case I915_EXEC_DEFAULT:
  2166.                 break;
  2167.         }
  2168.  
  2169. //      pthread_mutex_lock(&bufmgr_gem->lock);
  2170.         /* Update indices and set up the validate list. */
  2171.         drm_intel_gem_bo_process_reloc2(bo);
  2172.  
  2173.         /* Add the batch buffer to the validation list.  There are no relocations
  2174.          * pointing to it.
  2175.          */
  2176.         drm_intel_add_validate_buffer2(bo, 0);
  2177.  
  2178.         VG_CLEAR(execbuf);
  2179.         execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
  2180.         execbuf.buffer_count = bufmgr_gem->exec_count;
  2181.         execbuf.batch_start_offset = 0;
  2182.         execbuf.batch_len = used;
  2183.         execbuf.cliprects_ptr = (uintptr_t)cliprects;
  2184.         execbuf.num_cliprects = num_cliprects;
  2185.         execbuf.DR1 = 0;
  2186.         execbuf.DR4 = DR4;
  2187.         execbuf.flags = flags;
  2188.         if (ctx == NULL)
  2189.                 i915_execbuffer2_set_context_id(execbuf, 0);
  2190.         else
  2191.                 i915_execbuffer2_set_context_id(execbuf, ctx->ctx_id);
  2192.         execbuf.rsvd2 = 0;
  2193.  
  2194.         aub_exec(bo, flags, used);
  2195.  
  2196.         if (bufmgr_gem->no_exec)
  2197.                 goto skip_execution;
  2198.  
  2199.         ret = drmIoctl(bufmgr_gem->fd,
  2200.                        DRM_IOCTL_I915_GEM_EXECBUFFER2,
  2201.                        &execbuf);
  2202.         if (ret != 0) {
  2203.                 ret = -errno;
  2204.                 if (ret == -ENOSPC) {
  2205.                         DBG("Execbuffer fails to pin. "
  2206.                             "Estimate: %u. Actual: %u. Available: %u\n",
  2207.                             drm_intel_gem_estimate_batch_space(bufmgr_gem->exec_bos,
  2208.                                                                bufmgr_gem->exec_count),
  2209.                             drm_intel_gem_compute_batch_space(bufmgr_gem->exec_bos,
  2210.                                                               bufmgr_gem->exec_count),
  2211.                             (unsigned int) bufmgr_gem->gtt_size);
  2212.                 }
  2213.         }
  2214.         drm_intel_update_buffer_offsets2(bufmgr_gem);
  2215.  
  2216. skip_execution:
  2217.         if (bufmgr_gem->bufmgr.debug)
  2218.                 drm_intel_gem_dump_validation_list(bufmgr_gem);
  2219.  
  2220.         for (i = 0; i < bufmgr_gem->exec_count; i++) {
  2221.                 drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
  2222.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
  2223.  
  2224.                 /* Disconnect the buffer from the validate list */
  2225.                 bo_gem->validate_index = -1;
  2226.                 bufmgr_gem->exec_bos[i] = NULL;
  2227.         }
  2228.         bufmgr_gem->exec_count = 0;
  2229. //      pthread_mutex_unlock(&bufmgr_gem->lock);
  2230.  
  2231.         return ret;
  2232. }
  2233.  
  2234. static int
  2235. drm_intel_gem_bo_exec2(drm_intel_bo *bo, int used,
  2236.                        drm_clip_rect_t *cliprects, int num_cliprects,
  2237.                        int DR4)
  2238. {
  2239.         return do_exec2(bo, used, NULL, cliprects, num_cliprects, DR4,
  2240.                         I915_EXEC_RENDER);
  2241. }
  2242.  
  2243. static int
  2244. drm_intel_gem_bo_mrb_exec2(drm_intel_bo *bo, int used,
  2245.                         drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
  2246.                         unsigned int flags)
  2247. {
  2248.         return do_exec2(bo, used, NULL, cliprects, num_cliprects, DR4,
  2249.                         flags);
  2250. }
  2251.  
  2252. int
  2253. drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
  2254.                               int used, unsigned int flags)
  2255. {
  2256.         return do_exec2(bo, used, ctx, NULL, 0, 0, flags);
  2257. }
  2258.  
  2259. static int
  2260. drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
  2261. {
  2262.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2263.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2264.         struct drm_i915_gem_pin pin;
  2265.         int ret;
  2266.  
  2267.         VG_CLEAR(pin);
  2268.         pin.handle = bo_gem->gem_handle;
  2269.         pin.alignment = alignment;
  2270.  
  2271.         ret = drmIoctl(bufmgr_gem->fd,
  2272.                        DRM_IOCTL_I915_GEM_PIN,
  2273.                        &pin);
  2274.         if (ret != 0)
  2275.                 return -errno;
  2276.  
  2277.         bo->offset = pin.offset;
  2278.         return 0;
  2279. }
  2280.  
  2281. static int
  2282. drm_intel_gem_bo_unpin(drm_intel_bo *bo)
  2283. {
  2284.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2285.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2286.         struct drm_i915_gem_unpin unpin;
  2287.         int ret;
  2288.  
  2289.         VG_CLEAR(unpin);
  2290.         unpin.handle = bo_gem->gem_handle;
  2291.  
  2292.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
  2293.         if (ret != 0)
  2294.                 return -errno;
  2295.  
  2296.         return 0;
  2297. }
  2298.  
  2299. static int
  2300. drm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
  2301.                                      uint32_t tiling_mode,
  2302.                                      uint32_t stride)
  2303. {
  2304.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2305.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2306.         struct drm_i915_gem_set_tiling set_tiling;
  2307.         int ret;
  2308.  
  2309.         if (bo_gem->global_name == 0 &&
  2310.             tiling_mode == bo_gem->tiling_mode &&
  2311.             stride == bo_gem->stride)
  2312.                 return 0;
  2313.  
  2314.         memset(&set_tiling, 0, sizeof(set_tiling));
  2315. //      do {
  2316.                 /* set_tiling is slightly broken and overwrites the
  2317.                  * input on the error path, so we have to open code
  2318.                  * rmIoctl.
  2319.                  */
  2320.                 set_tiling.handle = bo_gem->gem_handle;
  2321.                 set_tiling.tiling_mode = tiling_mode;
  2322.                 set_tiling.stride = stride;
  2323.  
  2324.                 ret = drmIoctl(bufmgr_gem->fd,
  2325.                             DRM_IOCTL_I915_GEM_SET_TILING,
  2326.                             &set_tiling);
  2327. //      } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
  2328.         if (ret == -1)
  2329.                 return -errno;
  2330.  
  2331.         bo_gem->tiling_mode = set_tiling.tiling_mode;
  2332.         bo_gem->swizzle_mode = set_tiling.swizzle_mode;
  2333.         bo_gem->stride = set_tiling.stride;
  2334.         return 0;
  2335. }
  2336.  
  2337. static int
  2338. drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
  2339.                             uint32_t stride)
  2340. {
  2341.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2342.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2343.         int ret;
  2344.  
  2345.         /* Linear buffers have no stride. By ensuring that we only ever use
  2346.          * stride 0 with linear buffers, we simplify our code.
  2347.          */
  2348.         if (*tiling_mode == I915_TILING_NONE)
  2349.                 stride = 0;
  2350.  
  2351.         ret = drm_intel_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
  2352.         if (ret == 0)
  2353.                 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
  2354.  
  2355.         *tiling_mode = bo_gem->tiling_mode;
  2356.         return ret;
  2357. }
  2358.  
  2359. static int
  2360. drm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
  2361.                             uint32_t * swizzle_mode)
  2362. {
  2363.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2364.  
  2365.         *tiling_mode = bo_gem->tiling_mode;
  2366.         *swizzle_mode = bo_gem->swizzle_mode;
  2367.         return 0;
  2368. }
  2369.  
  2370. #if 0
  2371. drm_intel_bo *
  2372. drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
  2373. {
  2374.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  2375.         int ret;
  2376.         uint32_t handle;
  2377.         drm_intel_bo_gem *bo_gem;
  2378.         struct drm_i915_gem_get_tiling get_tiling;
  2379.         drmMMListHead *list;
  2380.  
  2381.         ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
  2382.  
  2383.         /*
  2384.          * See if the kernel has already returned this buffer to us. Just as
  2385.          * for named buffers, we must not create two bo's pointing at the same
  2386.          * kernel object
  2387.          */
  2388.         for (list = bufmgr_gem->named.next;
  2389.              list != &bufmgr_gem->named;
  2390.              list = list->next) {
  2391.                 bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
  2392.                 if (bo_gem->gem_handle == handle) {
  2393.                         drm_intel_gem_bo_reference(&bo_gem->bo);
  2394.                         return &bo_gem->bo;
  2395.                 }
  2396.         }
  2397.  
  2398.         if (ret) {
  2399.           fprintf(stderr,"ret is %d %d\n", ret, errno);
  2400.                 return NULL;
  2401.         }
  2402.  
  2403.         bo_gem = calloc(1, sizeof(*bo_gem));
  2404.         if (!bo_gem)
  2405.                 return NULL;
  2406.  
  2407.         /* Determine size of bo.  The fd-to-handle ioctl really should
  2408.          * return the size, but it doesn't.  If we have kernel 3.12 or
  2409.          * later, we can lseek on the prime fd to get the size.  Older
  2410.          * kernels will just fail, in which case we fall back to the
  2411.          * provided (estimated or guess size). */
  2412.         ret = lseek(prime_fd, 0, SEEK_END);
  2413.         if (ret != -1)
  2414.                 bo_gem->bo.size = ret;
  2415.         else
  2416.         bo_gem->bo.size = size;
  2417.  
  2418.         bo_gem->bo.handle = handle;
  2419.         bo_gem->bo.bufmgr = bufmgr;
  2420.  
  2421.         bo_gem->gem_handle = handle;
  2422.  
  2423.         atomic_set(&bo_gem->refcount, 1);
  2424.  
  2425.         bo_gem->name = "prime";
  2426.         bo_gem->validate_index = -1;
  2427.         bo_gem->reloc_tree_fences = 0;
  2428.         bo_gem->used_as_reloc_target = false;
  2429.         bo_gem->has_error = false;
  2430.         bo_gem->reusable = false;
  2431.  
  2432.         DRMINITLISTHEAD(&bo_gem->vma_list);
  2433.         DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
  2434.  
  2435.         VG_CLEAR(get_tiling);
  2436.         get_tiling.handle = bo_gem->gem_handle;
  2437.         ret = drmIoctl(bufmgr_gem->fd,
  2438.                        DRM_IOCTL_I915_GEM_GET_TILING,
  2439.                        &get_tiling);
  2440.         if (ret != 0) {
  2441.                 drm_intel_gem_bo_unreference(&bo_gem->bo);
  2442.                 return NULL;
  2443.         }
  2444.         bo_gem->tiling_mode = get_tiling.tiling_mode;
  2445.         bo_gem->swizzle_mode = get_tiling.swizzle_mode;
  2446.         /* XXX stride is unknown */
  2447.         drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
  2448.  
  2449.         return &bo_gem->bo;
  2450. }
  2451.  
  2452. int
  2453. drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
  2454. {
  2455.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2456.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2457.  
  2458.         if (DRMLISTEMPTY(&bo_gem->name_list))
  2459.                 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
  2460.  
  2461.         if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle,
  2462.                                DRM_CLOEXEC, prime_fd) != 0)
  2463.                 return -errno;
  2464.  
  2465.         bo_gem->reusable = false;
  2466.  
  2467.         return 0;
  2468. }
  2469. #endif
  2470.  
  2471. static int
  2472. drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
  2473. {
  2474.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
  2475.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2476.         int ret;
  2477.  
  2478.         if (!bo_gem->global_name) {
  2479.                 struct drm_gem_flink flink;
  2480.  
  2481.                 VG_CLEAR(flink);
  2482.                 flink.handle = bo_gem->gem_handle;
  2483.  
  2484.                 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
  2485.                 if (ret != 0)
  2486.                         return -errno;
  2487.  
  2488.                 bo_gem->global_name = flink.name;
  2489.                 bo_gem->reusable = false;
  2490.  
  2491.                 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
  2492.         }
  2493.  
  2494.         *name = bo_gem->global_name;
  2495.         return 0;
  2496. }
  2497.  
  2498. /**
  2499.  * Enables unlimited caching of buffer objects for reuse.
  2500.  *
  2501.  * This is potentially very memory expensive, as the cache at each bucket
  2502.  * size is only bounded by how many buffers of that size we've managed to have
  2503.  * in flight at once.
  2504.  */
  2505. void
  2506. drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
  2507. {
  2508.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  2509.  
  2510.         bufmgr_gem->bo_reuse = true;
  2511. }
  2512.  
  2513. /**
  2514.  * Enable use of fenced reloc type.
  2515.  *
  2516.  * New code should enable this to avoid unnecessary fence register
  2517.  * allocation.  If this option is not enabled, all relocs will have fence
  2518.  * register allocated.
  2519.  */
  2520. void
  2521. drm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr)
  2522. {
  2523.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2524.  
  2525.         if (bufmgr_gem->bufmgr.bo_exec == drm_intel_gem_bo_exec2)
  2526.                 bufmgr_gem->fenced_relocs = true;
  2527. }
  2528.  
  2529. /**
  2530.  * Return the additional aperture space required by the tree of buffer objects
  2531.  * rooted at bo.
  2532.  */
  2533. static int
  2534. drm_intel_gem_bo_get_aperture_space(drm_intel_bo *bo)
  2535. {
  2536.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2537.         int i;
  2538.         int total = 0;
  2539.  
  2540.         if (bo == NULL || bo_gem->included_in_check_aperture)
  2541.                 return 0;
  2542.  
  2543.         total += bo->size;
  2544.         bo_gem->included_in_check_aperture = true;
  2545.  
  2546.         for (i = 0; i < bo_gem->reloc_count; i++)
  2547.                 total +=
  2548.                     drm_intel_gem_bo_get_aperture_space(bo_gem->
  2549.                                                         reloc_target_info[i].bo);
  2550.  
  2551.         return total;
  2552. }
  2553.  
  2554. /**
  2555.  * Count the number of buffers in this list that need a fence reg
  2556.  *
  2557.  * If the count is greater than the number of available regs, we'll have
  2558.  * to ask the caller to resubmit a batch with fewer tiled buffers.
  2559.  *
  2560.  * This function over-counts if the same buffer is used multiple times.
  2561.  */
  2562. static unsigned int
  2563. drm_intel_gem_total_fences(drm_intel_bo ** bo_array, int count)
  2564. {
  2565.         int i;
  2566.         unsigned int total = 0;
  2567.  
  2568.         for (i = 0; i < count; i++) {
  2569.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo_array[i];
  2570.  
  2571.                 if (bo_gem == NULL)
  2572.                         continue;
  2573.  
  2574.                 total += bo_gem->reloc_tree_fences;
  2575.         }
  2576.         return total;
  2577. }
  2578.  
  2579. /**
  2580.  * Clear the flag set by drm_intel_gem_bo_get_aperture_space() so we're ready
  2581.  * for the next drm_intel_bufmgr_check_aperture_space() call.
  2582.  */
  2583. static void
  2584. drm_intel_gem_bo_clear_aperture_space_flag(drm_intel_bo *bo)
  2585. {
  2586.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2587.         int i;
  2588.  
  2589.         if (bo == NULL || !bo_gem->included_in_check_aperture)
  2590.                 return;
  2591.  
  2592.         bo_gem->included_in_check_aperture = false;
  2593.  
  2594.         for (i = 0; i < bo_gem->reloc_count; i++)
  2595.                 drm_intel_gem_bo_clear_aperture_space_flag(bo_gem->
  2596.                                                            reloc_target_info[i].bo);
  2597. }
  2598.  
  2599. /**
  2600.  * Return a conservative estimate for the amount of aperture required
  2601.  * for a collection of buffers. This may double-count some buffers.
  2602.  */
  2603. static unsigned int
  2604. drm_intel_gem_estimate_batch_space(drm_intel_bo **bo_array, int count)
  2605. {
  2606.         int i;
  2607.         unsigned int total = 0;
  2608.  
  2609.         for (i = 0; i < count; i++) {
  2610.                 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo_array[i];
  2611.                 if (bo_gem != NULL)
  2612.                         total += bo_gem->reloc_tree_size;
  2613.         }
  2614.         return total;
  2615. }
  2616.  
  2617. /**
  2618.  * Return the amount of aperture needed for a collection of buffers.
  2619.  * This avoids double counting any buffers, at the cost of looking
  2620.  * at every buffer in the set.
  2621.  */
  2622. static unsigned int
  2623. drm_intel_gem_compute_batch_space(drm_intel_bo **bo_array, int count)
  2624. {
  2625.         int i;
  2626.         unsigned int total = 0;
  2627.  
  2628.         for (i = 0; i < count; i++) {
  2629.                 total += drm_intel_gem_bo_get_aperture_space(bo_array[i]);
  2630.                 /* For the first buffer object in the array, we get an
  2631.                  * accurate count back for its reloc_tree size (since nothing
  2632.                  * had been flagged as being counted yet).  We can save that
  2633.                  * value out as a more conservative reloc_tree_size that
  2634.                  * avoids double-counting target buffers.  Since the first
  2635.                  * buffer happens to usually be the batch buffer in our
  2636.                  * callers, this can pull us back from doing the tree
  2637.                  * walk on every new batch emit.
  2638.                  */
  2639.                 if (i == 0) {
  2640.                         drm_intel_bo_gem *bo_gem =
  2641.                             (drm_intel_bo_gem *) bo_array[i];
  2642.                         bo_gem->reloc_tree_size = total;
  2643.                 }
  2644.         }
  2645.  
  2646.         for (i = 0; i < count; i++)
  2647.                 drm_intel_gem_bo_clear_aperture_space_flag(bo_array[i]);
  2648.         return total;
  2649. }
  2650.  
  2651. /**
  2652.  * Return -1 if the batchbuffer should be flushed before attempting to
  2653.  * emit rendering referencing the buffers pointed to by bo_array.
  2654.  *
  2655.  * This is required because if we try to emit a batchbuffer with relocations
  2656.  * to a tree of buffers that won't simultaneously fit in the aperture,
  2657.  * the rendering will return an error at a point where the software is not
  2658.  * prepared to recover from it.
  2659.  *
  2660.  * However, we also want to emit the batchbuffer significantly before we reach
  2661.  * the limit, as a series of batchbuffers each of which references buffers
  2662.  * covering almost all of the aperture means that at each emit we end up
  2663.  * waiting to evict a buffer from the last rendering, and we get synchronous
  2664.  * performance.  By emitting smaller batchbuffers, we eat some CPU overhead to
  2665.  * get better parallelism.
  2666.  */
  2667. static int
  2668. drm_intel_gem_check_aperture_space(drm_intel_bo **bo_array, int count)
  2669. {
  2670.         drm_intel_bufmgr_gem *bufmgr_gem =
  2671.             (drm_intel_bufmgr_gem *) bo_array[0]->bufmgr;
  2672.         unsigned int total = 0;
  2673.         unsigned int threshold = bufmgr_gem->gtt_size * 3 / 4;
  2674.         int total_fences;
  2675.  
  2676.         /* Check for fence reg constraints if necessary */
  2677.         if (bufmgr_gem->available_fences) {
  2678.                 total_fences = drm_intel_gem_total_fences(bo_array, count);
  2679.                 if (total_fences > bufmgr_gem->available_fences)
  2680.                         return -ENOSPC;
  2681.         }
  2682.  
  2683.         total = drm_intel_gem_estimate_batch_space(bo_array, count);
  2684.  
  2685.         if (total > threshold)
  2686.                 total = drm_intel_gem_compute_batch_space(bo_array, count);
  2687.  
  2688.         if (total > threshold) {
  2689.                 DBG("check_space: overflowed available aperture, "
  2690.                     "%dkb vs %dkb\n",
  2691.                     total / 1024, (int)bufmgr_gem->gtt_size / 1024);
  2692.                 return -ENOSPC;
  2693.         } else {
  2694.                 DBG("drm_check_space: total %dkb vs bufgr %dkb\n", total / 1024,
  2695.                     (int)bufmgr_gem->gtt_size / 1024);
  2696.                 return 0;
  2697.         }
  2698. }
  2699.  
  2700. /*
  2701.  * Disable buffer reuse for objects which are shared with the kernel
  2702.  * as scanout buffers
  2703.  */
  2704. static int
  2705. drm_intel_gem_bo_disable_reuse(drm_intel_bo *bo)
  2706. {
  2707.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2708.  
  2709.         bo_gem->reusable = false;
  2710.         return 0;
  2711. }
  2712.  
  2713. static int
  2714. drm_intel_gem_bo_is_reusable(drm_intel_bo *bo)
  2715. {
  2716.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2717.  
  2718.         return bo_gem->reusable;
  2719. }
  2720.  
  2721. static int
  2722. _drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
  2723. {
  2724.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2725.         int i;
  2726.  
  2727.         for (i = 0; i < bo_gem->reloc_count; i++) {
  2728.                 if (bo_gem->reloc_target_info[i].bo == target_bo)
  2729.                         return 1;
  2730.                 if (bo == bo_gem->reloc_target_info[i].bo)
  2731.                         continue;
  2732.                 if (_drm_intel_gem_bo_references(bo_gem->reloc_target_info[i].bo,
  2733.                                                 target_bo))
  2734.                         return 1;
  2735.         }
  2736.  
  2737.         return 0;
  2738. }
  2739.  
  2740. /** Return true if target_bo is referenced by bo's relocation tree. */
  2741. static int
  2742. drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
  2743. {
  2744.         drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
  2745.  
  2746.         if (bo == NULL || target_bo == NULL)
  2747.                 return 0;
  2748.         if (target_bo_gem->used_as_reloc_target)
  2749.                 return _drm_intel_gem_bo_references(bo, target_bo);
  2750.         return 0;
  2751. }
  2752.  
  2753. static void
  2754. add_bucket(drm_intel_bufmgr_gem *bufmgr_gem, int size)
  2755. {
  2756.         unsigned int i = bufmgr_gem->num_buckets;
  2757.  
  2758.         assert(i < ARRAY_SIZE(bufmgr_gem->cache_bucket));
  2759.  
  2760.         DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head);
  2761.         bufmgr_gem->cache_bucket[i].size = size;
  2762.         bufmgr_gem->num_buckets++;
  2763. }
  2764.  
  2765. static void
  2766. init_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem)
  2767. {
  2768.         unsigned long size, cache_max_size = 64 * 1024 * 1024;
  2769.  
  2770.         /* OK, so power of two buckets was too wasteful of memory.
  2771.          * Give 3 other sizes between each power of two, to hopefully
  2772.          * cover things accurately enough.  (The alternative is
  2773.          * probably to just go for exact matching of sizes, and assume
  2774.          * that for things like composited window resize the tiled
  2775.          * width/height alignment and rounding of sizes to pages will
  2776.          * get us useful cache hit rates anyway)
  2777.          */
  2778.         add_bucket(bufmgr_gem, 4096);
  2779.         add_bucket(bufmgr_gem, 4096 * 2);
  2780.         add_bucket(bufmgr_gem, 4096 * 3);
  2781.  
  2782.         /* Initialize the linked lists for BO reuse cache. */
  2783.         for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
  2784.                 add_bucket(bufmgr_gem, size);
  2785.  
  2786.                 add_bucket(bufmgr_gem, size + size * 1 / 4);
  2787.                 add_bucket(bufmgr_gem, size + size * 2 / 4);
  2788.                 add_bucket(bufmgr_gem, size + size * 3 / 4);
  2789.         }
  2790. }
  2791.  
  2792. void
  2793. drm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit)
  2794. {
  2795.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2796.  
  2797.         bufmgr_gem->vma_max = limit;
  2798.  
  2799.         drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
  2800. }
  2801.  
  2802. /**
  2803.  * Get the PCI ID for the device.  This can be overridden by setting the
  2804.  * INTEL_DEVID_OVERRIDE environment variable to the desired ID.
  2805.  */
  2806. static int
  2807. get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
  2808. {
  2809.         char *devid_override;
  2810.         int devid;
  2811.         int ret;
  2812.         drm_i915_getparam_t gp;
  2813.  
  2814.         VG_CLEAR(devid);
  2815.         VG_CLEAR(gp);
  2816.         gp.param = I915_PARAM_CHIPSET_ID;
  2817.         gp.value = &devid;
  2818.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  2819.         if (ret) {
  2820.                 fprintf(stderr, "get chip id failed: %d [%d]\n", ret, errno);
  2821.                 fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value);
  2822.         }
  2823.         return devid;
  2824. }
  2825.  
  2826. int
  2827. drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
  2828. {
  2829.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2830.  
  2831.         return bufmgr_gem->pci_device;
  2832. }
  2833.  
  2834. /**
  2835.  * Sets up AUB dumping.
  2836.  *
  2837.  * This is a trace file format that can be used with the simulator.
  2838.  * Packets are emitted in a format somewhat like GPU command packets.
  2839.  * You can set up a GTT and upload your objects into the referenced
  2840.  * space, then send off batchbuffers and get BMPs out the other end.
  2841.  */
  2842. void
  2843. drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
  2844. {
  2845.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2846.         int entry = 0x200003;
  2847.         int i;
  2848.         int gtt_size = 0x10000;
  2849.         const char *filename;
  2850.  
  2851.         if (!enable) {
  2852.                 if (bufmgr_gem->aub_file) {
  2853.                         fclose(bufmgr_gem->aub_file);
  2854.                         bufmgr_gem->aub_file = NULL;
  2855.                 }
  2856.                 return;
  2857.         }
  2858.  
  2859.         bufmgr_gem->aub_file = fopen("intel.aub", "w+");
  2860.         if (!bufmgr_gem->aub_file)
  2861.                 return;
  2862.  
  2863.         /* Start allocating objects from just after the GTT. */
  2864.         bufmgr_gem->aub_offset = gtt_size;
  2865.  
  2866.         /* Start with a (required) version packet. */
  2867.         aub_out(bufmgr_gem, CMD_AUB_HEADER | (13 - 2));
  2868.         aub_out(bufmgr_gem,
  2869.                 (4 << AUB_HEADER_MAJOR_SHIFT) |
  2870.                 (0 << AUB_HEADER_MINOR_SHIFT));
  2871.         for (i = 0; i < 8; i++) {
  2872.                 aub_out(bufmgr_gem, 0); /* app name */
  2873.         }
  2874.         aub_out(bufmgr_gem, 0); /* timestamp */
  2875.         aub_out(bufmgr_gem, 0); /* timestamp */
  2876.         aub_out(bufmgr_gem, 0); /* comment len */
  2877.  
  2878.         /* Set up the GTT. The max we can handle is 256M */
  2879.         aub_out(bufmgr_gem, CMD_AUB_TRACE_HEADER_BLOCK | (5 - 2));
  2880.         aub_out(bufmgr_gem, AUB_TRACE_MEMTYPE_NONLOCAL | 0 | AUB_TRACE_OP_DATA_WRITE);
  2881.         aub_out(bufmgr_gem, 0); /* subtype */
  2882.         aub_out(bufmgr_gem, 0); /* offset */
  2883.         aub_out(bufmgr_gem, gtt_size); /* size */
  2884.         for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) {
  2885.                 aub_out(bufmgr_gem, entry);
  2886.         }
  2887. }
  2888.  
  2889. drm_intel_context *
  2890. drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
  2891. {
  2892.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2893.         struct drm_i915_gem_context_create create;
  2894.         drm_intel_context *context = NULL;
  2895.         int ret;
  2896.  
  2897.         VG_CLEAR(create);
  2898.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
  2899.         if (ret != 0) {
  2900.                 DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
  2901.                     strerror(errno));
  2902.                 return NULL;
  2903.         }
  2904.  
  2905.         context = calloc(1, sizeof(*context));
  2906.         context->ctx_id = create.ctx_id;
  2907.         context->bufmgr = bufmgr;
  2908.  
  2909.         return context;
  2910. }
  2911.  
  2912. void
  2913. drm_intel_gem_context_destroy(drm_intel_context *ctx)
  2914. {
  2915.         drm_intel_bufmgr_gem *bufmgr_gem;
  2916.         struct drm_i915_gem_context_destroy destroy;
  2917.         int ret;
  2918.  
  2919.         if (ctx == NULL)
  2920.                 return;
  2921.  
  2922.         VG_CLEAR(destroy);
  2923.  
  2924.         bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
  2925.         destroy.ctx_id = ctx->ctx_id;
  2926.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY,
  2927.                        &destroy);
  2928.         if (ret != 0)
  2929.                 fprintf(stderr, "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY failed: %s\n",
  2930.                         strerror(errno));
  2931.  
  2932.         free(ctx);
  2933. }
  2934.  
  2935. int
  2936. drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
  2937.                    uint32_t offset,
  2938.                    uint64_t *result)
  2939. {
  2940.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
  2941.         struct drm_i915_reg_read reg_read;
  2942.         int ret;
  2943.  
  2944.         VG_CLEAR(reg_read);
  2945.         reg_read.offset = offset;
  2946.  
  2947.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
  2948.  
  2949.         *result = reg_read.val;
  2950.         return ret;
  2951. }
  2952.  
  2953.  
  2954. /**
  2955.  * Annotate the given bo for use in aub dumping.
  2956.  *
  2957.  * \param annotations is an array of drm_intel_aub_annotation objects
  2958.  * describing the type of data in various sections of the bo.  Each
  2959.  * element of the array specifies the type and subtype of a section of
  2960.  * the bo, and the past-the-end offset of that section.  The elements
  2961.  * of \c annotations must be sorted so that ending_offset is
  2962.  * increasing.
  2963.  *
  2964.  * \param count is the number of elements in the \c annotations array.
  2965.  * If \c count is zero, then \c annotations will not be dereferenced.
  2966.  *
  2967.  * Annotations are copied into a private data structure, so caller may
  2968.  * re-use the memory pointed to by \c annotations after the call
  2969.  * returns.
  2970.  *
  2971.  * Annotations are stored for the lifetime of the bo; to reset to the
  2972.  * default state (no annotations), call this function with a \c count
  2973.  * of zero.
  2974.  */
  2975. void
  2976. drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
  2977.                                          drm_intel_aub_annotation *annotations,
  2978.                                          unsigned count)
  2979. {
  2980.         drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
  2981.         unsigned size = sizeof(*annotations) * count;
  2982.         drm_intel_aub_annotation *new_annotations =
  2983.                 count > 0 ? realloc(bo_gem->aub_annotations, size) : NULL;
  2984.         if (new_annotations == NULL) {
  2985.                 free(bo_gem->aub_annotations);
  2986.                 bo_gem->aub_annotations = NULL;
  2987.                 bo_gem->aub_annotation_count = 0;
  2988.                 return;
  2989.         }
  2990.         memcpy(new_annotations, annotations, size);
  2991.         bo_gem->aub_annotations = new_annotations;
  2992.         bo_gem->aub_annotation_count = count;
  2993. }
  2994.  
  2995. /**
  2996.  * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
  2997.  * and manage map buffer objections.
  2998.  *
  2999.  * \param fd File descriptor of the opened DRM device.
  3000.  */
  3001. drm_intel_bufmgr *
  3002. drm_intel_bufmgr_gem_init(int fd, int batch_size)
  3003. {
  3004.         drm_intel_bufmgr_gem *bufmgr_gem;
  3005.         struct drm_i915_gem_get_aperture aperture;
  3006.         drm_i915_getparam_t gp;
  3007.         int ret, tmp;
  3008.         bool exec2 = false;
  3009.  
  3010.         bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
  3011.         if (bufmgr_gem == NULL)
  3012.                 return NULL;
  3013.  
  3014.         bufmgr_gem->fd = fd;
  3015.  
  3016. //      if (pthread_mutex_init(&bufmgr_gem->lock, NULL) != 0) {
  3017. //              free(bufmgr_gem);
  3018. //              return NULL;
  3019. //      }
  3020.  
  3021.         ret = drmIoctl(bufmgr_gem->fd,
  3022.                        DRM_IOCTL_I915_GEM_GET_APERTURE,
  3023.                        &aperture);
  3024.  
  3025.         if (ret == 0)
  3026.                 bufmgr_gem->gtt_size = aperture.aper_available_size;
  3027.         else {
  3028.                 printf("DRM_IOCTL_I915_GEM_APERTURE failed: %s\n",
  3029.                         strerror(errno));
  3030.                 bufmgr_gem->gtt_size = 128 * 1024 * 1024;
  3031.                 printf("Assuming %dkB available aperture size.\n"
  3032.                         "May lead to reduced performance or incorrect "
  3033.                         "rendering.\n",
  3034.                         (int)bufmgr_gem->gtt_size / 1024);
  3035.         }
  3036.  
  3037.         bufmgr_gem->pci_device = get_pci_device_id(bufmgr_gem);
  3038.  
  3039.         if (IS_GEN2(bufmgr_gem->pci_device))
  3040.                 bufmgr_gem->gen = 2;
  3041.         else if (IS_GEN3(bufmgr_gem->pci_device))
  3042.                 bufmgr_gem->gen = 3;
  3043.         else if (IS_GEN4(bufmgr_gem->pci_device))
  3044.                 bufmgr_gem->gen = 4;
  3045.         else if (IS_GEN5(bufmgr_gem->pci_device))
  3046.                 bufmgr_gem->gen = 5;
  3047.         else if (IS_GEN6(bufmgr_gem->pci_device))
  3048.                 bufmgr_gem->gen = 6;
  3049.         else if (IS_GEN7(bufmgr_gem->pci_device))
  3050.                 bufmgr_gem->gen = 7;
  3051.         else {
  3052.                 free(bufmgr_gem);
  3053.                 return NULL;
  3054.         }
  3055.  
  3056. //    printf("gen %d\n", bufmgr_gem->gen);
  3057.  
  3058.         if (IS_GEN3(bufmgr_gem->pci_device) &&
  3059.             bufmgr_gem->gtt_size > 256*1024*1024) {
  3060.                 /* The unmappable part of gtt on gen 3 (i.e. above 256MB) can't
  3061.                  * be used for tiled blits. To simplify the accounting, just
  3062.                  * substract the unmappable part (fixed to 256MB on all known
  3063.                  * gen3 devices) if the kernel advertises it. */
  3064.                 bufmgr_gem->gtt_size -= 256*1024*1024;
  3065.         }
  3066.  
  3067.         VG_CLEAR(gp);
  3068.         gp.value = &tmp;
  3069.  
  3070.         gp.param = I915_PARAM_HAS_EXECBUF2;
  3071.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3072.         if (!ret)
  3073.                 exec2 = true;
  3074.  
  3075.         gp.param = I915_PARAM_HAS_BSD;
  3076.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3077.         bufmgr_gem->has_bsd = ret == 0;
  3078.  
  3079.         gp.param = I915_PARAM_HAS_BLT;
  3080.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3081.         bufmgr_gem->has_blt = ret == 0;
  3082.  
  3083.         gp.param = I915_PARAM_HAS_RELAXED_FENCING;
  3084.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3085.         bufmgr_gem->has_relaxed_fencing = ret == 0;
  3086.  
  3087.         gp.param = I915_PARAM_HAS_WAIT_TIMEOUT;
  3088.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3089.         bufmgr_gem->has_wait_timeout = ret == 0;
  3090.  
  3091.         gp.param = I915_PARAM_HAS_LLC;
  3092.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3093.         if (ret != 0) {
  3094.                 /* Kernel does not supports HAS_LLC query, fallback to GPU
  3095.                  * generation detection and assume that we have LLC on GEN6/7
  3096.                  */
  3097.                 bufmgr_gem->has_llc = (IS_GEN6(bufmgr_gem->pci_device) |
  3098.                                 IS_GEN7(bufmgr_gem->pci_device));
  3099.         } else
  3100.                 bufmgr_gem->has_llc = *gp.value;
  3101.  
  3102.         gp.param = I915_PARAM_HAS_VEBOX;
  3103.         ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3104.         bufmgr_gem->has_vebox = (ret == 0) & (*gp.value > 0);
  3105.  
  3106.         if (bufmgr_gem->gen < 4) {
  3107.                 gp.param = I915_PARAM_NUM_FENCES_AVAIL;
  3108.                 gp.value = &bufmgr_gem->available_fences;
  3109.                 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
  3110.                 if (ret) {
  3111.                         fprintf(stderr, "get fences failed: %d [%d]\n", ret,
  3112.                                 errno);
  3113.                         fprintf(stderr, "param: %d, val: %d\n", gp.param,
  3114.                                 *gp.value);
  3115.                         bufmgr_gem->available_fences = 0;
  3116.                 } else {
  3117.                         /* XXX The kernel reports the total number of fences,
  3118.                          * including any that may be pinned.
  3119.                          *
  3120.                          * We presume that there will be at least one pinned
  3121.                          * fence for the scanout buffer, but there may be more
  3122.                          * than one scanout and the user may be manually
  3123.                          * pinning buffers. Let's move to execbuffer2 and
  3124.                          * thereby forget the insanity of using fences...
  3125.                          */
  3126.                         bufmgr_gem->available_fences -= 2;
  3127.                         if (bufmgr_gem->available_fences < 0)
  3128.                                 bufmgr_gem->available_fences = 0;
  3129.                 }
  3130.         }
  3131.  
  3132.         /* Let's go with one relocation per every 2 dwords (but round down a bit
  3133.          * since a power of two will mean an extra page allocation for the reloc
  3134.          * buffer).
  3135.          *
  3136.          * Every 4 was too few for the blender benchmark.
  3137.          */
  3138.         bufmgr_gem->max_relocs = batch_size / sizeof(uint32_t) / 2 - 2;
  3139.  
  3140.         bufmgr_gem->bufmgr.bo_alloc = drm_intel_gem_bo_alloc;
  3141. //      bufmgr_gem->bufmgr.bo_alloc_for_render =
  3142. //          drm_intel_gem_bo_alloc_for_render;
  3143.         bufmgr_gem->bufmgr.bo_alloc_tiled = drm_intel_gem_bo_alloc_tiled;
  3144.         bufmgr_gem->bufmgr.bo_reference = drm_intel_gem_bo_reference;
  3145.         bufmgr_gem->bufmgr.bo_unreference = drm_intel_gem_bo_unreference;
  3146.         bufmgr_gem->bufmgr.bo_map = drm_intel_gem_bo_map;
  3147.         bufmgr_gem->bufmgr.bo_unmap = drm_intel_gem_bo_unmap;
  3148.         bufmgr_gem->bufmgr.bo_subdata = drm_intel_gem_bo_subdata;
  3149. //      bufmgr_gem->bufmgr.bo_get_subdata = drm_intel_gem_bo_get_subdata;
  3150.         bufmgr_gem->bufmgr.bo_wait_rendering = drm_intel_gem_bo_wait_rendering;
  3151.         bufmgr_gem->bufmgr.bo_emit_reloc = drm_intel_gem_bo_emit_reloc;
  3152.         bufmgr_gem->bufmgr.bo_emit_reloc_fence = drm_intel_gem_bo_emit_reloc_fence;
  3153.         bufmgr_gem->bufmgr.bo_pin = drm_intel_gem_bo_pin;
  3154.         bufmgr_gem->bufmgr.bo_unpin = drm_intel_gem_bo_unpin;
  3155.         bufmgr_gem->bufmgr.bo_get_tiling = drm_intel_gem_bo_get_tiling;
  3156.         bufmgr_gem->bufmgr.bo_set_tiling = drm_intel_gem_bo_set_tiling;
  3157.         bufmgr_gem->bufmgr.bo_flink = drm_intel_gem_bo_flink;
  3158.         /* Use the new one if available */
  3159. //      if (exec2) {
  3160.                 bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec2;
  3161.                 bufmgr_gem->bufmgr.bo_mrb_exec = drm_intel_gem_bo_mrb_exec2;
  3162. //      } else
  3163. //              bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec;
  3164.         bufmgr_gem->bufmgr.bo_busy = drm_intel_gem_bo_busy;
  3165.         bufmgr_gem->bufmgr.bo_madvise = drm_intel_gem_bo_madvise;
  3166.         bufmgr_gem->bufmgr.destroy = drm_intel_bufmgr_gem_destroy;
  3167.         bufmgr_gem->bufmgr.debug = 0;
  3168.         bufmgr_gem->bufmgr.check_aperture_space =
  3169.             drm_intel_gem_check_aperture_space;
  3170.         bufmgr_gem->bufmgr.bo_disable_reuse = drm_intel_gem_bo_disable_reuse;
  3171.         bufmgr_gem->bufmgr.bo_is_reusable = drm_intel_gem_bo_is_reusable;
  3172. //      bufmgr_gem->bufmgr.get_pipe_from_crtc_id =
  3173. //          drm_intel_gem_get_pipe_from_crtc_id;
  3174.         bufmgr_gem->bufmgr.bo_references = drm_intel_gem_bo_references;
  3175.  
  3176.         DRMINITLISTHEAD(&bufmgr_gem->named);
  3177.         init_cache_buckets(bufmgr_gem);
  3178.  
  3179.         DRMINITLISTHEAD(&bufmgr_gem->vma_cache);
  3180.         bufmgr_gem->vma_max = -1; /* unlimited by default */
  3181.  
  3182.         return &bufmgr_gem->bufmgr;
  3183. }
  3184.  
  3185.  
  3186. drm_intel_bo *
  3187. bo_create_from_gem_handle(drm_intel_bufmgr *bufmgr,
  3188.                           unsigned int size, unsigned int handle)
  3189. {
  3190.         drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
  3191.         drm_intel_bo_gem *bo_gem;
  3192.         int ret;
  3193.         struct drm_i915_gem_get_tiling get_tiling;
  3194.         drmMMListHead *list;
  3195.  
  3196.         /* At the moment most applications only have a few named bo.
  3197.          * For instance, in a DRI client only the render buffers passed
  3198.          * between X and the client are named. And since X returns the
  3199.          * alternating names for the front/back buffer a linear search
  3200.          * provides a sufficiently fast match.
  3201.          */
  3202.         for (list = bufmgr_gem->named.next;
  3203.              list != &bufmgr_gem->named;
  3204.              list = list->next) {
  3205.                 bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
  3206.                 if (bo_gem->gem_handle == handle) {
  3207.                         return &bo_gem->bo;
  3208.                 }
  3209.         }
  3210.  
  3211.         bo_gem = calloc(1, sizeof(*bo_gem));
  3212.         if (!bo_gem)
  3213.                 return NULL;
  3214.  
  3215.         bo_gem->bo.size = size;
  3216.         bo_gem->bo.offset = 0;
  3217.         bo_gem->bo.virtual = NULL;
  3218.         bo_gem->bo.bufmgr = bufmgr;
  3219.         bo_gem->name = NULL;
  3220.         atomic_set(&bo_gem->refcount, 1);
  3221.         bo_gem->validate_index = -1;
  3222.         bo_gem->gem_handle = handle;
  3223.         bo_gem->bo.handle = handle;
  3224.         bo_gem->global_name = 0;
  3225.         bo_gem->reusable = false;
  3226.  
  3227.         VG_CLEAR(get_tiling);
  3228.         get_tiling.handle = bo_gem->gem_handle;
  3229.         ret = drmIoctl(bufmgr_gem->fd,
  3230.                        DRM_IOCTL_I915_GEM_GET_TILING,
  3231.                        &get_tiling);
  3232.         if (ret != 0) {
  3233.                 drm_intel_gem_bo_unreference(&bo_gem->bo);
  3234.                 return NULL;
  3235.         }
  3236.         bo_gem->tiling_mode = get_tiling.tiling_mode;
  3237.         bo_gem->swizzle_mode = get_tiling.swizzle_mode;
  3238.         /* XXX stride is unknown */
  3239.         drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
  3240.  
  3241.         DRMINITLISTHEAD(&bo_gem->vma_list);
  3242.         DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
  3243.         printf("bo_create_from_handle: %d\n", handle);
  3244.  
  3245.         return &bo_gem->bo;
  3246. }
  3247.