intel_bufmgr_fake.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /**************************************************************************
  2. *
  3. * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. /* Originally a fake version of the buffer manager so that we can
  28. * prototype the changes in a driver fairly quickly, has been fleshed
  29. * out to a fully functional interim solution.
  30. *
  31. * Basically wraps the old style memory management in the new
  32. * programming interface, but is more expressive and avoids many of
  33. * the bugs in the old texture manager.
  34. */
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <assert.h>
  38. #include <errno.h>
  39. #include <strings.h>
  40. #include <xf86drm.h>
  41. #include <pthread.h>
  42. #include "intel_bufmgr.h"
  43. #include "intel_bufmgr_priv.h"
  44. #include "drm.h"
  45. #include "i915_drm.h"
  46. #include "mm.h"
  47. #include "libdrm_macros.h"
  48. #include "libdrm_lists.h"
  49. #define DBG(...) do { \
  50. if (bufmgr_fake->bufmgr.debug) \
  51. drmMsg(__VA_ARGS__); \
  52. } while (0)
  53. /* Internal flags:
  54. */
  55. #define BM_NO_BACKING_STORE 0x00000001
  56. #define BM_NO_FENCE_SUBDATA 0x00000002
  57. #define BM_PINNED 0x00000004
  58. /* Wrapper around mm.c's mem_block, which understands that you must
  59. * wait for fences to expire before memory can be freed. This is
  60. * specific to our use of memcpy for uploads - an upload that was
  61. * processed through the command queue wouldn't need to care about
  62. * fences.
  63. */
  64. #define MAX_RELOCS 4096
  65. struct fake_buffer_reloc {
  66. /** Buffer object that the relocation points at. */
  67. drm_intel_bo *target_buf;
  68. /** Offset of the relocation entry within reloc_buf. */
  69. uint32_t offset;
  70. /**
  71. * Cached value of the offset when we last performed this relocation.
  72. */
  73. uint32_t last_target_offset;
  74. /** Value added to target_buf's offset to get the relocation entry. */
  75. uint32_t delta;
  76. /** Cache domains the target buffer is read into. */
  77. uint32_t read_domains;
  78. /** Cache domain the target buffer will have dirty cachelines in. */
  79. uint32_t write_domain;
  80. };
  81. struct block {
  82. struct block *next, *prev;
  83. struct mem_block *mem; /* BM_MEM_AGP */
  84. /**
  85. * Marks that the block is currently in the aperture and has yet to be
  86. * fenced.
  87. */
  88. unsigned on_hardware:1;
  89. /**
  90. * Marks that the block is currently fenced (being used by rendering)
  91. * and can't be freed until @fence is passed.
  92. */
  93. unsigned fenced:1;
  94. /** Fence cookie for the block. */
  95. unsigned fence; /* Split to read_fence, write_fence */
  96. drm_intel_bo *bo;
  97. void *virtual;
  98. };
  99. typedef struct _bufmgr_fake {
  100. drm_intel_bufmgr bufmgr;
  101. pthread_mutex_t lock;
  102. unsigned long low_offset;
  103. unsigned long size;
  104. void *virtual;
  105. struct mem_block *heap;
  106. unsigned buf_nr; /* for generating ids */
  107. /**
  108. * List of blocks which are currently in the GART but haven't been
  109. * fenced yet.
  110. */
  111. struct block on_hardware;
  112. /**
  113. * List of blocks which are in the GART and have an active fence on
  114. * them.
  115. */
  116. struct block fenced;
  117. /**
  118. * List of blocks which have an expired fence and are ready to be
  119. * evicted.
  120. */
  121. struct block lru;
  122. unsigned int last_fence;
  123. unsigned fail:1;
  124. unsigned need_fence:1;
  125. int thrashing;
  126. /**
  127. * Driver callback to emit a fence, returning the cookie.
  128. *
  129. * This allows the driver to hook in a replacement for the DRM usage in
  130. * bufmgr_fake.
  131. *
  132. * Currently, this also requires that a write flush be emitted before
  133. * emitting the fence, but this should change.
  134. */
  135. unsigned int (*fence_emit) (void *private);
  136. /** Driver callback to wait for a fence cookie to have passed. */
  137. void (*fence_wait) (unsigned int fence, void *private);
  138. void *fence_priv;
  139. /**
  140. * Driver callback to execute a buffer.
  141. *
  142. * This allows the driver to hook in a replacement for the DRM usage in
  143. * bufmgr_fake.
  144. */
  145. int (*exec) (drm_intel_bo *bo, unsigned int used, void *priv);
  146. void *exec_priv;
  147. /** Driver-supplied argument to driver callbacks */
  148. void *driver_priv;
  149. /**
  150. * Pointer to kernel-updated sarea data for the last completed user irq
  151. */
  152. volatile int *last_dispatch;
  153. int fd;
  154. int debug;
  155. int performed_rendering;
  156. } drm_intel_bufmgr_fake;
  157. typedef struct _drm_intel_bo_fake {
  158. drm_intel_bo bo;
  159. unsigned id; /* debug only */
  160. const char *name;
  161. unsigned dirty:1;
  162. /**
  163. * has the card written to this buffer - we make need to copy it back
  164. */
  165. unsigned card_dirty:1;
  166. unsigned int refcount;
  167. /* Flags may consist of any of the DRM_BO flags, plus
  168. * DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the
  169. * first two driver private flags.
  170. */
  171. uint64_t flags;
  172. /** Cache domains the target buffer is read into. */
  173. uint32_t read_domains;
  174. /** Cache domain the target buffer will have dirty cachelines in. */
  175. uint32_t write_domain;
  176. unsigned int alignment;
  177. int is_static, validated;
  178. unsigned int map_count;
  179. /** relocation list */
  180. struct fake_buffer_reloc *relocs;
  181. int nr_relocs;
  182. /**
  183. * Total size of the target_bos of this buffer.
  184. *
  185. * Used for estimation in check_aperture.
  186. */
  187. unsigned int child_size;
  188. struct block *block;
  189. void *backing_store;
  190. void (*invalidate_cb) (drm_intel_bo *bo, void *ptr);
  191. void *invalidate_ptr;
  192. } drm_intel_bo_fake;
  193. static int clear_fenced(drm_intel_bufmgr_fake *bufmgr_fake,
  194. unsigned int fence_cookie);
  195. #define MAXFENCE 0x7fffffff
  196. static int
  197. FENCE_LTE(unsigned a, unsigned b)
  198. {
  199. if (a == b)
  200. return 1;
  201. if (a < b && b - a < (1 << 24))
  202. return 1;
  203. if (a > b && MAXFENCE - a + b < (1 << 24))
  204. return 1;
  205. return 0;
  206. }
  207. drm_public void
  208. drm_intel_bufmgr_fake_set_fence_callback(drm_intel_bufmgr *bufmgr,
  209. unsigned int (*emit) (void *priv),
  210. void (*wait) (unsigned int fence,
  211. void *priv),
  212. void *priv)
  213. {
  214. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  215. bufmgr_fake->fence_emit = emit;
  216. bufmgr_fake->fence_wait = wait;
  217. bufmgr_fake->fence_priv = priv;
  218. }
  219. static unsigned int
  220. _fence_emit_internal(drm_intel_bufmgr_fake *bufmgr_fake)
  221. {
  222. struct drm_i915_irq_emit ie;
  223. int ret, seq = 1;
  224. if (bufmgr_fake->fence_emit != NULL) {
  225. seq = bufmgr_fake->fence_emit(bufmgr_fake->fence_priv);
  226. return seq;
  227. }
  228. ie.irq_seq = &seq;
  229. ret = drmCommandWriteRead(bufmgr_fake->fd, DRM_I915_IRQ_EMIT,
  230. &ie, sizeof(ie));
  231. if (ret) {
  232. drmMsg("%s: drm_i915_irq_emit: %d\n", __func__, ret);
  233. abort();
  234. }
  235. DBG("emit 0x%08x\n", seq);
  236. return seq;
  237. }
  238. static void
  239. _fence_wait_internal(drm_intel_bufmgr_fake *bufmgr_fake, int seq)
  240. {
  241. struct drm_i915_irq_wait iw;
  242. int hw_seq, busy_count = 0;
  243. int ret;
  244. int kernel_lied;
  245. if (bufmgr_fake->fence_wait != NULL) {
  246. bufmgr_fake->fence_wait(seq, bufmgr_fake->fence_priv);
  247. clear_fenced(bufmgr_fake, seq);
  248. return;
  249. }
  250. iw.irq_seq = seq;
  251. DBG("wait 0x%08x\n", iw.irq_seq);
  252. /* The kernel IRQ_WAIT implementation is all sorts of broken.
  253. * 1) It returns 1 to 0x7fffffff instead of using the full 32-bit
  254. * unsigned range.
  255. * 2) It returns 0 if hw_seq >= seq, not seq - hw_seq < 0 on the 32-bit
  256. * signed range.
  257. * 3) It waits if seq < hw_seq, not seq - hw_seq > 0 on the 32-bit
  258. * signed range.
  259. * 4) It returns -EBUSY in 3 seconds even if the hardware is still
  260. * successfully chewing through buffers.
  261. *
  262. * Assume that in userland we treat sequence numbers as ints, which
  263. * makes some of the comparisons convenient, since the sequence
  264. * numbers are all positive signed integers.
  265. *
  266. * From this we get several cases we need to handle. Here's a timeline.
  267. * 0x2 0x7 0x7ffffff8 0x7ffffffd
  268. * | | | |
  269. * ------------------------------------------------------------
  270. *
  271. * A) Normal wait for hw to catch up
  272. * hw_seq seq
  273. * | |
  274. * ------------------------------------------------------------
  275. * seq - hw_seq = 5. If we call IRQ_WAIT, it will wait for hw to
  276. * catch up.
  277. *
  278. * B) Normal wait for a sequence number that's already passed.
  279. * seq hw_seq
  280. * | |
  281. * ------------------------------------------------------------
  282. * seq - hw_seq = -5. If we call IRQ_WAIT, it returns 0 quickly.
  283. *
  284. * C) Hardware has already wrapped around ahead of us
  285. * hw_seq seq
  286. * | |
  287. * ------------------------------------------------------------
  288. * seq - hw_seq = 0x80000000 - 5. If we called IRQ_WAIT, it would wait
  289. * for hw_seq >= seq, which may never occur. Thus, we want to catch
  290. * this in userland and return 0.
  291. *
  292. * D) We've wrapped around ahead of the hardware.
  293. * seq hw_seq
  294. * | |
  295. * ------------------------------------------------------------
  296. * seq - hw_seq = -(0x80000000 - 5). If we called IRQ_WAIT, it would
  297. * return 0 quickly because hw_seq >= seq, even though the hardware
  298. * isn't caught up. Thus, we need to catch this early return in
  299. * userland and bother the kernel until the hardware really does
  300. * catch up.
  301. *
  302. * E) Hardware might wrap after we test in userland.
  303. * hw_seq seq
  304. * | |
  305. * ------------------------------------------------------------
  306. * seq - hw_seq = 5. If we call IRQ_WAIT, it will likely see seq >=
  307. * hw_seq and wait. However, suppose hw_seq wraps before we make it
  308. * into the kernel. The kernel sees hw_seq >= seq and waits for 3
  309. * seconds then returns -EBUSY. This is case C). We should catch
  310. * this and then return successfully.
  311. *
  312. * F) Hardware might take a long time on a buffer.
  313. * hw_seq seq
  314. * | |
  315. * -------------------------------------------------------------------
  316. * seq - hw_seq = 5. If we call IRQ_WAIT, if sequence 2 through 5
  317. * take too long, it will return -EBUSY. Batchbuffers in the
  318. * gltestperf demo were seen to take up to 7 seconds. We should
  319. * catch early -EBUSY return and keep trying.
  320. */
  321. do {
  322. /* Keep a copy of last_dispatch so that if the wait -EBUSYs
  323. * because the hardware didn't catch up in 3 seconds, we can
  324. * see if it at least made progress and retry.
  325. */
  326. hw_seq = *bufmgr_fake->last_dispatch;
  327. /* Catch case C */
  328. if (seq - hw_seq > 0x40000000)
  329. return;
  330. ret = drmCommandWrite(bufmgr_fake->fd, DRM_I915_IRQ_WAIT,
  331. &iw, sizeof(iw));
  332. /* Catch case D */
  333. kernel_lied = (ret == 0) && (seq - *bufmgr_fake->last_dispatch <
  334. -0x40000000);
  335. /* Catch case E */
  336. if (ret == -EBUSY
  337. && (seq - *bufmgr_fake->last_dispatch > 0x40000000))
  338. ret = 0;
  339. /* Catch case F: Allow up to 15 seconds chewing on one buffer. */
  340. if ((ret == -EBUSY) && (hw_seq != *bufmgr_fake->last_dispatch))
  341. busy_count = 0;
  342. else
  343. busy_count++;
  344. } while (kernel_lied || ret == -EAGAIN || ret == -EINTR ||
  345. (ret == -EBUSY && busy_count < 5));
  346. if (ret != 0) {
  347. drmMsg("%s:%d: Error waiting for fence: %s.\n", __FILE__,
  348. __LINE__, strerror(-ret));
  349. abort();
  350. }
  351. clear_fenced(bufmgr_fake, seq);
  352. }
  353. static int
  354. _fence_test(drm_intel_bufmgr_fake *bufmgr_fake, unsigned fence)
  355. {
  356. /* Slight problem with wrap-around:
  357. */
  358. return fence == 0 || FENCE_LTE(fence, bufmgr_fake->last_fence);
  359. }
  360. /**
  361. * Allocate a memory manager block for the buffer.
  362. */
  363. static int
  364. alloc_block(drm_intel_bo *bo)
  365. {
  366. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  367. drm_intel_bufmgr_fake *bufmgr_fake =
  368. (drm_intel_bufmgr_fake *) bo->bufmgr;
  369. struct block *block = (struct block *)calloc(sizeof *block, 1);
  370. unsigned int align_log2 = ffs(bo_fake->alignment) - 1;
  371. unsigned int sz;
  372. if (!block)
  373. return 1;
  374. sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1);
  375. block->mem = mmAllocMem(bufmgr_fake->heap, sz, align_log2, 0);
  376. if (!block->mem) {
  377. free(block);
  378. return 0;
  379. }
  380. DRMINITLISTHEAD(block);
  381. /* Insert at head or at tail??? */
  382. DRMLISTADDTAIL(block, &bufmgr_fake->lru);
  383. block->virtual = (uint8_t *) bufmgr_fake->virtual +
  384. block->mem->ofs - bufmgr_fake->low_offset;
  385. block->bo = bo;
  386. bo_fake->block = block;
  387. return 1;
  388. }
  389. /* Release the card storage associated with buf:
  390. */
  391. static void
  392. free_block(drm_intel_bufmgr_fake *bufmgr_fake, struct block *block,
  393. int skip_dirty_copy)
  394. {
  395. drm_intel_bo_fake *bo_fake;
  396. DBG("free block %p %08x %d %d\n", block, block->mem->ofs,
  397. block->on_hardware, block->fenced);
  398. if (!block)
  399. return;
  400. bo_fake = (drm_intel_bo_fake *) block->bo;
  401. if (bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE))
  402. skip_dirty_copy = 1;
  403. if (!skip_dirty_copy && (bo_fake->card_dirty == 1)) {
  404. memcpy(bo_fake->backing_store, block->virtual, block->bo->size);
  405. bo_fake->card_dirty = 0;
  406. bo_fake->dirty = 1;
  407. }
  408. if (block->on_hardware) {
  409. block->bo = NULL;
  410. } else if (block->fenced) {
  411. block->bo = NULL;
  412. } else {
  413. DBG(" - free immediately\n");
  414. DRMLISTDEL(block);
  415. mmFreeMem(block->mem);
  416. free(block);
  417. }
  418. }
  419. static void
  420. alloc_backing_store(drm_intel_bo *bo)
  421. {
  422. drm_intel_bufmgr_fake *bufmgr_fake =
  423. (drm_intel_bufmgr_fake *) bo->bufmgr;
  424. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  425. assert(!bo_fake->backing_store);
  426. assert(!(bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE)));
  427. bo_fake->backing_store = malloc(bo->size);
  428. DBG("alloc_backing - buf %d %p %lu\n", bo_fake->id,
  429. bo_fake->backing_store, bo->size);
  430. assert(bo_fake->backing_store);
  431. }
  432. static void
  433. free_backing_store(drm_intel_bo *bo)
  434. {
  435. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  436. if (bo_fake->backing_store) {
  437. assert(!(bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE)));
  438. free(bo_fake->backing_store);
  439. bo_fake->backing_store = NULL;
  440. }
  441. }
  442. static void
  443. set_dirty(drm_intel_bo *bo)
  444. {
  445. drm_intel_bufmgr_fake *bufmgr_fake =
  446. (drm_intel_bufmgr_fake *) bo->bufmgr;
  447. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  448. if (bo_fake->flags & BM_NO_BACKING_STORE
  449. && bo_fake->invalidate_cb != NULL)
  450. bo_fake->invalidate_cb(bo, bo_fake->invalidate_ptr);
  451. assert(!(bo_fake->flags & BM_PINNED));
  452. DBG("set_dirty - buf %d\n", bo_fake->id);
  453. bo_fake->dirty = 1;
  454. }
  455. static int
  456. evict_lru(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int max_fence)
  457. {
  458. struct block *block, *tmp;
  459. DBG("%s\n", __func__);
  460. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
  461. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
  462. if (bo_fake != NULL && (bo_fake->flags & BM_NO_FENCE_SUBDATA))
  463. continue;
  464. if (block->fence && max_fence && !FENCE_LTE(block->fence,
  465. max_fence))
  466. return 0;
  467. set_dirty(&bo_fake->bo);
  468. bo_fake->block = NULL;
  469. free_block(bufmgr_fake, block, 0);
  470. return 1;
  471. }
  472. return 0;
  473. }
  474. static int
  475. evict_mru(drm_intel_bufmgr_fake *bufmgr_fake)
  476. {
  477. struct block *block, *tmp;
  478. DBG("%s\n", __func__);
  479. DRMLISTFOREACHSAFEREVERSE(block, tmp, &bufmgr_fake->lru) {
  480. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
  481. if (bo_fake && (bo_fake->flags & BM_NO_FENCE_SUBDATA))
  482. continue;
  483. set_dirty(&bo_fake->bo);
  484. bo_fake->block = NULL;
  485. free_block(bufmgr_fake, block, 0);
  486. return 1;
  487. }
  488. return 0;
  489. }
  490. /**
  491. * Removes all objects from the fenced list older than the given fence.
  492. */
  493. static int
  494. clear_fenced(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int fence_cookie)
  495. {
  496. struct block *block, *tmp;
  497. int ret = 0;
  498. bufmgr_fake->last_fence = fence_cookie;
  499. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->fenced) {
  500. assert(block->fenced);
  501. if (_fence_test(bufmgr_fake, block->fence)) {
  502. block->fenced = 0;
  503. if (!block->bo) {
  504. DBG("delayed free: offset %x sz %x\n",
  505. block->mem->ofs, block->mem->size);
  506. DRMLISTDEL(block);
  507. mmFreeMem(block->mem);
  508. free(block);
  509. } else {
  510. DBG("return to lru: offset %x sz %x\n",
  511. block->mem->ofs, block->mem->size);
  512. DRMLISTDEL(block);
  513. DRMLISTADDTAIL(block, &bufmgr_fake->lru);
  514. }
  515. ret = 1;
  516. } else {
  517. /* Blocks are ordered by fence, so if one fails, all
  518. * from here will fail also:
  519. */
  520. DBG("fence not passed: offset %x sz %x %d %d \n",
  521. block->mem->ofs, block->mem->size, block->fence,
  522. bufmgr_fake->last_fence);
  523. break;
  524. }
  525. }
  526. DBG("%s: %d\n", __func__, ret);
  527. return ret;
  528. }
  529. static void
  530. fence_blocks(drm_intel_bufmgr_fake *bufmgr_fake, unsigned fence)
  531. {
  532. struct block *block, *tmp;
  533. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->on_hardware) {
  534. DBG("Fence block %p (sz 0x%x ofs %x buf %p) with fence %d\n",
  535. block, block->mem->size, block->mem->ofs, block->bo, fence);
  536. block->fence = fence;
  537. block->on_hardware = 0;
  538. block->fenced = 1;
  539. /* Move to tail of pending list here
  540. */
  541. DRMLISTDEL(block);
  542. DRMLISTADDTAIL(block, &bufmgr_fake->fenced);
  543. }
  544. assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
  545. }
  546. static int
  547. evict_and_alloc_block(drm_intel_bo *bo)
  548. {
  549. drm_intel_bufmgr_fake *bufmgr_fake =
  550. (drm_intel_bufmgr_fake *) bo->bufmgr;
  551. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  552. assert(bo_fake->block == NULL);
  553. /* Search for already free memory:
  554. */
  555. if (alloc_block(bo))
  556. return 1;
  557. /* If we're not thrashing, allow lru eviction to dig deeper into
  558. * recently used textures. We'll probably be thrashing soon:
  559. */
  560. if (!bufmgr_fake->thrashing) {
  561. while (evict_lru(bufmgr_fake, 0))
  562. if (alloc_block(bo))
  563. return 1;
  564. }
  565. /* Keep thrashing counter alive?
  566. */
  567. if (bufmgr_fake->thrashing)
  568. bufmgr_fake->thrashing = 20;
  569. /* Wait on any already pending fences - here we are waiting for any
  570. * freed memory that has been submitted to hardware and fenced to
  571. * become available:
  572. */
  573. while (!DRMLISTEMPTY(&bufmgr_fake->fenced)) {
  574. uint32_t fence = bufmgr_fake->fenced.next->fence;
  575. _fence_wait_internal(bufmgr_fake, fence);
  576. if (alloc_block(bo))
  577. return 1;
  578. }
  579. if (!DRMLISTEMPTY(&bufmgr_fake->on_hardware)) {
  580. while (!DRMLISTEMPTY(&bufmgr_fake->fenced)) {
  581. uint32_t fence = bufmgr_fake->fenced.next->fence;
  582. _fence_wait_internal(bufmgr_fake, fence);
  583. }
  584. if (!bufmgr_fake->thrashing) {
  585. DBG("thrashing\n");
  586. }
  587. bufmgr_fake->thrashing = 20;
  588. if (alloc_block(bo))
  589. return 1;
  590. }
  591. while (evict_mru(bufmgr_fake))
  592. if (alloc_block(bo))
  593. return 1;
  594. DBG("%s 0x%lx bytes failed\n", __func__, bo->size);
  595. return 0;
  596. }
  597. /***********************************************************************
  598. * Public functions
  599. */
  600. /**
  601. * Wait for hardware idle by emitting a fence and waiting for it.
  602. */
  603. static void
  604. drm_intel_bufmgr_fake_wait_idle(drm_intel_bufmgr_fake *bufmgr_fake)
  605. {
  606. unsigned int cookie;
  607. cookie = _fence_emit_internal(bufmgr_fake);
  608. _fence_wait_internal(bufmgr_fake, cookie);
  609. }
  610. /**
  611. * Wait for rendering to a buffer to complete.
  612. *
  613. * It is assumed that the batchbuffer which performed the rendering included
  614. * the necessary flushing.
  615. */
  616. static void
  617. drm_intel_fake_bo_wait_rendering_locked(drm_intel_bo *bo)
  618. {
  619. drm_intel_bufmgr_fake *bufmgr_fake =
  620. (drm_intel_bufmgr_fake *) bo->bufmgr;
  621. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  622. if (bo_fake->block == NULL || !bo_fake->block->fenced)
  623. return;
  624. _fence_wait_internal(bufmgr_fake, bo_fake->block->fence);
  625. }
  626. static void
  627. drm_intel_fake_bo_wait_rendering(drm_intel_bo *bo)
  628. {
  629. drm_intel_bufmgr_fake *bufmgr_fake =
  630. (drm_intel_bufmgr_fake *) bo->bufmgr;
  631. pthread_mutex_lock(&bufmgr_fake->lock);
  632. drm_intel_fake_bo_wait_rendering_locked(bo);
  633. pthread_mutex_unlock(&bufmgr_fake->lock);
  634. }
  635. /* Specifically ignore texture memory sharing.
  636. * -- just evict everything
  637. * -- and wait for idle
  638. */
  639. drm_public void
  640. drm_intel_bufmgr_fake_contended_lock_take(drm_intel_bufmgr *bufmgr)
  641. {
  642. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  643. struct block *block, *tmp;
  644. pthread_mutex_lock(&bufmgr_fake->lock);
  645. bufmgr_fake->need_fence = 1;
  646. bufmgr_fake->fail = 0;
  647. /* Wait for hardware idle. We don't know where acceleration has been
  648. * happening, so we'll need to wait anyway before letting anything get
  649. * put on the card again.
  650. */
  651. drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
  652. /* Check that we hadn't released the lock without having fenced the last
  653. * set of buffers.
  654. */
  655. assert(DRMLISTEMPTY(&bufmgr_fake->fenced));
  656. assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
  657. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
  658. assert(_fence_test(bufmgr_fake, block->fence));
  659. set_dirty(block->bo);
  660. }
  661. pthread_mutex_unlock(&bufmgr_fake->lock);
  662. }
  663. static drm_intel_bo *
  664. drm_intel_fake_bo_alloc(drm_intel_bufmgr *bufmgr,
  665. const char *name,
  666. unsigned long size,
  667. unsigned int alignment)
  668. {
  669. drm_intel_bufmgr_fake *bufmgr_fake;
  670. drm_intel_bo_fake *bo_fake;
  671. bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  672. assert(size != 0);
  673. bo_fake = calloc(1, sizeof(*bo_fake));
  674. if (!bo_fake)
  675. return NULL;
  676. bo_fake->bo.size = size;
  677. bo_fake->bo.offset = -1;
  678. bo_fake->bo.virtual = NULL;
  679. bo_fake->bo.bufmgr = bufmgr;
  680. bo_fake->refcount = 1;
  681. /* Alignment must be a power of two */
  682. assert((alignment & (alignment - 1)) == 0);
  683. if (alignment == 0)
  684. alignment = 1;
  685. bo_fake->alignment = alignment;
  686. bo_fake->id = ++bufmgr_fake->buf_nr;
  687. bo_fake->name = name;
  688. bo_fake->flags = 0;
  689. bo_fake->is_static = 0;
  690. DBG("drm_bo_alloc: (buf %d: %s, %lu kb)\n", bo_fake->id, bo_fake->name,
  691. bo_fake->bo.size / 1024);
  692. return &bo_fake->bo;
  693. }
  694. static drm_intel_bo *
  695. drm_intel_fake_bo_alloc_tiled(drm_intel_bufmgr * bufmgr,
  696. const char *name,
  697. int x, int y, int cpp,
  698. uint32_t *tiling_mode,
  699. unsigned long *pitch,
  700. unsigned long flags)
  701. {
  702. unsigned long stride, aligned_y;
  703. /* No runtime tiling support for fake. */
  704. *tiling_mode = I915_TILING_NONE;
  705. /* Align it for being a render target. Shouldn't need anything else. */
  706. stride = x * cpp;
  707. stride = ROUND_UP_TO(stride, 64);
  708. /* 965 subspan loading alignment */
  709. aligned_y = ALIGN(y, 2);
  710. *pitch = stride;
  711. return drm_intel_fake_bo_alloc(bufmgr, name, stride * aligned_y,
  712. 4096);
  713. }
  714. drm_public drm_intel_bo *
  715. drm_intel_bo_fake_alloc_static(drm_intel_bufmgr *bufmgr,
  716. const char *name,
  717. unsigned long offset,
  718. unsigned long size, void *virtual)
  719. {
  720. drm_intel_bufmgr_fake *bufmgr_fake;
  721. drm_intel_bo_fake *bo_fake;
  722. bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  723. assert(size != 0);
  724. bo_fake = calloc(1, sizeof(*bo_fake));
  725. if (!bo_fake)
  726. return NULL;
  727. bo_fake->bo.size = size;
  728. bo_fake->bo.offset = offset;
  729. bo_fake->bo.virtual = virtual;
  730. bo_fake->bo.bufmgr = bufmgr;
  731. bo_fake->refcount = 1;
  732. bo_fake->id = ++bufmgr_fake->buf_nr;
  733. bo_fake->name = name;
  734. bo_fake->flags = BM_PINNED;
  735. bo_fake->is_static = 1;
  736. DBG("drm_bo_alloc_static: (buf %d: %s, %lu kb)\n", bo_fake->id,
  737. bo_fake->name, bo_fake->bo.size / 1024);
  738. return &bo_fake->bo;
  739. }
  740. static void
  741. drm_intel_fake_bo_reference(drm_intel_bo *bo)
  742. {
  743. drm_intel_bufmgr_fake *bufmgr_fake =
  744. (drm_intel_bufmgr_fake *) bo->bufmgr;
  745. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  746. pthread_mutex_lock(&bufmgr_fake->lock);
  747. bo_fake->refcount++;
  748. pthread_mutex_unlock(&bufmgr_fake->lock);
  749. }
  750. static void
  751. drm_intel_fake_bo_reference_locked(drm_intel_bo *bo)
  752. {
  753. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  754. bo_fake->refcount++;
  755. }
  756. static void
  757. drm_intel_fake_bo_unreference_locked(drm_intel_bo *bo)
  758. {
  759. drm_intel_bufmgr_fake *bufmgr_fake =
  760. (drm_intel_bufmgr_fake *) bo->bufmgr;
  761. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  762. int i;
  763. if (--bo_fake->refcount == 0) {
  764. assert(bo_fake->map_count == 0);
  765. /* No remaining references, so free it */
  766. if (bo_fake->block)
  767. free_block(bufmgr_fake, bo_fake->block, 1);
  768. free_backing_store(bo);
  769. for (i = 0; i < bo_fake->nr_relocs; i++)
  770. drm_intel_fake_bo_unreference_locked(bo_fake->relocs[i].
  771. target_buf);
  772. DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id,
  773. bo_fake->name);
  774. free(bo_fake->relocs);
  775. free(bo);
  776. }
  777. }
  778. static void
  779. drm_intel_fake_bo_unreference(drm_intel_bo *bo)
  780. {
  781. drm_intel_bufmgr_fake *bufmgr_fake =
  782. (drm_intel_bufmgr_fake *) bo->bufmgr;
  783. pthread_mutex_lock(&bufmgr_fake->lock);
  784. drm_intel_fake_bo_unreference_locked(bo);
  785. pthread_mutex_unlock(&bufmgr_fake->lock);
  786. }
  787. /**
  788. * Set the buffer as not requiring backing store, and instead get the callback
  789. * invoked whenever it would be set dirty.
  790. */
  791. drm_public void
  792. drm_intel_bo_fake_disable_backing_store(drm_intel_bo *bo,
  793. void (*invalidate_cb) (drm_intel_bo *bo,
  794. void *ptr),
  795. void *ptr)
  796. {
  797. drm_intel_bufmgr_fake *bufmgr_fake =
  798. (drm_intel_bufmgr_fake *) bo->bufmgr;
  799. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  800. pthread_mutex_lock(&bufmgr_fake->lock);
  801. if (bo_fake->backing_store)
  802. free_backing_store(bo);
  803. bo_fake->flags |= BM_NO_BACKING_STORE;
  804. DBG("disable_backing_store set buf %d dirty\n", bo_fake->id);
  805. bo_fake->dirty = 1;
  806. bo_fake->invalidate_cb = invalidate_cb;
  807. bo_fake->invalidate_ptr = ptr;
  808. /* Note that it is invalid right from the start. Also note
  809. * invalidate_cb is called with the bufmgr locked, so cannot
  810. * itself make bufmgr calls.
  811. */
  812. if (invalidate_cb != NULL)
  813. invalidate_cb(bo, ptr);
  814. pthread_mutex_unlock(&bufmgr_fake->lock);
  815. }
  816. /**
  817. * Map a buffer into bo->virtual, allocating either card memory space (If
  818. * BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary.
  819. */
  820. static int
  821. drm_intel_fake_bo_map_locked(drm_intel_bo *bo, int write_enable)
  822. {
  823. drm_intel_bufmgr_fake *bufmgr_fake =
  824. (drm_intel_bufmgr_fake *) bo->bufmgr;
  825. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  826. /* Static buffers are always mapped. */
  827. if (bo_fake->is_static) {
  828. if (bo_fake->card_dirty) {
  829. drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
  830. bo_fake->card_dirty = 0;
  831. }
  832. return 0;
  833. }
  834. /* Allow recursive mapping. Mesa may recursively map buffers with
  835. * nested display loops, and it is used internally in bufmgr_fake
  836. * for relocation.
  837. */
  838. if (bo_fake->map_count++ != 0)
  839. return 0;
  840. {
  841. DBG("drm_bo_map: (buf %d: %s, %lu kb)\n", bo_fake->id,
  842. bo_fake->name, bo_fake->bo.size / 1024);
  843. if (bo->virtual != NULL) {
  844. drmMsg("%s: already mapped\n", __func__);
  845. abort();
  846. } else if (bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)) {
  847. if (!bo_fake->block && !evict_and_alloc_block(bo)) {
  848. DBG("%s: alloc failed\n", __func__);
  849. bufmgr_fake->fail = 1;
  850. return 1;
  851. } else {
  852. assert(bo_fake->block);
  853. bo_fake->dirty = 0;
  854. if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA) &&
  855. bo_fake->block->fenced) {
  856. drm_intel_fake_bo_wait_rendering_locked
  857. (bo);
  858. }
  859. bo->virtual = bo_fake->block->virtual;
  860. }
  861. } else {
  862. if (write_enable)
  863. set_dirty(bo);
  864. if (bo_fake->backing_store == 0)
  865. alloc_backing_store(bo);
  866. if ((bo_fake->card_dirty == 1) && bo_fake->block) {
  867. if (bo_fake->block->fenced)
  868. drm_intel_fake_bo_wait_rendering_locked
  869. (bo);
  870. memcpy(bo_fake->backing_store,
  871. bo_fake->block->virtual,
  872. bo_fake->block->bo->size);
  873. bo_fake->card_dirty = 0;
  874. }
  875. bo->virtual = bo_fake->backing_store;
  876. }
  877. }
  878. return 0;
  879. }
  880. static int
  881. drm_intel_fake_bo_map(drm_intel_bo *bo, int write_enable)
  882. {
  883. drm_intel_bufmgr_fake *bufmgr_fake =
  884. (drm_intel_bufmgr_fake *) bo->bufmgr;
  885. int ret;
  886. pthread_mutex_lock(&bufmgr_fake->lock);
  887. ret = drm_intel_fake_bo_map_locked(bo, write_enable);
  888. pthread_mutex_unlock(&bufmgr_fake->lock);
  889. return ret;
  890. }
  891. static int
  892. drm_intel_fake_bo_unmap_locked(drm_intel_bo *bo)
  893. {
  894. drm_intel_bufmgr_fake *bufmgr_fake =
  895. (drm_intel_bufmgr_fake *) bo->bufmgr;
  896. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  897. /* Static buffers are always mapped. */
  898. if (bo_fake->is_static)
  899. return 0;
  900. assert(bo_fake->map_count != 0);
  901. if (--bo_fake->map_count != 0)
  902. return 0;
  903. DBG("drm_bo_unmap: (buf %d: %s, %lu kb)\n", bo_fake->id, bo_fake->name,
  904. bo_fake->bo.size / 1024);
  905. bo->virtual = NULL;
  906. return 0;
  907. }
  908. static int drm_intel_fake_bo_unmap(drm_intel_bo *bo)
  909. {
  910. drm_intel_bufmgr_fake *bufmgr_fake =
  911. (drm_intel_bufmgr_fake *) bo->bufmgr;
  912. int ret;
  913. pthread_mutex_lock(&bufmgr_fake->lock);
  914. ret = drm_intel_fake_bo_unmap_locked(bo);
  915. pthread_mutex_unlock(&bufmgr_fake->lock);
  916. return ret;
  917. }
  918. static int
  919. drm_intel_fake_bo_subdata(drm_intel_bo *bo, unsigned long offset,
  920. unsigned long size, const void *data)
  921. {
  922. int ret;
  923. if (size == 0 || data == NULL)
  924. return 0;
  925. ret = drm_intel_bo_map(bo, 1);
  926. if (ret)
  927. return ret;
  928. memcpy((unsigned char *)bo->virtual + offset, data, size);
  929. drm_intel_bo_unmap(bo);
  930. return 0;
  931. }
  932. static void
  933. drm_intel_fake_kick_all_locked(drm_intel_bufmgr_fake *bufmgr_fake)
  934. {
  935. struct block *block, *tmp;
  936. bufmgr_fake->performed_rendering = 0;
  937. /* okay for ever BO that is on the HW kick it off.
  938. seriously not afraid of the POLICE right now */
  939. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->on_hardware) {
  940. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
  941. block->on_hardware = 0;
  942. free_block(bufmgr_fake, block, 0);
  943. bo_fake->block = NULL;
  944. bo_fake->validated = 0;
  945. if (!(bo_fake->flags & BM_NO_BACKING_STORE))
  946. bo_fake->dirty = 1;
  947. }
  948. }
  949. static int
  950. drm_intel_fake_bo_validate(drm_intel_bo *bo)
  951. {
  952. drm_intel_bufmgr_fake *bufmgr_fake;
  953. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  954. bufmgr_fake = (drm_intel_bufmgr_fake *) bo->bufmgr;
  955. DBG("drm_bo_validate: (buf %d: %s, %lu kb)\n", bo_fake->id,
  956. bo_fake->name, bo_fake->bo.size / 1024);
  957. /* Sanity check: Buffers should be unmapped before being validated.
  958. * This is not so much of a problem for bufmgr_fake, but TTM refuses,
  959. * and the problem is harder to debug there.
  960. */
  961. assert(bo_fake->map_count == 0);
  962. if (bo_fake->is_static) {
  963. /* Add it to the needs-fence list */
  964. bufmgr_fake->need_fence = 1;
  965. return 0;
  966. }
  967. /* Allocate the card memory */
  968. if (!bo_fake->block && !evict_and_alloc_block(bo)) {
  969. bufmgr_fake->fail = 1;
  970. DBG("Failed to validate buf %d:%s\n", bo_fake->id,
  971. bo_fake->name);
  972. return -1;
  973. }
  974. assert(bo_fake->block);
  975. assert(bo_fake->block->bo == &bo_fake->bo);
  976. bo->offset = bo_fake->block->mem->ofs;
  977. /* Upload the buffer contents if necessary */
  978. if (bo_fake->dirty) {
  979. DBG("Upload dirty buf %d:%s, sz %lu offset 0x%x\n", bo_fake->id,
  980. bo_fake->name, bo->size, bo_fake->block->mem->ofs);
  981. assert(!(bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)));
  982. /* Actually, should be able to just wait for a fence on the
  983. * memory, which we would be tracking when we free it. Waiting
  984. * for idle is a sufficiently large hammer for now.
  985. */
  986. drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
  987. /* we may never have mapped this BO so it might not have any
  988. * backing store if this happens it should be rare, but 0 the
  989. * card memory in any case */
  990. if (bo_fake->backing_store)
  991. memcpy(bo_fake->block->virtual, bo_fake->backing_store,
  992. bo->size);
  993. else
  994. memset(bo_fake->block->virtual, 0, bo->size);
  995. bo_fake->dirty = 0;
  996. }
  997. bo_fake->block->fenced = 0;
  998. bo_fake->block->on_hardware = 1;
  999. DRMLISTDEL(bo_fake->block);
  1000. DRMLISTADDTAIL(bo_fake->block, &bufmgr_fake->on_hardware);
  1001. bo_fake->validated = 1;
  1002. bufmgr_fake->need_fence = 1;
  1003. return 0;
  1004. }
  1005. static void
  1006. drm_intel_fake_fence_validated(drm_intel_bufmgr *bufmgr)
  1007. {
  1008. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  1009. unsigned int cookie;
  1010. cookie = _fence_emit_internal(bufmgr_fake);
  1011. fence_blocks(bufmgr_fake, cookie);
  1012. DBG("drm_fence_validated: 0x%08x cookie\n", cookie);
  1013. }
  1014. static void
  1015. drm_intel_fake_destroy(drm_intel_bufmgr *bufmgr)
  1016. {
  1017. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  1018. pthread_mutex_destroy(&bufmgr_fake->lock);
  1019. mmDestroy(bufmgr_fake->heap);
  1020. free(bufmgr);
  1021. }
  1022. static int
  1023. drm_intel_fake_emit_reloc(drm_intel_bo *bo, uint32_t offset,
  1024. drm_intel_bo *target_bo, uint32_t target_offset,
  1025. uint32_t read_domains, uint32_t write_domain)
  1026. {
  1027. drm_intel_bufmgr_fake *bufmgr_fake =
  1028. (drm_intel_bufmgr_fake *) bo->bufmgr;
  1029. struct fake_buffer_reloc *r;
  1030. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  1031. drm_intel_bo_fake *target_fake = (drm_intel_bo_fake *) target_bo;
  1032. int i;
  1033. pthread_mutex_lock(&bufmgr_fake->lock);
  1034. assert(bo);
  1035. assert(target_bo);
  1036. if (bo_fake->relocs == NULL) {
  1037. bo_fake->relocs =
  1038. malloc(sizeof(struct fake_buffer_reloc) * MAX_RELOCS);
  1039. }
  1040. r = &bo_fake->relocs[bo_fake->nr_relocs++];
  1041. assert(bo_fake->nr_relocs <= MAX_RELOCS);
  1042. drm_intel_fake_bo_reference_locked(target_bo);
  1043. if (!target_fake->is_static) {
  1044. bo_fake->child_size +=
  1045. ALIGN(target_bo->size, target_fake->alignment);
  1046. bo_fake->child_size += target_fake->child_size;
  1047. }
  1048. r->target_buf = target_bo;
  1049. r->offset = offset;
  1050. r->last_target_offset = target_bo->offset;
  1051. r->delta = target_offset;
  1052. r->read_domains = read_domains;
  1053. r->write_domain = write_domain;
  1054. if (bufmgr_fake->debug) {
  1055. /* Check that a conflicting relocation hasn't already been
  1056. * emitted.
  1057. */
  1058. for (i = 0; i < bo_fake->nr_relocs - 1; i++) {
  1059. struct fake_buffer_reloc *r2 = &bo_fake->relocs[i];
  1060. assert(r->offset != r2->offset);
  1061. }
  1062. }
  1063. pthread_mutex_unlock(&bufmgr_fake->lock);
  1064. return 0;
  1065. }
  1066. /**
  1067. * Incorporates the validation flags associated with each relocation into
  1068. * the combined validation flags for the buffer on this batchbuffer submission.
  1069. */
  1070. static void
  1071. drm_intel_fake_calculate_domains(drm_intel_bo *bo)
  1072. {
  1073. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  1074. int i;
  1075. for (i = 0; i < bo_fake->nr_relocs; i++) {
  1076. struct fake_buffer_reloc *r = &bo_fake->relocs[i];
  1077. drm_intel_bo_fake *target_fake =
  1078. (drm_intel_bo_fake *) r->target_buf;
  1079. /* Do the same for the tree of buffers we depend on */
  1080. drm_intel_fake_calculate_domains(r->target_buf);
  1081. target_fake->read_domains |= r->read_domains;
  1082. target_fake->write_domain |= r->write_domain;
  1083. }
  1084. }
  1085. static int
  1086. drm_intel_fake_reloc_and_validate_buffer(drm_intel_bo *bo)
  1087. {
  1088. drm_intel_bufmgr_fake *bufmgr_fake =
  1089. (drm_intel_bufmgr_fake *) bo->bufmgr;
  1090. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  1091. int i, ret;
  1092. assert(bo_fake->map_count == 0);
  1093. for (i = 0; i < bo_fake->nr_relocs; i++) {
  1094. struct fake_buffer_reloc *r = &bo_fake->relocs[i];
  1095. drm_intel_bo_fake *target_fake =
  1096. (drm_intel_bo_fake *) r->target_buf;
  1097. uint32_t reloc_data;
  1098. /* Validate the target buffer if that hasn't been done. */
  1099. if (!target_fake->validated) {
  1100. ret =
  1101. drm_intel_fake_reloc_and_validate_buffer(r->target_buf);
  1102. if (ret != 0) {
  1103. if (bo->virtual != NULL)
  1104. drm_intel_fake_bo_unmap_locked(bo);
  1105. return ret;
  1106. }
  1107. }
  1108. /* Calculate the value of the relocation entry. */
  1109. if (r->target_buf->offset != r->last_target_offset) {
  1110. reloc_data = r->target_buf->offset + r->delta;
  1111. if (bo->virtual == NULL)
  1112. drm_intel_fake_bo_map_locked(bo, 1);
  1113. *(uint32_t *) ((uint8_t *) bo->virtual + r->offset) =
  1114. reloc_data;
  1115. r->last_target_offset = r->target_buf->offset;
  1116. }
  1117. }
  1118. if (bo->virtual != NULL)
  1119. drm_intel_fake_bo_unmap_locked(bo);
  1120. if (bo_fake->write_domain != 0) {
  1121. if (!(bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED))) {
  1122. if (bo_fake->backing_store == 0)
  1123. alloc_backing_store(bo);
  1124. }
  1125. bo_fake->card_dirty = 1;
  1126. bufmgr_fake->performed_rendering = 1;
  1127. }
  1128. return drm_intel_fake_bo_validate(bo);
  1129. }
  1130. static void
  1131. drm_intel_bo_fake_post_submit(drm_intel_bo *bo)
  1132. {
  1133. drm_intel_bufmgr_fake *bufmgr_fake =
  1134. (drm_intel_bufmgr_fake *) bo->bufmgr;
  1135. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
  1136. int i;
  1137. for (i = 0; i < bo_fake->nr_relocs; i++) {
  1138. struct fake_buffer_reloc *r = &bo_fake->relocs[i];
  1139. drm_intel_bo_fake *target_fake =
  1140. (drm_intel_bo_fake *) r->target_buf;
  1141. if (target_fake->validated)
  1142. drm_intel_bo_fake_post_submit(r->target_buf);
  1143. DBG("%s@0x%08x + 0x%08x -> %s@0x%08x + 0x%08x\n",
  1144. bo_fake->name, (uint32_t) bo->offset, r->offset,
  1145. target_fake->name, (uint32_t) r->target_buf->offset,
  1146. r->delta);
  1147. }
  1148. assert(bo_fake->map_count == 0);
  1149. bo_fake->validated = 0;
  1150. bo_fake->read_domains = 0;
  1151. bo_fake->write_domain = 0;
  1152. }
  1153. drm_public void
  1154. drm_intel_bufmgr_fake_set_exec_callback(drm_intel_bufmgr *bufmgr,
  1155. int (*exec) (drm_intel_bo *bo,
  1156. unsigned int used,
  1157. void *priv),
  1158. void *priv)
  1159. {
  1160. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  1161. bufmgr_fake->exec = exec;
  1162. bufmgr_fake->exec_priv = priv;
  1163. }
  1164. static int
  1165. drm_intel_fake_bo_exec(drm_intel_bo *bo, int used,
  1166. drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
  1167. {
  1168. drm_intel_bufmgr_fake *bufmgr_fake =
  1169. (drm_intel_bufmgr_fake *) bo->bufmgr;
  1170. drm_intel_bo_fake *batch_fake = (drm_intel_bo_fake *) bo;
  1171. struct drm_i915_batchbuffer batch;
  1172. int ret;
  1173. int retry_count = 0;
  1174. pthread_mutex_lock(&bufmgr_fake->lock);
  1175. bufmgr_fake->performed_rendering = 0;
  1176. drm_intel_fake_calculate_domains(bo);
  1177. batch_fake->read_domains = I915_GEM_DOMAIN_COMMAND;
  1178. /* we've ran out of RAM so blow the whole lot away and retry */
  1179. restart:
  1180. ret = drm_intel_fake_reloc_and_validate_buffer(bo);
  1181. if (bufmgr_fake->fail == 1) {
  1182. if (retry_count == 0) {
  1183. retry_count++;
  1184. drm_intel_fake_kick_all_locked(bufmgr_fake);
  1185. bufmgr_fake->fail = 0;
  1186. goto restart;
  1187. } else /* dump out the memory here */
  1188. mmDumpMemInfo(bufmgr_fake->heap);
  1189. }
  1190. assert(ret == 0);
  1191. if (bufmgr_fake->exec != NULL) {
  1192. ret = bufmgr_fake->exec(bo, used, bufmgr_fake->exec_priv);
  1193. if (ret != 0) {
  1194. pthread_mutex_unlock(&bufmgr_fake->lock);
  1195. return ret;
  1196. }
  1197. } else {
  1198. batch.start = bo->offset;
  1199. batch.used = used;
  1200. batch.cliprects = cliprects;
  1201. batch.num_cliprects = num_cliprects;
  1202. batch.DR1 = 0;
  1203. batch.DR4 = DR4;
  1204. if (drmCommandWrite
  1205. (bufmgr_fake->fd, DRM_I915_BATCHBUFFER, &batch,
  1206. sizeof(batch))) {
  1207. drmMsg("DRM_I915_BATCHBUFFER: %d\n", -errno);
  1208. pthread_mutex_unlock(&bufmgr_fake->lock);
  1209. return -errno;
  1210. }
  1211. }
  1212. drm_intel_fake_fence_validated(bo->bufmgr);
  1213. drm_intel_bo_fake_post_submit(bo);
  1214. pthread_mutex_unlock(&bufmgr_fake->lock);
  1215. return 0;
  1216. }
  1217. /**
  1218. * Return an error if the list of BOs will exceed the aperture size.
  1219. *
  1220. * This is a rough guess and likely to fail, as during the validate sequence we
  1221. * may place a buffer in an inopportune spot early on and then fail to fit
  1222. * a set smaller than the aperture.
  1223. */
  1224. static int
  1225. drm_intel_fake_check_aperture_space(drm_intel_bo ** bo_array, int count)
  1226. {
  1227. drm_intel_bufmgr_fake *bufmgr_fake =
  1228. (drm_intel_bufmgr_fake *) bo_array[0]->bufmgr;
  1229. unsigned int sz = 0;
  1230. int i;
  1231. for (i = 0; i < count; i++) {
  1232. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo_array[i];
  1233. if (bo_fake == NULL)
  1234. continue;
  1235. if (!bo_fake->is_static)
  1236. sz += ALIGN(bo_array[i]->size, bo_fake->alignment);
  1237. sz += bo_fake->child_size;
  1238. }
  1239. if (sz > bufmgr_fake->size) {
  1240. DBG("check_space: overflowed bufmgr size, %ukb vs %lukb\n",
  1241. sz / 1024, bufmgr_fake->size / 1024);
  1242. return -1;
  1243. }
  1244. DBG("drm_check_space: sz %ukb vs bufgr %lukb\n", sz / 1024,
  1245. bufmgr_fake->size / 1024);
  1246. return 0;
  1247. }
  1248. /**
  1249. * Evicts all buffers, waiting for fences to pass and copying contents out
  1250. * as necessary.
  1251. *
  1252. * Used by the X Server on LeaveVT, when the card memory is no longer our
  1253. * own.
  1254. */
  1255. drm_public void
  1256. drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
  1257. {
  1258. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  1259. struct block *block, *tmp;
  1260. pthread_mutex_lock(&bufmgr_fake->lock);
  1261. bufmgr_fake->need_fence = 1;
  1262. bufmgr_fake->fail = 0;
  1263. /* Wait for hardware idle. We don't know where acceleration has been
  1264. * happening, so we'll need to wait anyway before letting anything get
  1265. * put on the card again.
  1266. */
  1267. drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
  1268. /* Check that we hadn't released the lock without having fenced the last
  1269. * set of buffers.
  1270. */
  1271. assert(DRMLISTEMPTY(&bufmgr_fake->fenced));
  1272. assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
  1273. DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
  1274. drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
  1275. /* Releases the memory, and memcpys dirty contents out if
  1276. * necessary.
  1277. */
  1278. free_block(bufmgr_fake, block, 0);
  1279. bo_fake->block = NULL;
  1280. }
  1281. pthread_mutex_unlock(&bufmgr_fake->lock);
  1282. }
  1283. drm_public void
  1284. drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
  1285. volatile unsigned int
  1286. *last_dispatch)
  1287. {
  1288. drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
  1289. bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
  1290. }
  1291. drm_public drm_intel_bufmgr *
  1292. drm_intel_bufmgr_fake_init(int fd, unsigned long low_offset,
  1293. void *low_virtual, unsigned long size,
  1294. volatile unsigned int *last_dispatch)
  1295. {
  1296. drm_intel_bufmgr_fake *bufmgr_fake;
  1297. bufmgr_fake = calloc(1, sizeof(*bufmgr_fake));
  1298. if (pthread_mutex_init(&bufmgr_fake->lock, NULL) != 0) {
  1299. free(bufmgr_fake);
  1300. return NULL;
  1301. }
  1302. /* Initialize allocator */
  1303. DRMINITLISTHEAD(&bufmgr_fake->fenced);
  1304. DRMINITLISTHEAD(&bufmgr_fake->on_hardware);
  1305. DRMINITLISTHEAD(&bufmgr_fake->lru);
  1306. bufmgr_fake->low_offset = low_offset;
  1307. bufmgr_fake->virtual = low_virtual;
  1308. bufmgr_fake->size = size;
  1309. bufmgr_fake->heap = mmInit(low_offset, size);
  1310. /* Hook in methods */
  1311. bufmgr_fake->bufmgr.bo_alloc = drm_intel_fake_bo_alloc;
  1312. bufmgr_fake->bufmgr.bo_alloc_for_render = drm_intel_fake_bo_alloc;
  1313. bufmgr_fake->bufmgr.bo_alloc_tiled = drm_intel_fake_bo_alloc_tiled;
  1314. bufmgr_fake->bufmgr.bo_reference = drm_intel_fake_bo_reference;
  1315. bufmgr_fake->bufmgr.bo_unreference = drm_intel_fake_bo_unreference;
  1316. bufmgr_fake->bufmgr.bo_map = drm_intel_fake_bo_map;
  1317. bufmgr_fake->bufmgr.bo_unmap = drm_intel_fake_bo_unmap;
  1318. bufmgr_fake->bufmgr.bo_subdata = drm_intel_fake_bo_subdata;
  1319. bufmgr_fake->bufmgr.bo_wait_rendering =
  1320. drm_intel_fake_bo_wait_rendering;
  1321. bufmgr_fake->bufmgr.bo_emit_reloc = drm_intel_fake_emit_reloc;
  1322. bufmgr_fake->bufmgr.destroy = drm_intel_fake_destroy;
  1323. bufmgr_fake->bufmgr.bo_exec = drm_intel_fake_bo_exec;
  1324. bufmgr_fake->bufmgr.check_aperture_space =
  1325. drm_intel_fake_check_aperture_space;
  1326. bufmgr_fake->bufmgr.debug = 0;
  1327. bufmgr_fake->fd = fd;
  1328. bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
  1329. return &bufmgr_fake->bufmgr;
  1330. }