2 * Copyright © 2008 Nicolai Haehnle
3 * Copyright © 2008 Dave Airlie
4 * Copyright © 2008 Jérôme Glisse
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * The above copyright notice and this permission notice (including the
24 * next paragraph) shall be included in all copies or substantial portions
29 * Aapo Tahkola <aet@rasterburn.org>
30 * Nicolai Haehnle <prefect_@gmx.net>
32 * Jérôme Glisse <glisse@freedesktop.org>
42 #include <sys/ioctl.h>
45 #include "main/simple_list.h"
48 #include "radeon_drm.h"
49 #include "radeon_common.h"
50 #include "radeon_bocs_wrapper.h"
51 #include "radeon_macros.h"
53 #ifdef HAVE_LIBDRM_RADEON
54 #include "radeon_bo_int.h"
56 #include "radeon_bo_int_drm.h"
59 /* no seriously texmem.c is this screwed up */
60 struct bo_legacy_texture_object
{
61 driTextureObject base
;
62 struct bo_legacy
*parent
;
66 struct radeon_bo_int base
;
72 struct bo_legacy_texture_object
*tobj
;
76 struct bo_legacy
*next
, *prev
;
77 struct bo_legacy
*pnext
, *pprev
;
80 struct bo_manager_legacy
{
81 struct radeon_bo_manager base
;
83 unsigned nfree_handles
;
84 unsigned cfree_handles
;
87 struct bo_legacy pending_bos
;
89 uint32_t texture_offset
;
90 unsigned dma_alloc_size
;
91 uint32_t dma_buf_count
;
93 driTextureObject texture_swapped
;
94 driTexHeap
*texture_heap
;
95 struct radeon_screen
*screen
;
96 unsigned *free_handles
;
99 static void bo_legacy_tobj_destroy(void *data
, driTextureObject
*t
)
101 struct bo_legacy_texture_object
*tobj
= (struct bo_legacy_texture_object
*)t
;
104 tobj
->parent
->tobj
= NULL
;
105 tobj
->parent
->validated
= 0;
109 static void inline clean_handles(struct bo_manager_legacy
*bom
)
111 while (bom
->cfree_handles
> 0 &&
112 !bom
->free_handles
[bom
->cfree_handles
- 1])
113 bom
->cfree_handles
--;
116 static int legacy_new_handle(struct bo_manager_legacy
*bom
, uint32_t *handle
)
121 if (bom
->nhandle
== 0xFFFFFFFF) {
124 if (bom
->cfree_handles
> 0) {
125 tmp
= bom
->free_handles
[--bom
->cfree_handles
];
128 bom
->cfree_handles
= 0;
129 tmp
= bom
->nhandle
++;
136 static int legacy_free_handle(struct bo_manager_legacy
*bom
, uint32_t handle
)
143 if (handle
== (bom
->nhandle
- 1)) {
147 for (i
= bom
->cfree_handles
- 1; i
>= 0; i
--) {
148 if (bom
->free_handles
[i
] == (bom
->nhandle
- 1)) {
150 bom
->free_handles
[i
] = 0;
156 if (bom
->cfree_handles
< bom
->nfree_handles
) {
157 bom
->free_handles
[bom
->cfree_handles
++] = handle
;
160 bom
->nfree_handles
+= 0x100;
161 handles
= (uint32_t*)realloc(bom
->free_handles
, bom
->nfree_handles
* 4);
162 if (handles
== NULL
) {
163 bom
->nfree_handles
-= 0x100;
166 bom
->free_handles
= handles
;
167 bom
->free_handles
[bom
->cfree_handles
++] = handle
;
171 static void legacy_get_current_age(struct bo_manager_legacy
*boml
)
173 drm_radeon_getparam_t gp
;
174 unsigned char *RADEONMMIO
= NULL
;
177 if ( IS_R300_CLASS(boml
->screen
)
178 || IS_R600_CLASS(boml
->screen
) )
180 gp
.param
= RADEON_PARAM_LAST_CLEAR
;
181 gp
.value
= (int *)&boml
->current_age
;
182 r
= drmCommandWriteRead(boml
->base
.fd
, DRM_RADEON_GETPARAM
,
185 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
, r
);
190 RADEONMMIO
= boml
->screen
->mmio
.map
;
191 boml
->current_age
= boml
->screen
->scratch
[3];
192 boml
->current_age
= INREG(RADEON_GUI_SCRATCH_REG3
);
196 static int legacy_is_pending(struct radeon_bo_int
*boi
)
198 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)boi
->bom
;
199 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)boi
;
201 if (bo_legacy
->is_pending
<= 0) {
202 bo_legacy
->is_pending
= 0;
205 if (boml
->current_age
>= bo_legacy
->pending
) {
206 if (boml
->pending_bos
.pprev
== bo_legacy
) {
207 boml
->pending_bos
.pprev
= bo_legacy
->pprev
;
209 bo_legacy
->pprev
->pnext
= bo_legacy
->pnext
;
210 if (bo_legacy
->pnext
) {
211 bo_legacy
->pnext
->pprev
= bo_legacy
->pprev
;
213 assert(bo_legacy
->is_pending
<= boi
->cref
);
214 while (bo_legacy
->is_pending
--) {
215 boi
= (struct radeon_bo_int
*)radeon_bo_unref((struct radeon_bo
*)boi
);
220 bo_legacy
->is_pending
= 0;
227 static int legacy_wait_pending(struct radeon_bo_int
*bo
)
229 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bo
->bom
;
230 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
232 if (!bo_legacy
->is_pending
) {
235 /* FIXME: lockup and userspace busy looping that's all the folks */
236 legacy_get_current_age(boml
);
237 while (legacy_is_pending(bo
)) {
239 legacy_get_current_age(boml
);
244 void legacy_track_pending(struct radeon_bo_manager
*bom
, int debug
)
246 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*) bom
;
247 struct bo_legacy
*bo_legacy
;
248 struct bo_legacy
*next
;
250 legacy_get_current_age(boml
);
251 bo_legacy
= boml
->pending_bos
.pnext
;
254 fprintf(stderr
,"pending %p %d %d %d\n", bo_legacy
, bo_legacy
->base
.size
,
255 boml
->current_age
, bo_legacy
->pending
);
256 next
= bo_legacy
->pnext
;
257 if (legacy_is_pending(&(bo_legacy
->base
))) {
263 static int legacy_wait_any_pending(struct bo_manager_legacy
*boml
)
265 struct bo_legacy
*bo_legacy
;
267 legacy_get_current_age(boml
);
268 bo_legacy
= boml
->pending_bos
.pnext
;
271 legacy_wait_pending(&bo_legacy
->base
);
275 static void legacy_kick_all_buffers(struct bo_manager_legacy
*boml
)
277 struct bo_legacy
*legacy
;
279 legacy
= boml
->bos
.next
;
280 while (legacy
!= &boml
->bos
) {
282 if (legacy
->validated
) {
283 driDestroyTextureObject(&legacy
->tobj
->base
);
285 legacy
->validated
= 0;
288 legacy
= legacy
->next
;
292 static struct bo_legacy
*bo_allocate(struct bo_manager_legacy
*boml
,
298 struct bo_legacy
*bo_legacy
;
302 pgsize
= getpagesize() - 1;
304 size
= (size
+ pgsize
) & ~pgsize
;
306 bo_legacy
= (struct bo_legacy
*)calloc(1, sizeof(struct bo_legacy
));
307 if (bo_legacy
== NULL
) {
310 bo_legacy
->base
.bom
= (struct radeon_bo_manager
*)boml
;
311 bo_legacy
->base
.handle
= 0;
312 bo_legacy
->base
.size
= size
;
313 bo_legacy
->base
.alignment
= alignment
;
314 bo_legacy
->base
.domains
= domains
;
315 bo_legacy
->base
.flags
= flags
;
316 bo_legacy
->base
.ptr
= NULL
;
317 bo_legacy
->map_count
= 0;
318 bo_legacy
->next
= NULL
;
319 bo_legacy
->prev
= NULL
;
320 bo_legacy
->pnext
= NULL
;
321 bo_legacy
->pprev
= NULL
;
322 bo_legacy
->next
= boml
->bos
.next
;
323 bo_legacy
->prev
= &boml
->bos
;
324 boml
->bos
.next
= bo_legacy
;
325 if (bo_legacy
->next
) {
326 bo_legacy
->next
->prev
= bo_legacy
;
332 static int bo_dma_alloc(struct radeon_bo_int
*bo
)
334 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bo
->bom
;
335 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
336 drm_radeon_mem_alloc_t alloc
;
341 /* align size on 4Kb */
342 size
= (((4 * 1024) - 1) + bo_legacy
->base
.size
) & ~((4 * 1024) - 1);
343 alloc
.region
= RADEON_MEM_REGION_GART
;
344 alloc
.alignment
= bo_legacy
->base
.alignment
;
346 alloc
.region_offset
= &base_offset
;
347 r
= drmCommandWriteRead(bo
->bom
->fd
,
352 /* ptr is set to NULL if dma allocation failed */
353 bo_legacy
->ptr
= NULL
;
356 bo_legacy
->ptr
= boml
->screen
->gartTextures
.map
+ base_offset
;
357 bo_legacy
->offset
= boml
->screen
->gart_texture_offset
+ base_offset
;
359 boml
->dma_alloc_size
+= size
;
360 boml
->dma_buf_count
++;
364 static int bo_dma_free(struct radeon_bo_int
*bo
)
366 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bo
->bom
;
367 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
368 drm_radeon_mem_free_t memfree
;
371 if (bo_legacy
->ptr
== NULL
) {
372 /* ptr is set to NULL if dma allocation failed */
375 legacy_get_current_age(boml
);
376 memfree
.region
= RADEON_MEM_REGION_GART
;
377 memfree
.region_offset
= bo_legacy
->offset
;
378 memfree
.region_offset
-= boml
->screen
->gart_texture_offset
;
379 r
= drmCommandWrite(boml
->base
.fd
,
384 fprintf(stderr
, "Failed to free bo[%p] at %08x\n",
385 &bo_legacy
->base
, memfree
.region_offset
);
386 fprintf(stderr
, "ret = %s\n", strerror(-r
));
389 boml
->dma_alloc_size
-= bo_legacy
->base
.size
;
390 boml
->dma_buf_count
--;
394 static void bo_free(struct bo_legacy
*bo_legacy
)
396 struct bo_manager_legacy
*boml
;
398 if (bo_legacy
== NULL
) {
401 boml
= (struct bo_manager_legacy
*)bo_legacy
->base
.bom
;
402 bo_legacy
->prev
->next
= bo_legacy
->next
;
403 if (bo_legacy
->next
) {
404 bo_legacy
->next
->prev
= bo_legacy
->prev
;
406 if (!bo_legacy
->static_bo
) {
407 legacy_free_handle(boml
, bo_legacy
->base
.handle
);
408 if (bo_legacy
->base
.domains
& RADEON_GEM_DOMAIN_GTT
) {
410 bo_dma_free(&bo_legacy
->base
);
412 driDestroyTextureObject(&bo_legacy
->tobj
->base
);
413 bo_legacy
->tobj
= NULL
;
414 /* free backing store */
415 free(bo_legacy
->ptr
);
418 memset(bo_legacy
, 0 , sizeof(struct bo_legacy
));
422 static struct radeon_bo
*bo_open(struct radeon_bo_manager
*bom
,
429 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bom
;
430 struct bo_legacy
*bo_legacy
;
434 bo_legacy
= boml
->bos
.next
;
436 if (bo_legacy
->base
.handle
== handle
) {
437 radeon_bo_ref((struct radeon_bo
*)&(bo_legacy
->base
));
438 return (struct radeon_bo
*)bo_legacy
;
440 bo_legacy
= bo_legacy
->next
;
444 bo_legacy
= bo_allocate(boml
, size
, alignment
, domains
, flags
);
445 bo_legacy
->static_bo
= 0;
446 r
= legacy_new_handle(boml
, &bo_legacy
->base
.handle
);
451 if (bo_legacy
->base
.domains
& RADEON_GEM_DOMAIN_GTT
)
454 legacy_track_pending(&boml
->base
, 0);
457 r
= bo_dma_alloc(&(bo_legacy
->base
));
460 if (legacy_wait_any_pending(boml
) == -1)
471 bo_legacy
->ptr
= malloc(bo_legacy
->base
.size
);
472 if (bo_legacy
->ptr
== NULL
) {
477 radeon_bo_ref((struct radeon_bo
*)&(bo_legacy
->base
));
479 return (struct radeon_bo
*)bo_legacy
;
482 static void bo_ref(struct radeon_bo_int
*bo
)
486 static struct radeon_bo
*bo_unref(struct radeon_bo_int
*boi
)
488 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)boi
;
490 if (boi
->cref
<= 0) {
491 bo_legacy
->prev
->next
= bo_legacy
->next
;
492 if (bo_legacy
->next
) {
493 bo_legacy
->next
->prev
= bo_legacy
->prev
;
495 if (!bo_legacy
->is_pending
) {
500 return (struct radeon_bo
*)boi
;
503 static int bo_map(struct radeon_bo_int
*bo
, int write
)
505 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bo
->bom
;
506 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
508 legacy_wait_pending(bo
);
509 bo_legacy
->validated
= 0;
510 bo_legacy
->dirty
= 1;
511 bo_legacy
->map_count
++;
512 bo
->ptr
= bo_legacy
->ptr
;
513 /* Read the first pixel in the frame buffer. This should
514 * be a noop, right? In fact without this conform fails as reading
515 * from the framebuffer sometimes produces old results -- the
516 * on-card read cache gets mixed up and doesn't notice that the
517 * framebuffer has been updated.
519 * Note that we should probably be reading some otherwise unused
520 * region of VRAM, otherwise we might get incorrect results when
521 * reading pixels from the top left of the screen.
523 * I found this problem on an R420 with glean's texCube test.
524 * Note that the R200 span code also *writes* the first pixel in the
525 * framebuffer, but I've found this to be unnecessary.
526 * -- Nicolai Hähnle, June 2008
528 if (!(bo
->domains
& RADEON_GEM_DOMAIN_GTT
)) {
530 volatile int *buf
= (int*)boml
->screen
->driScreen
->pFB
;
537 static int bo_unmap(struct radeon_bo_int
*bo
)
539 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
541 if (--bo_legacy
->map_count
> 0)
551 static int bo_is_busy(struct radeon_bo_int
*bo
, uint32_t *domain
)
554 if (bo
->domains
& RADEON_GEM_DOMAIN_GTT
)
555 *domain
= RADEON_GEM_DOMAIN_GTT
;
557 *domain
= RADEON_GEM_DOMAIN_CPU
;
558 if (legacy_is_pending(bo
))
564 static int bo_is_static(struct radeon_bo_int
*bo
)
566 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
567 return bo_legacy
->static_bo
;
570 static struct radeon_bo_funcs bo_legacy_funcs
= {
583 static int bo_vram_validate(struct radeon_bo_int
*bo
,
587 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bo
->bom
;
588 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
590 int retry_count
= 0, pending_retry
= 0;
592 if (!bo_legacy
->tobj
) {
593 bo_legacy
->tobj
= CALLOC(sizeof(struct bo_legacy_texture_object
));
594 bo_legacy
->tobj
->parent
= bo_legacy
;
595 make_empty_list(&bo_legacy
->tobj
->base
);
596 bo_legacy
->tobj
->base
.totalSize
= bo
->size
;
598 r
= driAllocateTexture(&boml
->texture_heap
, 1,
599 &bo_legacy
->tobj
->base
);
602 while(boml
->cpendings
&& pending_retry
++ < 10000) {
603 legacy_track_pending(&boml
->base
, 0);
605 if (retry_count
> 2) {
606 free(bo_legacy
->tobj
);
607 bo_legacy
->tobj
= NULL
;
608 fprintf(stderr
, "Ouch! vram_validate failed %d\n", r
);
614 bo_legacy
->offset
= boml
->texture_offset
+
615 bo_legacy
->tobj
->base
.memBlock
->ofs
;
616 bo_legacy
->dirty
= 1;
619 assert(bo_legacy
->tobj
->base
.memBlock
);
622 driUpdateTextureLRU(&bo_legacy
->tobj
->base
);
624 if (bo_legacy
->dirty
|| bo_legacy
->tobj
->base
.dirty_images
[0]) {
625 if (IS_R600_CLASS(boml
->screen
)) {
626 drm_radeon_texture_t tex
;
627 drm_radeon_tex_image_t tmp
;
630 tex
.offset
= bo_legacy
->offset
;
632 assert(!(tex
.offset
& 1023));
636 tmp
.width
= bo
->size
;
638 tmp
.data
= bo_legacy
->ptr
;
639 tex
.format
= RADEON_TXFORMAT_ARGB8888
;
640 tex
.width
= tmp
.width
;
641 tex
.height
= tmp
.height
;
642 tex
.pitch
= bo
->size
;
644 ret
= drmCommandWriteRead(bo
->bom
->fd
,
647 sizeof(drm_radeon_texture_t
));
649 if (RADEON_DEBUG
& RADEON_IOCTL
)
650 fprintf(stderr
, "DRM_RADEON_TEXTURE: again!\n");
653 } while (ret
== -EAGAIN
);
655 /* Copy to VRAM using a blit.
656 * All memory is 4K aligned. We're using 1024 pixels wide blits.
658 drm_radeon_texture_t tex
;
659 drm_radeon_tex_image_t tmp
;
662 tex
.offset
= bo_legacy
->offset
;
664 assert(!(tex
.offset
& 1023));
668 if (bo
->size
< 4096) {
669 tmp
.width
= (bo
->size
+ 3) / 4;
673 tmp
.height
= (bo
->size
+ 4095) / 4096;
675 tmp
.data
= bo_legacy
->ptr
;
676 tex
.format
= RADEON_TXFORMAT_ARGB8888
;
677 tex
.width
= tmp
.width
;
678 tex
.height
= tmp
.height
;
679 tex
.pitch
= MAX2(tmp
.width
/ 16, 1);
681 ret
= drmCommandWriteRead(bo
->bom
->fd
,
684 sizeof(drm_radeon_texture_t
));
686 if (RADEON_DEBUG
& RADEON_IOCTL
)
687 fprintf(stderr
, "DRM_RADEON_TEXTURE: again!\n");
690 } while (ret
== -EAGAIN
);
692 bo_legacy
->dirty
= 0;
693 bo_legacy
->tobj
->base
.dirty_images
[0] = 0;
699 * radeon_bo_legacy_validate -
702 * -EINVAL - mapped buffer can't be validated
703 * -EAGAIN - restart validation we've kicked all the buffers out
705 int radeon_bo_legacy_validate(struct radeon_bo
*bo
,
709 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
710 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)boi
->bom
;
711 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
715 if (bo_legacy
->map_count
) {
716 fprintf(stderr
, "bo(%p, %d) is mapped (%d) can't valide it.\n",
717 bo
, boi
->size
, bo_legacy
->map_count
);
721 fprintf(stderr
, "bo(%p) has size 0.\n", bo
);
724 if (bo_legacy
->static_bo
|| bo_legacy
->validated
) {
725 *soffset
= bo_legacy
->offset
;
726 *eoffset
= bo_legacy
->offset
+ boi
->size
;
730 if (!(boi
->domains
& RADEON_GEM_DOMAIN_GTT
)) {
732 r
= bo_vram_validate(boi
, soffset
, eoffset
);
734 legacy_track_pending(&boml
->base
, 0);
735 legacy_kick_all_buffers(boml
);
738 fprintf(stderr
,"legacy bo: failed to get relocations into aperture\n");
745 *soffset
= bo_legacy
->offset
;
746 *eoffset
= bo_legacy
->offset
+ boi
->size
;
747 bo_legacy
->validated
= 1;
752 void radeon_bo_legacy_pending(struct radeon_bo
*bo
, uint32_t pending
)
754 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
755 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)boi
->bom
;
756 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
758 bo_legacy
->pending
= pending
;
759 bo_legacy
->is_pending
++;
760 /* add to pending list */
762 if (bo_legacy
->is_pending
> 1) {
765 bo_legacy
->pprev
= boml
->pending_bos
.pprev
;
766 bo_legacy
->pnext
= NULL
;
767 bo_legacy
->pprev
->pnext
= bo_legacy
;
768 boml
->pending_bos
.pprev
= bo_legacy
;
772 void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager
*bom
)
774 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bom
;
775 struct bo_legacy
*bo_legacy
;
780 bo_legacy
= boml
->bos
.next
;
782 struct bo_legacy
*next
;
784 next
= bo_legacy
->next
;
788 driDestroyTextureHeap(boml
->texture_heap
);
789 free(boml
->free_handles
);
793 static struct bo_legacy
*radeon_legacy_bo_alloc_static(struct bo_manager_legacy
*bom
,
797 struct bo_legacy
*bo
;
799 bo
= bo_allocate(bom
, size
, 0, RADEON_GEM_DOMAIN_VRAM
, 0);
804 bo
->offset
= offset
+ bom
->fb_location
;
805 bo
->base
.handle
= bo
->offset
;
806 bo
->ptr
= bom
->screen
->driScreen
->pFB
+ offset
;
807 if (bo
->base
.handle
> bom
->nhandle
) {
808 bom
->nhandle
= bo
->base
.handle
+ 1;
810 radeon_bo_ref((struct radeon_bo
*)&(bo
->base
));
814 struct radeon_bo_manager
*radeon_bo_manager_legacy_ctor(struct radeon_screen
*scrn
)
816 struct bo_manager_legacy
*bom
;
817 struct bo_legacy
*bo
;
820 bom
= (struct bo_manager_legacy
*)
821 calloc(1, sizeof(struct bo_manager_legacy
));
826 make_empty_list(&bom
->texture_swapped
);
828 bom
->texture_heap
= driCreateTextureHeap(0,
832 RADEON_NR_TEX_REGIONS
,
833 (drmTextureRegionPtr
)scrn
->sarea
->tex_list
[0],
834 &scrn
->sarea
->tex_age
[0],
835 &bom
->texture_swapped
,
836 sizeof(struct bo_legacy_texture_object
),
837 &bo_legacy_tobj_destroy
);
838 bom
->texture_offset
= scrn
->texOffset
[0];
840 bom
->base
.funcs
= &bo_legacy_funcs
;
841 bom
->base
.fd
= scrn
->driScreen
->fd
;
842 bom
->bos
.next
= NULL
;
843 bom
->bos
.prev
= NULL
;
844 bom
->pending_bos
.pprev
= &bom
->pending_bos
;
845 bom
->pending_bos
.pnext
= NULL
;
847 bom
->fb_location
= scrn
->fbLocation
;
849 bom
->cfree_handles
= 0;
850 bom
->nfree_handles
= 0x400;
851 bom
->free_handles
= (uint32_t*)malloc(bom
->nfree_handles
* 4);
852 if (bom
->free_handles
== NULL
) {
853 radeon_bo_manager_legacy_dtor((struct radeon_bo_manager
*)bom
);
857 /* biggest framebuffer size */
861 bo
= radeon_legacy_bo_alloc_static(bom
, size
, bom
->screen
->frontOffset
);
864 radeon_bo_manager_legacy_dtor((struct radeon_bo_manager
*)bom
);
867 if (scrn
->sarea
->tiling_enabled
) {
868 bo
->base
.flags
= RADEON_BO_FLAGS_MACRO_TILE
;
872 bo
= radeon_legacy_bo_alloc_static(bom
, size
, bom
->screen
->backOffset
);
875 radeon_bo_manager_legacy_dtor((struct radeon_bo_manager
*)bom
);
878 if (scrn
->sarea
->tiling_enabled
) {
879 bo
->base
.flags
= RADEON_BO_FLAGS_MACRO_TILE
;
883 bo
= radeon_legacy_bo_alloc_static(bom
, size
, bom
->screen
->depthOffset
);
886 radeon_bo_manager_legacy_dtor((struct radeon_bo_manager
*)bom
);
890 if (scrn
->sarea
->tiling_enabled
) {
891 bo
->base
.flags
|= RADEON_BO_FLAGS_MACRO_TILE
;
892 bo
->base
.flags
|= RADEON_BO_FLAGS_MICRO_TILE
;
894 return (struct radeon_bo_manager
*)bom
;
897 void radeon_bo_legacy_texture_age(struct radeon_bo_manager
*bom
)
899 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bom
;
900 DRI_AGE_TEXTURES(boml
->texture_heap
);
903 unsigned radeon_bo_legacy_relocs_size(struct radeon_bo
*bo
)
905 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
906 struct bo_legacy
*bo_legacy
= (struct bo_legacy
*)bo
;
908 if (bo_legacy
->static_bo
|| (boi
->domains
& RADEON_GEM_DOMAIN_GTT
)) {
915 * Fake up a bo for things like texture image_override.
916 * bo->offset already includes fb_location
918 struct radeon_bo
*radeon_legacy_bo_alloc_fake(struct radeon_bo_manager
*bom
,
922 struct bo_manager_legacy
*boml
= (struct bo_manager_legacy
*)bom
;
923 struct bo_legacy
*bo
;
925 bo
= bo_allocate(boml
, size
, 0, RADEON_GEM_DOMAIN_VRAM
, 0);
931 bo
->base
.handle
= bo
->offset
;
932 bo
->ptr
= boml
->screen
->driScreen
->pFB
+ (offset
- boml
->fb_location
);
933 if (bo
->base
.handle
> boml
->nhandle
) {
934 boml
->nhandle
= bo
->base
.handle
+ 1;
936 radeon_bo_ref((struct radeon_bo
*)&(bo
->base
));
937 return (struct radeon_bo
*)&(bo
->base
);