~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/bufmgr_fake.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
117
117
   struct block fenced;         /* after bmFenceBuffers (mi_flush, emit irq, write dword) */
118
118
                                /* then to pool->lru or free() */
119
119
 
 
120
   unsigned ctxId;
120
121
   unsigned last_fence;
121
122
   unsigned free_on_hardware;
122
123
 
163
164
   struct bufmgr *bm = intel->bm;
164
165
   struct pool *pool = &bm->pool[pool_nr];
165
166
   struct block *block = (struct block *)calloc(sizeof *block, 1);
 
167
   GLuint sz, align = (1<<buf->alignment);
 
168
 
166
169
   if (!block)
167
170
      return GL_FALSE;
168
171
 
169
 
   block->mem = mmAllocMem(pool->heap, buf->size, buf->alignment, 0);
 
172
   sz = (buf->size + align-1) & ~(align-1);
 
173
 
 
174
   block->mem = mmAllocMem(pool->heap, 
 
175
                           sz, 
 
176
                           buf->alignment, 0);
170
177
   if (!block->mem) {
171
178
      free(block);
172
179
      return GL_FALSE;
262
269
}
263
270
 
264
271
 
265
 
static int evict_lru( struct intel_context *intel, GLuint max_fence )
 
272
static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool )
266
273
{
267
274
   struct bufmgr *bm = intel->bm;
268
275
   struct block *block, *tmp;
286
293
            block->buf->block = NULL;
287
294
 
288
295
            free_block(intel, block);
 
296
            *pool = i;
289
297
            return 1;
290
298
         }
291
299
      }
299
307
#define foreach_s_rev(ptr, t, list)   \
300
308
        for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev)
301
309
 
302
 
static int evict_mru( struct intel_context *intel)
 
310
static int evict_mru( struct intel_context *intel, GLuint *pool )
303
311
{
304
312
   struct bufmgr *bm = intel->bm;
305
313
   struct block *block, *tmp;
319
327
            block->buf->block = NULL;
320
328
 
321
329
            free_block(intel, block);
 
330
            *pool = i;
322
331
            return 1;
323
332
         }
324
333
      }
426
435
   struct bufmgr *bm = intel->bm;
427
436
   int i;
428
437
 
 
438
   assert(intel->locked);
 
439
 
429
440
   DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name);
430
441
 
431
442
   for (i = 0; i < bm->nr_pools; i++) {
447
458
static GLboolean evict_and_alloc_block( struct intel_context *intel,
448
459
                                        struct buffer *buf )
449
460
{
 
461
   GLuint pool;
450
462
   struct bufmgr *bm = intel->bm;
451
463
 
452
464
   assert(buf->block == NULL);
472
484
 
473
485
   /* Look for memory blocks not used for >1 frame:
474
486
    */
475
 
   while (evict_lru(intel, intel->second_last_swap_fence))
476
 
      if (alloc_block(intel, buf))
 
487
   while (evict_lru(intel, intel->second_last_swap_fence, &pool))
 
488
      if (alloc_from_pool(intel, pool, buf))
477
489
         return GL_TRUE;
478
490
 
479
491
   /* If we're not thrashing, allow lru eviction to dig deeper into
480
492
    * recently used textures.  We'll probably be thrashing soon:
481
493
    */
482
494
   if (!intel->thrashing) {
483
 
      while (evict_lru(intel, 0))
484
 
         if (alloc_block(intel, buf))
 
495
      while (evict_lru(intel, 0, &pool))
 
496
         if (alloc_from_pool(intel, pool, buf))
485
497
            return GL_TRUE;
486
498
   }
487
499
 
508
520
   if (!is_empty_list(&bm->on_hardware)) {
509
521
      bmSetFence(intel);
510
522
 
511
 
      if (!is_empty_list(&bm->fenced)) {
 
523
      while (!is_empty_list(&bm->fenced)) {
512
524
         GLuint fence = bm->fenced.next->fence;
513
525
         bmFinishFence(intel, fence);
514
526
      }
522
534
         return GL_TRUE;
523
535
   }
524
536
 
525
 
   while (evict_mru(intel))
526
 
      if (alloc_block(intel, buf))
 
537
   while (evict_mru(intel, &pool))
 
538
      if (alloc_from_pool(intel, pool, buf))
527
539
         return GL_TRUE;
528
540
 
 
541
   DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size);
 
542
 
 
543
   assert(is_empty_list(&bm->on_hardware));
 
544
   assert(is_empty_list(&bm->fenced));
 
545
 
529
546
   return GL_FALSE;
530
547
}
531
548
 
562
579
      make_empty_list(&bm.referenced);
563
580
      make_empty_list(&bm.fenced);
564
581
      make_empty_list(&bm.on_hardware);
 
582
      
 
583
      /* The context id of any of the share group.  This won't be used
 
584
       * in communication with the kernel, so it doesn't matter if
 
585
       * this context is eventually deleted.
 
586
       */
 
587
      bm.ctxId = intel->hHWContext;
565
588
   }
566
589
 
567
590
   nr_attach++;
582
605
                unsigned flags)
583
606
{
584
607
   struct bufmgr *bm = intel->bm;
585
 
   int retval;
 
608
   int retval = 0;
586
609
 
587
610
   LOCK(bm);
588
611
   {
621
644
   return retval;
622
645
}
623
646
 
624
 
static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name)
 
647
static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align)
625
648
{
626
649
   struct bufmgr *bm = intel->bm;
627
650
   struct buffer *buf = calloc(sizeof(*buf), 1);
628
651
 
629
652
   buf->id = ++bm->buf_nr;
630
653
   buf->name = name;
631
 
   buf->alignment = 12; /* page-alignment to fit in with AGP swapping */
 
654
   buf->alignment = align;      
632
655
   buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL;
633
656
 
634
657
   return buf;
635
658
}
636
659
 
 
660
 
 
661
void *bmFindVirtual( struct intel_context *intel,
 
662
                     unsigned int offset,
 
663
                     size_t sz )
 
664
{
 
665
   struct bufmgr *bm = intel->bm;
 
666
   int i;
 
667
 
 
668
   for (i = 0; i < bm->nr_pools; i++)
 
669
      if (offset >= bm->pool[i].low_offset &&
 
670
          offset + sz <= bm->pool[i].low_offset + bm->pool[i].size)
 
671
         return bm->pool[i].virtual + offset;
 
672
 
 
673
   return NULL;
 
674
}
637
675
 
638
676
 
639
677
void bmGenBuffers(struct intel_context *intel, 
640
678
                  const char *name, unsigned n, 
641
 
                  struct buffer **buffers)
 
679
                  struct buffer **buffers,
 
680
                  int align )
642
681
{
643
682
   struct bufmgr *bm = intel->bm;
644
683
   LOCK(bm);
646
685
      int i;
647
686
 
648
687
      for (i = 0; i < n; i++)
649
 
         buffers[i] = do_GenBuffer(intel, name);
 
688
         buffers[i] = do_GenBuffer(intel, name, align);
650
689
   }
651
690
   UNLOCK(bm);
652
691
}
694
733
      if (bm->pool[pool].static_buffer)
695
734
         buf = bm->pool[pool].static_buffer;
696
735
      else {
697
 
         buf = do_GenBuffer(intel, "static");
 
736
         buf = do_GenBuffer(intel, "static", 12);
698
737
   
699
738
         bm->pool[pool].static_buffer = buf;
700
739
         assert(!buf->block);
735
774
/* If buffer size changes, free and reallocate.  Otherwise update in
736
775
 * place.
737
776
 */
738
 
void bmBufferData(struct intel_context *intel, 
739
 
                  struct buffer *buf, 
740
 
                  unsigned size, 
741
 
                  const void *data, 
742
 
                  unsigned flags )
 
777
int bmBufferData(struct intel_context *intel, 
 
778
                 struct buffer *buf, 
 
779
                 unsigned size, 
 
780
                 const void *data, 
 
781
                 unsigned flags )
743
782
{
744
783
   struct bufmgr *bm = intel->bm;
 
784
   int retval = 0;
745
785
 
746
786
   LOCK(bm);
747
787
   {
773
813
 
774
814
      buf->size = size;
775
815
      if (buf->block) {
776
 
         assert (buf->block->mem->size == size);
 
816
         assert (buf->block->mem->size >= size);
777
817
      }
778
818
 
779
819
      if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) {
780
 
         if (data != NULL) {      
781
 
            if (!buf->block && !evict_and_alloc_block(intel, buf))
782
 
               assert(0);
 
820
 
 
821
         assert(intel->locked || data == NULL);
 
822
 
 
823
         if (data != NULL) {
 
824
            if (!buf->block && !evict_and_alloc_block(intel, buf)) {
 
825
               bm->fail = 1;
 
826
               retval = -1;
 
827
               goto out;
 
828
            }
783
829
 
784
830
            wait_quiescent(intel, buf->block);
785
831
 
803
849
         }
804
850
      }
805
851
   }
 
852
 out:
806
853
   UNLOCK(bm);
 
854
   return retval;
807
855
}
808
856
 
809
857
 
810
858
/* Update the buffer in place, in whatever space it is currently resident:
811
859
 */
812
 
void bmBufferSubData(struct intel_context *intel, 
 
860
int bmBufferSubData(struct intel_context *intel, 
813
861
                     struct buffer *buf, 
814
862
                     unsigned offset, 
815
863
                     unsigned size, 
816
864
                     const void *data )
817
865
{
818
866
   struct bufmgr *bm = intel->bm;
 
867
   int retval = 0;
819
868
 
820
869
   if (size == 0) 
821
 
      return;
 
870
      return 0;
822
871
 
823
872
   LOCK(bm); 
824
873
   {
827
876
      assert(offset+size <= buf->size);
828
877
 
829
878
      if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) {
830
 
         if (!buf->block && !evict_and_alloc_block(intel, buf))
831
 
            assert(0);
 
879
 
 
880
         assert(intel->locked);
 
881
 
 
882
         if (!buf->block && !evict_and_alloc_block(intel, buf)) {
 
883
            bm->fail = 1;
 
884
            retval = -1;
 
885
            goto out;
 
886
         }
832
887
         
833
888
         if (!(buf->flags & BM_NO_FENCE_SUBDATA))
834
889
            wait_quiescent(intel, buf->block);
847
902
         do_memcpy(buf->backing_store + offset, data, size); 
848
903
      }
849
904
   }
 
905
 out:
850
906
   UNLOCK(bm);
 
907
   return retval;
851
908
}
852
909
 
853
910
 
854
911
 
855
 
void bmBufferDataAUB(struct intel_context *intel, 
 
912
int bmBufferDataAUB(struct intel_context *intel, 
856
913
                     struct buffer *buf, 
857
914
                     unsigned size, 
858
915
                     const void *data, 
860
917
                     unsigned aubtype,
861
918
                     unsigned aubsubtype )
862
919
{
863
 
   bmBufferData(intel, buf, size, data, flags);
 
920
   int retval = bmBufferData(intel, buf, size, data, flags);
864
921
   
865
922
 
866
923
   /* This only works because in this version of the buffer manager we
867
924
    * allocate all buffers statically in agp space and so can emit the
868
925
    * uploads to the aub file with the correct offsets as they happen.
869
926
    */
870
 
   if (data && intel->aub_file) {
 
927
   if (retval == 0 && data && intel->aub_file) {
871
928
 
872
929
      if (buf->block && !buf->dirty) {
873
930
         intel->vtbl.aub_gtt_data(intel,
879
936
         buf->aub_dirty = 0;
880
937
      }
881
938
   }
 
939
   
 
940
   return retval;
882
941
}
883
942
                       
884
943
 
885
 
void bmBufferSubDataAUB(struct intel_context *intel, 
 
944
int bmBufferSubDataAUB(struct intel_context *intel, 
886
945
                        struct buffer *buf, 
887
946
                        unsigned offset, 
888
947
                        unsigned size, 
890
949
                        unsigned aubtype,
891
950
                        unsigned aubsubtype )
892
951
{
893
 
   bmBufferSubData(intel, buf, offset, size, data);
 
952
   int retval = bmBufferSubData(intel, buf, offset, size, data);
894
953
   
895
954
 
896
955
   /* This only works because in this version of the buffer manager we
898
957
    * uploads to the aub file with the correct offsets as they happen.
899
958
    */
900
959
   if (intel->aub_file) {
901
 
      if (buf->block && !buf->dirty)
 
960
      if (retval == 0 && buf->block && !buf->dirty)
902
961
         intel->vtbl.aub_gtt_data(intel,
903
962
                                      buf->block->mem->ofs + offset,
904
963
                                      ((const char *)buf->block->virtual) + offset,
906
965
                                      aubtype,
907
966
                                      aubsubtype);
908
967
   }
 
968
 
 
969
   return retval;
909
970
}
910
971
 
911
972
void bmUnmapBufferAUB( struct intel_context *intel, 
930
991
                        struct buffer *buf)
931
992
{
932
993
   struct bufmgr *bm = intel->bm;
933
 
   unsigned retval;
 
994
   unsigned retval = 0;
934
995
 
935
996
   LOCK(bm);
936
997
   {
998
1059
                   unsigned flags )
999
1060
{
1000
1061
   struct bufmgr *bm = intel->bm;
1001
 
   void *retval;
 
1062
   void *retval = NULL;
1002
1063
 
1003
1064
   LOCK(bm);
1004
1065
   {
1009
1070
         retval = NULL;
1010
1071
      }
1011
1072
      else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) {
 
1073
 
 
1074
         assert(intel->locked);
 
1075
 
1012
1076
         if (!buf->block && !evict_and_alloc_block(intel, buf)) {
1013
 
            _mesa_printf("%s: alloc failed\n", __FUNCTION__);
 
1077
            DBG("%s: alloc failed\n", __FUNCTION__);
 
1078
            bm->fail = 1;
1014
1079
            retval = NULL;
1015
1080
         }
1016
1081
         else {
1025
1090
         }
1026
1091
      }
1027
1092
      else {
1028
 
               DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id);
 
1093
         DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id);
1029
1094
         set_dirty(intel, buf);
1030
1095
 
1031
1096
         if (buf->backing_store == 0)
1104
1169
int bmValidateBuffers( struct intel_context *intel )
1105
1170
{
1106
1171
   struct bufmgr *bm = intel->bm;
1107
 
   int retval;
 
1172
   int retval = 0;
1108
1173
 
1109
1174
   LOCK(bm);
1110
1175
   {
1111
1176
      DBG("%s fail %d\n", __FUNCTION__, bm->fail);
 
1177
      assert(intel->locked);
1112
1178
 
1113
1179
      if (!bm->fail) {
1114
1180
         struct block *block, *tmp;
1162
1228
         bm->need_fence = 1;
1163
1229
      }
1164
1230
 
1165
 
      retval = !bm->fail;
1166
 
      bm->fail = 0;
1167
 
      assert(is_empty_list(&bm->referenced));
 
1231
      retval = bm->fail ? -1 : 0;
1168
1232
   }
1169
1233
   UNLOCK(bm);
1170
1234
 
 
1235
 
 
1236
   if (retval != 0)
 
1237
      DBG("%s failed\n", __FUNCTION__);
 
1238
 
1171
1239
   return retval;
1172
1240
}
1173
1241
 
1213
1281
 
1214
1282
         block->referenced = 0;
1215
1283
      }
1216
 
 
1217
 
      bm->fail = 0;
1218
1284
   }
1219
1285
   UNLOCK(bm);
1220
1286
}
1241
1307
      GLuint dword[2];
1242
1308
      dword[0] = intel->vtbl.flush_cmd();
1243
1309
      dword[1] = 0;
1244
 
      intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword), GL_TRUE);
 
1310
      intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword));
1245
1311
      
1246
1312
      intel->bm->last_fence = intelEmitIrqLocked( intel );
1247
1313
      
1303
1369
      assert(is_empty_list(&bm->referenced));
1304
1370
 
1305
1371
      bm->need_fence = 1;
1306
 
      bmFinishFence(intel, bmSetFence(intel));
1307
 
 
1308
 
      for (i = 0; i < bm->nr_pools; i++) {
1309
 
         if (!(bm->pool[i].flags & BM_NO_EVICT)) {
1310
 
            foreach_s(block, tmp, &bm->pool[i].lru) {
1311
 
               assert(bmTestFence(intel, block->fence));
1312
 
               set_dirty(intel, block->buf);
1313
 
            }
1314
 
         }
1315
 
      }
1316
 
   }
1317
 
   UNLOCK(bm);
1318
 
}
1319
 
 
1320
 
 
 
1372
      bm->fail = 0;
 
1373
      bmFinishFence(intel, bmSetFence(intel));
 
1374
 
 
1375
      assert(is_empty_list(&bm->fenced));
 
1376
      assert(is_empty_list(&bm->on_hardware));
 
1377
 
 
1378
      for (i = 0; i < bm->nr_pools; i++) {
 
1379
         if (!(bm->pool[i].flags & BM_NO_EVICT)) {
 
1380
            foreach_s(block, tmp, &bm->pool[i].lru) {
 
1381
               assert(bmTestFence(intel, block->fence));
 
1382
               set_dirty(intel, block->buf);
 
1383
            }
 
1384
         }
 
1385
      }
 
1386
   }
 
1387
   UNLOCK(bm);
 
1388
}
 
1389
 
 
1390
 
 
1391
 
 
1392
void bmEvictAll( struct intel_context *intel )
 
1393
{
 
1394
   struct bufmgr *bm = intel->bm;
 
1395
 
 
1396
   LOCK(bm);
 
1397
   {
 
1398
      struct block *block, *tmp;
 
1399
      GLuint i;
 
1400
 
 
1401
      DBG("%s\n", __FUNCTION__);
 
1402
 
 
1403
      assert(is_empty_list(&bm->referenced));
 
1404
 
 
1405
      bm->need_fence = 1;
 
1406
      bm->fail = 0;
 
1407
      bmFinishFence(intel, bmSetFence(intel));
 
1408
 
 
1409
      assert(is_empty_list(&bm->fenced));
 
1410
      assert(is_empty_list(&bm->on_hardware));
 
1411
 
 
1412
      for (i = 0; i < bm->nr_pools; i++) {
 
1413
         if (!(bm->pool[i].flags & BM_NO_EVICT)) {
 
1414
            foreach_s(block, tmp, &bm->pool[i].lru) {
 
1415
               assert(bmTestFence(intel, block->fence));
 
1416
               set_dirty(intel, block->buf);
 
1417
               block->buf->block = NULL;
 
1418
 
 
1419
               free_block(intel, block);
 
1420
            }
 
1421
         }
 
1422
      }
 
1423
   }
 
1424
   UNLOCK(bm);
 
1425
}
 
1426
 
 
1427
 
 
1428
GLboolean bmError( struct intel_context *intel )
 
1429
{
 
1430
   struct bufmgr *bm = intel->bm;
 
1431
   GLboolean retval;
 
1432
 
 
1433
   LOCK(bm);
 
1434
   {
 
1435
      retval = bm->fail;
 
1436
   }
 
1437
   UNLOCK(bm);
 
1438
 
 
1439
   return retval;
 
1440
}
 
1441
 
 
1442
 
 
1443
GLuint bmCtxId( struct intel_context *intel )
 
1444
{
 
1445
   return intel->bm->ctxId;
 
1446
}