mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
radeon: Drop the legacy BO manager code.
This commit is contained in:
parent
976d4f58fa
commit
8c11f0a883
7 changed files with 0 additions and 988 deletions
|
|
@ -12,7 +12,6 @@ CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
|
|||
endif
|
||||
|
||||
RADEON_COMMON_SOURCES = \
|
||||
radeon_bo_legacy.c \
|
||||
radeon_buffer_objects.c \
|
||||
radeon_common_context.c \
|
||||
radeon_common.c \
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_bo_legacy.c
|
||||
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_bo_legacy.h
|
||||
|
|
@ -13,7 +13,6 @@ CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
|
|||
endif
|
||||
|
||||
RADEON_COMMON_SOURCES = \
|
||||
radeon_bo_legacy.c \
|
||||
radeon_buffer_objects.c \
|
||||
radeon_common_context.c \
|
||||
radeon_common.c \
|
||||
|
|
|
|||
|
|
@ -1,932 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Nicolai Haehnle
|
||||
* Copyright © 2008 Dave Airlie
|
||||
* Copyright © 2008 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Aapo Tahkola <aet@rasterburn.org>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
* Dave Airlie
|
||||
* Jérôme Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "xf86drm.h"
|
||||
#include "texmem.h"
|
||||
#include "main/simple_list.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_common.h"
|
||||
#include "radeon_bocs_wrapper.h"
|
||||
#include "radeon_macros.h"
|
||||
|
||||
#ifdef HAVE_LIBDRM_RADEON
|
||||
#include "radeon_bo_int.h"
|
||||
#else
|
||||
#include "radeon_bo_int_drm.h"
|
||||
#endif
|
||||
|
||||
/* no seriously texmem.c is this screwed up */
|
||||
struct bo_legacy_texture_object {
|
||||
driTextureObject base;
|
||||
struct bo_legacy *parent;
|
||||
};
|
||||
|
||||
struct bo_legacy {
|
||||
struct radeon_bo_int base;
|
||||
int map_count;
|
||||
uint32_t pending;
|
||||
int is_pending;
|
||||
int static_bo;
|
||||
uint32_t offset;
|
||||
struct bo_legacy_texture_object *tobj;
|
||||
int validated;
|
||||
int dirty;
|
||||
void *ptr;
|
||||
struct bo_legacy *next, *prev;
|
||||
struct bo_legacy *pnext, *pprev;
|
||||
};
|
||||
|
||||
struct bo_manager_legacy {
|
||||
struct radeon_bo_manager base;
|
||||
unsigned nhandle;
|
||||
unsigned nfree_handles;
|
||||
unsigned cfree_handles;
|
||||
uint32_t current_age;
|
||||
struct bo_legacy bos;
|
||||
struct bo_legacy pending_bos;
|
||||
uint32_t fb_location;
|
||||
uint32_t texture_offset;
|
||||
unsigned dma_alloc_size;
|
||||
uint32_t dma_buf_count;
|
||||
unsigned cpendings;
|
||||
driTextureObject texture_swapped;
|
||||
driTexHeap *texture_heap;
|
||||
struct radeon_screen *screen;
|
||||
unsigned *free_handles;
|
||||
};
|
||||
|
||||
static void bo_legacy_tobj_destroy(void *data, driTextureObject *t)
|
||||
{
|
||||
struct bo_legacy_texture_object *tobj = (struct bo_legacy_texture_object *)t;
|
||||
|
||||
if (tobj->parent) {
|
||||
tobj->parent->tobj = NULL;
|
||||
tobj->parent->validated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void inline clean_handles(struct bo_manager_legacy *bom)
|
||||
{
|
||||
while (bom->cfree_handles > 0 &&
|
||||
!bom->free_handles[bom->cfree_handles - 1])
|
||||
bom->cfree_handles--;
|
||||
|
||||
}
|
||||
static int legacy_new_handle(struct bo_manager_legacy *bom, uint32_t *handle)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
*handle = 0;
|
||||
if (bom->nhandle == 0xFFFFFFFF) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bom->cfree_handles > 0) {
|
||||
tmp = bom->free_handles[--bom->cfree_handles];
|
||||
clean_handles(bom);
|
||||
} else {
|
||||
bom->cfree_handles = 0;
|
||||
tmp = bom->nhandle++;
|
||||
}
|
||||
assert(tmp);
|
||||
*handle = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int legacy_free_handle(struct bo_manager_legacy *bom, uint32_t handle)
|
||||
{
|
||||
uint32_t *handles;
|
||||
|
||||
if (!handle) {
|
||||
return 0;
|
||||
}
|
||||
if (handle == (bom->nhandle - 1)) {
|
||||
int i;
|
||||
|
||||
bom->nhandle--;
|
||||
for (i = bom->cfree_handles - 1; i >= 0; i--) {
|
||||
if (bom->free_handles[i] == (bom->nhandle - 1)) {
|
||||
bom->nhandle--;
|
||||
bom->free_handles[i] = 0;
|
||||
}
|
||||
}
|
||||
clean_handles(bom);
|
||||
return 0;
|
||||
}
|
||||
if (bom->cfree_handles < bom->nfree_handles) {
|
||||
bom->free_handles[bom->cfree_handles++] = handle;
|
||||
return 0;
|
||||
}
|
||||
bom->nfree_handles += 0x100;
|
||||
handles = (uint32_t*)realloc(bom->free_handles, bom->nfree_handles * 4);
|
||||
if (handles == NULL) {
|
||||
bom->nfree_handles -= 0x100;
|
||||
return -ENOMEM;
|
||||
}
|
||||
bom->free_handles = handles;
|
||||
bom->free_handles[bom->cfree_handles++] = handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void legacy_get_current_age(struct bo_manager_legacy *boml)
|
||||
{
|
||||
drm_radeon_getparam_t gp;
|
||||
unsigned char *RADEONMMIO = NULL;
|
||||
int r;
|
||||
|
||||
if ( IS_R300_CLASS(boml->screen)
|
||||
|| IS_R600_CLASS(boml->screen) )
|
||||
{
|
||||
gp.param = RADEON_PARAM_LAST_CLEAR;
|
||||
gp.value = (int *)&boml->current_age;
|
||||
r = drmCommandWriteRead(boml->base.fd, DRM_RADEON_GETPARAM,
|
||||
&gp, sizeof(gp));
|
||||
if (r) {
|
||||
fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
RADEONMMIO = boml->screen->mmio.map;
|
||||
boml->current_age = boml->screen->scratch[3];
|
||||
boml->current_age = INREG(RADEON_GUI_SCRATCH_REG3);
|
||||
}
|
||||
}
|
||||
|
||||
static int legacy_is_pending(struct radeon_bo_int *boi)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
|
||||
|
||||
if (bo_legacy->is_pending <= 0) {
|
||||
bo_legacy->is_pending = 0;
|
||||
return 0;
|
||||
}
|
||||
if (boml->current_age >= bo_legacy->pending) {
|
||||
if (boml->pending_bos.pprev == bo_legacy) {
|
||||
boml->pending_bos.pprev = bo_legacy->pprev;
|
||||
}
|
||||
bo_legacy->pprev->pnext = bo_legacy->pnext;
|
||||
if (bo_legacy->pnext) {
|
||||
bo_legacy->pnext->pprev = bo_legacy->pprev;
|
||||
}
|
||||
assert(bo_legacy->is_pending <= boi->cref);
|
||||
while (bo_legacy->is_pending--) {
|
||||
boi = (struct radeon_bo_int *)radeon_bo_unref((struct radeon_bo *)boi);
|
||||
if (!boi)
|
||||
break;
|
||||
}
|
||||
if (boi)
|
||||
bo_legacy->is_pending = 0;
|
||||
boml->cpendings--;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int legacy_wait_pending(struct radeon_bo_int *bo)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
|
||||
if (!bo_legacy->is_pending) {
|
||||
return 0;
|
||||
}
|
||||
/* FIXME: lockup and userspace busy looping that's all the folks */
|
||||
legacy_get_current_age(boml);
|
||||
while (legacy_is_pending(bo)) {
|
||||
usleep(10);
|
||||
legacy_get_current_age(boml);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void legacy_track_pending(struct radeon_bo_manager *bom, int debug)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy*) bom;
|
||||
struct bo_legacy *bo_legacy;
|
||||
struct bo_legacy *next;
|
||||
|
||||
legacy_get_current_age(boml);
|
||||
bo_legacy = boml->pending_bos.pnext;
|
||||
while (bo_legacy) {
|
||||
if (debug)
|
||||
fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
|
||||
boml->current_age, bo_legacy->pending);
|
||||
next = bo_legacy->pnext;
|
||||
if (legacy_is_pending(&(bo_legacy->base))) {
|
||||
}
|
||||
bo_legacy = next;
|
||||
}
|
||||
}
|
||||
|
||||
static int legacy_wait_any_pending(struct bo_manager_legacy *boml)
|
||||
{
|
||||
struct bo_legacy *bo_legacy;
|
||||
|
||||
legacy_get_current_age(boml);
|
||||
bo_legacy = boml->pending_bos.pnext;
|
||||
if (!bo_legacy)
|
||||
return -1;
|
||||
legacy_wait_pending(&bo_legacy->base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void legacy_kick_all_buffers(struct bo_manager_legacy *boml)
|
||||
{
|
||||
struct bo_legacy *legacy;
|
||||
|
||||
legacy = boml->bos.next;
|
||||
while (legacy != &boml->bos) {
|
||||
if (legacy->tobj) {
|
||||
if (legacy->validated) {
|
||||
driDestroyTextureObject(&legacy->tobj->base);
|
||||
legacy->tobj = 0;
|
||||
legacy->validated = 0;
|
||||
}
|
||||
}
|
||||
legacy = legacy->next;
|
||||
}
|
||||
}
|
||||
|
||||
static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
|
||||
uint32_t size,
|
||||
uint32_t alignment,
|
||||
uint32_t domains,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct bo_legacy *bo_legacy;
|
||||
static int pgsize;
|
||||
|
||||
if (pgsize == 0)
|
||||
pgsize = getpagesize() - 1;
|
||||
|
||||
size = (size + pgsize) & ~pgsize;
|
||||
|
||||
bo_legacy = (struct bo_legacy*)calloc(1, sizeof(struct bo_legacy));
|
||||
if (bo_legacy == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
bo_legacy->base.bom = (struct radeon_bo_manager*)boml;
|
||||
bo_legacy->base.handle = 0;
|
||||
bo_legacy->base.size = size;
|
||||
bo_legacy->base.alignment = alignment;
|
||||
bo_legacy->base.domains = domains;
|
||||
bo_legacy->base.flags = flags;
|
||||
bo_legacy->base.ptr = NULL;
|
||||
bo_legacy->map_count = 0;
|
||||
bo_legacy->next = NULL;
|
||||
bo_legacy->prev = NULL;
|
||||
bo_legacy->pnext = NULL;
|
||||
bo_legacy->pprev = NULL;
|
||||
bo_legacy->next = boml->bos.next;
|
||||
bo_legacy->prev = &boml->bos;
|
||||
boml->bos.next = bo_legacy;
|
||||
if (bo_legacy->next) {
|
||||
bo_legacy->next->prev = bo_legacy;
|
||||
}
|
||||
|
||||
return bo_legacy;
|
||||
}
|
||||
|
||||
static int bo_dma_alloc(struct radeon_bo_int *bo)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
drm_radeon_mem_alloc_t alloc;
|
||||
unsigned size;
|
||||
int base_offset;
|
||||
int r;
|
||||
|
||||
/* align size on 4Kb */
|
||||
size = (((4 * 1024) - 1) + bo_legacy->base.size) & ~((4 * 1024) - 1);
|
||||
alloc.region = RADEON_MEM_REGION_GART;
|
||||
alloc.alignment = bo_legacy->base.alignment;
|
||||
alloc.size = size;
|
||||
alloc.region_offset = &base_offset;
|
||||
r = drmCommandWriteRead(bo->bom->fd,
|
||||
DRM_RADEON_ALLOC,
|
||||
&alloc,
|
||||
sizeof(alloc));
|
||||
if (r) {
|
||||
/* ptr is set to NULL if dma allocation failed */
|
||||
bo_legacy->ptr = NULL;
|
||||
return r;
|
||||
}
|
||||
bo_legacy->ptr = boml->screen->gartTextures.map + base_offset;
|
||||
bo_legacy->offset = boml->screen->gart_texture_offset + base_offset;
|
||||
bo->size = size;
|
||||
boml->dma_alloc_size += size;
|
||||
boml->dma_buf_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bo_dma_free(struct radeon_bo_int *bo)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
drm_radeon_mem_free_t memfree;
|
||||
int r;
|
||||
|
||||
if (bo_legacy->ptr == NULL) {
|
||||
/* ptr is set to NULL if dma allocation failed */
|
||||
return 0;
|
||||
}
|
||||
legacy_get_current_age(boml);
|
||||
memfree.region = RADEON_MEM_REGION_GART;
|
||||
memfree.region_offset = bo_legacy->offset;
|
||||
memfree.region_offset -= boml->screen->gart_texture_offset;
|
||||
r = drmCommandWrite(boml->base.fd,
|
||||
DRM_RADEON_FREE,
|
||||
&memfree,
|
||||
sizeof(memfree));
|
||||
if (r) {
|
||||
fprintf(stderr, "Failed to free bo[%p] at %08x\n",
|
||||
&bo_legacy->base, memfree.region_offset);
|
||||
fprintf(stderr, "ret = %s\n", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
boml->dma_alloc_size -= bo_legacy->base.size;
|
||||
boml->dma_buf_count--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bo_free(struct bo_legacy *bo_legacy)
|
||||
{
|
||||
struct bo_manager_legacy *boml;
|
||||
|
||||
if (bo_legacy == NULL) {
|
||||
return;
|
||||
}
|
||||
boml = (struct bo_manager_legacy *)bo_legacy->base.bom;
|
||||
bo_legacy->prev->next = bo_legacy->next;
|
||||
if (bo_legacy->next) {
|
||||
bo_legacy->next->prev = bo_legacy->prev;
|
||||
}
|
||||
if (!bo_legacy->static_bo) {
|
||||
legacy_free_handle(boml, bo_legacy->base.handle);
|
||||
if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) {
|
||||
/* dma buffers */
|
||||
bo_dma_free(&bo_legacy->base);
|
||||
} else {
|
||||
driDestroyTextureObject(&bo_legacy->tobj->base);
|
||||
bo_legacy->tobj = NULL;
|
||||
/* free backing store */
|
||||
free(bo_legacy->ptr);
|
||||
}
|
||||
}
|
||||
memset(bo_legacy, 0 , sizeof(struct bo_legacy));
|
||||
free(bo_legacy);
|
||||
}
|
||||
|
||||
static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
|
||||
uint32_t handle,
|
||||
uint32_t size,
|
||||
uint32_t alignment,
|
||||
uint32_t domains,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
|
||||
struct bo_legacy *bo_legacy;
|
||||
int r;
|
||||
|
||||
if (handle) {
|
||||
bo_legacy = boml->bos.next;
|
||||
while (bo_legacy) {
|
||||
if (bo_legacy->base.handle == handle) {
|
||||
radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
|
||||
return (struct radeon_bo*)bo_legacy;
|
||||
}
|
||||
bo_legacy = bo_legacy->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bo_legacy = bo_allocate(boml, size, alignment, domains, flags);
|
||||
bo_legacy->static_bo = 0;
|
||||
r = legacy_new_handle(boml, &bo_legacy->base.handle);
|
||||
if (r) {
|
||||
bo_free(bo_legacy);
|
||||
return NULL;
|
||||
}
|
||||
if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT)
|
||||
{
|
||||
retry:
|
||||
legacy_track_pending(&boml->base, 0);
|
||||
/* dma buffers */
|
||||
|
||||
r = bo_dma_alloc(&(bo_legacy->base));
|
||||
if (r)
|
||||
{
|
||||
if (legacy_wait_any_pending(boml) == -1)
|
||||
{
|
||||
bo_free(bo_legacy);
|
||||
return NULL;
|
||||
}
|
||||
goto retry;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bo_legacy->ptr = malloc(bo_legacy->base.size);
|
||||
if (bo_legacy->ptr == NULL) {
|
||||
bo_free(bo_legacy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
|
||||
|
||||
return (struct radeon_bo*)bo_legacy;
|
||||
}
|
||||
|
||||
static void bo_ref(struct radeon_bo_int *bo)
|
||||
{
|
||||
}
|
||||
|
||||
static struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
|
||||
{
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
|
||||
|
||||
if (boi->cref <= 0) {
|
||||
bo_legacy->prev->next = bo_legacy->next;
|
||||
if (bo_legacy->next) {
|
||||
bo_legacy->next->prev = bo_legacy->prev;
|
||||
}
|
||||
if (!bo_legacy->is_pending) {
|
||||
bo_free(bo_legacy);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return (struct radeon_bo *)boi;
|
||||
}
|
||||
|
||||
static int bo_map(struct radeon_bo_int *bo, int write)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
|
||||
legacy_wait_pending(bo);
|
||||
bo_legacy->validated = 0;
|
||||
bo_legacy->dirty = 1;
|
||||
bo_legacy->map_count++;
|
||||
bo->ptr = bo_legacy->ptr;
|
||||
/* Read the first pixel in the frame buffer. This should
|
||||
* be a noop, right? In fact without this conform fails as reading
|
||||
* from the framebuffer sometimes produces old results -- the
|
||||
* on-card read cache gets mixed up and doesn't notice that the
|
||||
* framebuffer has been updated.
|
||||
*
|
||||
* Note that we should probably be reading some otherwise unused
|
||||
* region of VRAM, otherwise we might get incorrect results when
|
||||
* reading pixels from the top left of the screen.
|
||||
*
|
||||
* I found this problem on an R420 with glean's texCube test.
|
||||
* Note that the R200 span code also *writes* the first pixel in the
|
||||
* framebuffer, but I've found this to be unnecessary.
|
||||
* -- Nicolai Hähnle, June 2008
|
||||
*/
|
||||
if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) {
|
||||
int p;
|
||||
volatile int *buf = (int*)boml->screen->driScreen->pFB;
|
||||
p = *buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bo_unmap(struct radeon_bo_int *bo)
|
||||
{
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
|
||||
if (--bo_legacy->map_count > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bo->ptr = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bo_is_busy(struct radeon_bo_int *bo, uint32_t *domain)
|
||||
{
|
||||
*domain = 0;
|
||||
if (bo->domains & RADEON_GEM_DOMAIN_GTT)
|
||||
*domain = RADEON_GEM_DOMAIN_GTT;
|
||||
else
|
||||
*domain = RADEON_GEM_DOMAIN_CPU;
|
||||
if (legacy_is_pending(bo))
|
||||
return -EBUSY;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bo_is_static(struct radeon_bo_int *bo)
|
||||
{
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
return bo_legacy->static_bo;
|
||||
}
|
||||
|
||||
static struct radeon_bo_funcs bo_legacy_funcs = {
|
||||
bo_open,
|
||||
bo_ref,
|
||||
bo_unref,
|
||||
bo_map,
|
||||
bo_unmap,
|
||||
NULL,
|
||||
bo_is_static,
|
||||
NULL,
|
||||
NULL,
|
||||
bo_is_busy
|
||||
};
|
||||
|
||||
static int bo_vram_validate(struct radeon_bo_int *bo,
|
||||
uint32_t *soffset,
|
||||
uint32_t *eoffset)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
int r;
|
||||
int retry_count = 0, pending_retry = 0;
|
||||
|
||||
if (!bo_legacy->tobj) {
|
||||
bo_legacy->tobj = CALLOC(sizeof(struct bo_legacy_texture_object));
|
||||
bo_legacy->tobj->parent = bo_legacy;
|
||||
make_empty_list(&bo_legacy->tobj->base);
|
||||
bo_legacy->tobj->base.totalSize = bo->size;
|
||||
retry:
|
||||
r = driAllocateTexture(&boml->texture_heap, 1,
|
||||
&bo_legacy->tobj->base);
|
||||
if (r) {
|
||||
pending_retry = 0;
|
||||
while(boml->cpendings && pending_retry++ < 10000) {
|
||||
legacy_track_pending(&boml->base, 0);
|
||||
retry_count++;
|
||||
if (retry_count > 2) {
|
||||
free(bo_legacy->tobj);
|
||||
bo_legacy->tobj = NULL;
|
||||
fprintf(stderr, "Ouch! vram_validate failed %d\n", r);
|
||||
return -1;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
bo_legacy->offset = boml->texture_offset +
|
||||
bo_legacy->tobj->base.memBlock->ofs;
|
||||
bo_legacy->dirty = 1;
|
||||
}
|
||||
|
||||
assert(bo_legacy->tobj->base.memBlock);
|
||||
|
||||
driUpdateTextureLRU(&bo_legacy->tobj->base);
|
||||
|
||||
if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) {
|
||||
if (IS_R600_CLASS(boml->screen)) {
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
int ret;
|
||||
|
||||
tex.offset = bo_legacy->offset;
|
||||
tex.image = &tmp;
|
||||
assert(!(tex.offset & 1023));
|
||||
|
||||
tmp.x = 0;
|
||||
tmp.y = 0;
|
||||
tmp.width = bo->size;
|
||||
tmp.height = 1;
|
||||
tmp.data = bo_legacy->ptr;
|
||||
tex.format = RADEON_TXFORMAT_ARGB8888;
|
||||
tex.width = tmp.width;
|
||||
tex.height = tmp.height;
|
||||
tex.pitch = bo->size;
|
||||
do {
|
||||
ret = drmCommandWriteRead(bo->bom->fd,
|
||||
DRM_RADEON_TEXTURE,
|
||||
&tex,
|
||||
sizeof(drm_radeon_texture_t));
|
||||
if (ret) {
|
||||
if (RADEON_DEBUG & RADEON_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while (ret == -EAGAIN);
|
||||
} else {
|
||||
/* Copy to VRAM using a blit.
|
||||
* All memory is 4K aligned. We're using 1024 pixels wide blits.
|
||||
*/
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
int ret;
|
||||
|
||||
tex.offset = bo_legacy->offset;
|
||||
tex.image = &tmp;
|
||||
assert(!(tex.offset & 1023));
|
||||
|
||||
tmp.x = 0;
|
||||
tmp.y = 0;
|
||||
if (bo->size < 4096) {
|
||||
tmp.width = (bo->size + 3) / 4;
|
||||
tmp.height = 1;
|
||||
} else {
|
||||
tmp.width = 1024;
|
||||
tmp.height = (bo->size + 4095) / 4096;
|
||||
}
|
||||
tmp.data = bo_legacy->ptr;
|
||||
tex.format = RADEON_TXFORMAT_ARGB8888;
|
||||
tex.width = tmp.width;
|
||||
tex.height = tmp.height;
|
||||
tex.pitch = MAX2(tmp.width / 16, 1);
|
||||
do {
|
||||
ret = drmCommandWriteRead(bo->bom->fd,
|
||||
DRM_RADEON_TEXTURE,
|
||||
&tex,
|
||||
sizeof(drm_radeon_texture_t));
|
||||
if (ret) {
|
||||
if (RADEON_DEBUG & RADEON_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while (ret == -EAGAIN);
|
||||
}
|
||||
bo_legacy->dirty = 0;
|
||||
bo_legacy->tobj->base.dirty_images[0] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* radeon_bo_legacy_validate -
|
||||
* returns:
|
||||
* 0 - all good
|
||||
* -EINVAL - mapped buffer can't be validated
|
||||
* -EAGAIN - restart validation we've kicked all the buffers out
|
||||
*/
|
||||
int radeon_bo_legacy_validate(struct radeon_bo *bo,
|
||||
uint32_t *soffset,
|
||||
uint32_t *eoffset)
|
||||
{
|
||||
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
int r;
|
||||
int retries = 0;
|
||||
|
||||
if (bo_legacy->map_count) {
|
||||
fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
|
||||
bo, boi->size, bo_legacy->map_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
if(boi->size == 0) {
|
||||
fprintf(stderr, "bo(%p) has size 0.\n", bo);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bo_legacy->static_bo || bo_legacy->validated) {
|
||||
*soffset = bo_legacy->offset;
|
||||
*eoffset = bo_legacy->offset + boi->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (!(boi->domains & RADEON_GEM_DOMAIN_GTT)) {
|
||||
|
||||
r = bo_vram_validate(boi, soffset, eoffset);
|
||||
if (r) {
|
||||
legacy_track_pending(&boml->base, 0);
|
||||
legacy_kick_all_buffers(boml);
|
||||
retries++;
|
||||
if (retries == 2) {
|
||||
fprintf(stderr,"legacy bo: failed to get relocations into aperture\n");
|
||||
assert(0);
|
||||
exit(-1);
|
||||
}
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
*soffset = bo_legacy->offset;
|
||||
*eoffset = bo_legacy->offset + boi->size;
|
||||
bo_legacy->validated = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending)
|
||||
{
|
||||
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
|
||||
bo_legacy->pending = pending;
|
||||
bo_legacy->is_pending++;
|
||||
/* add to pending list */
|
||||
radeon_bo_ref(bo);
|
||||
if (bo_legacy->is_pending > 1) {
|
||||
return;
|
||||
}
|
||||
bo_legacy->pprev = boml->pending_bos.pprev;
|
||||
bo_legacy->pnext = NULL;
|
||||
bo_legacy->pprev->pnext = bo_legacy;
|
||||
boml->pending_bos.pprev = bo_legacy;
|
||||
boml->cpendings++;
|
||||
}
|
||||
|
||||
void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
|
||||
struct bo_legacy *bo_legacy;
|
||||
|
||||
if (bom == NULL) {
|
||||
return;
|
||||
}
|
||||
bo_legacy = boml->bos.next;
|
||||
while (bo_legacy) {
|
||||
struct bo_legacy *next;
|
||||
|
||||
next = bo_legacy->next;
|
||||
bo_free(bo_legacy);
|
||||
bo_legacy = next;
|
||||
}
|
||||
driDestroyTextureHeap(boml->texture_heap);
|
||||
free(boml->free_handles);
|
||||
free(boml);
|
||||
}
|
||||
|
||||
static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy *bom,
|
||||
int size,
|
||||
uint32_t offset)
|
||||
{
|
||||
struct bo_legacy *bo;
|
||||
|
||||
bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
if (bo == NULL)
|
||||
return NULL;
|
||||
bo->static_bo = 1;
|
||||
bo->offset = offset + bom->fb_location;
|
||||
bo->base.handle = bo->offset;
|
||||
bo->ptr = bom->screen->driScreen->pFB + offset;
|
||||
if (bo->base.handle > bom->nhandle) {
|
||||
bom->nhandle = bo->base.handle + 1;
|
||||
}
|
||||
radeon_bo_ref((struct radeon_bo *)&(bo->base));
|
||||
return bo;
|
||||
}
|
||||
|
||||
struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn)
|
||||
{
|
||||
struct bo_manager_legacy *bom;
|
||||
struct bo_legacy *bo;
|
||||
unsigned size;
|
||||
|
||||
bom = (struct bo_manager_legacy*)
|
||||
calloc(1, sizeof(struct bo_manager_legacy));
|
||||
if (bom == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
make_empty_list(&bom->texture_swapped);
|
||||
|
||||
bom->texture_heap = driCreateTextureHeap(0,
|
||||
bom,
|
||||
scrn->texSize[0],
|
||||
12,
|
||||
RADEON_NR_TEX_REGIONS,
|
||||
(drmTextureRegionPtr)scrn->sarea->tex_list[0],
|
||||
&scrn->sarea->tex_age[0],
|
||||
&bom->texture_swapped,
|
||||
sizeof(struct bo_legacy_texture_object),
|
||||
&bo_legacy_tobj_destroy);
|
||||
bom->texture_offset = scrn->texOffset[0];
|
||||
|
||||
bom->base.funcs = &bo_legacy_funcs;
|
||||
bom->base.fd = scrn->driScreen->fd;
|
||||
bom->bos.next = NULL;
|
||||
bom->bos.prev = NULL;
|
||||
bom->pending_bos.pprev = &bom->pending_bos;
|
||||
bom->pending_bos.pnext = NULL;
|
||||
bom->screen = scrn;
|
||||
bom->fb_location = scrn->fbLocation;
|
||||
bom->nhandle = 1;
|
||||
bom->cfree_handles = 0;
|
||||
bom->nfree_handles = 0x400;
|
||||
bom->free_handles = (uint32_t*)malloc(bom->nfree_handles * 4);
|
||||
if (bom->free_handles == NULL) {
|
||||
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* biggest framebuffer size */
|
||||
size = 4096*4096*4;
|
||||
|
||||
/* allocate front */
|
||||
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset);
|
||||
|
||||
if (!bo) {
|
||||
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
||||
return NULL;
|
||||
}
|
||||
if (scrn->sarea->tiling_enabled) {
|
||||
bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
|
||||
}
|
||||
|
||||
/* allocate back */
|
||||
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset);
|
||||
|
||||
if (!bo) {
|
||||
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
||||
return NULL;
|
||||
}
|
||||
if (scrn->sarea->tiling_enabled) {
|
||||
bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
|
||||
}
|
||||
|
||||
/* allocate depth */
|
||||
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset);
|
||||
|
||||
if (!bo) {
|
||||
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
||||
return NULL;
|
||||
}
|
||||
bo->base.flags = 0;
|
||||
if (scrn->sarea->tiling_enabled) {
|
||||
bo->base.flags |= RADEON_BO_FLAGS_MACRO_TILE;
|
||||
bo->base.flags |= RADEON_BO_FLAGS_MICRO_TILE;
|
||||
}
|
||||
return (struct radeon_bo_manager*)bom;
|
||||
}
|
||||
|
||||
unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
|
||||
{
|
||||
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
|
||||
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
||||
|
||||
if (bo_legacy->static_bo || (boi->domains & RADEON_GEM_DOMAIN_GTT)) {
|
||||
return 0;
|
||||
}
|
||||
return boi->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fake up a bo for things like texture image_override.
|
||||
* bo->offset already includes fb_location
|
||||
*/
|
||||
struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
|
||||
int size,
|
||||
uint32_t offset)
|
||||
{
|
||||
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
|
||||
struct bo_legacy *bo;
|
||||
|
||||
bo = bo_allocate(boml, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
if (bo == NULL)
|
||||
return NULL;
|
||||
bo->static_bo = 1;
|
||||
bo->offset = offset;
|
||||
bo->base.handle = bo->offset;
|
||||
bo->ptr = boml->screen->driScreen->pFB + (offset - boml->fb_location);
|
||||
if (bo->base.handle > boml->nhandle) {
|
||||
boml->nhandle = bo->base.handle + 1;
|
||||
}
|
||||
radeon_bo_ref((struct radeon_bo *)&(bo->base));
|
||||
return (struct radeon_bo *)&(bo->base);
|
||||
}
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Nicolai Haehnle
|
||||
* Copyright © 2008 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Aapo Tahkola <aet@rasterburn.org>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
* Jérôme Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#ifndef RADEON_BO_LEGACY_H
|
||||
#define RADEON_BO_LEGACY_H
|
||||
|
||||
#include "radeon_screen.h"
|
||||
|
||||
void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending);
|
||||
int radeon_bo_legacy_validate(struct radeon_bo *bo,
|
||||
uint32_t *soffset,
|
||||
uint32_t *eoffset);
|
||||
struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn);
|
||||
void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom);
|
||||
void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom);
|
||||
unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo);
|
||||
struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
|
||||
int size,
|
||||
uint32_t offset);
|
||||
void legacy_track_pending(struct radeon_bo_manager *bom, int debug);
|
||||
|
||||
#endif
|
||||
|
|
@ -105,6 +105,4 @@ static inline void radeon_tracker_print(void *ptr, int io)
|
|||
}
|
||||
#endif
|
||||
|
||||
#include "radeon_bo_legacy.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue