diff options
author | Marek Olšák <[email protected]> | 2010-12-23 19:40:54 +1000 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2011-02-11 01:07:25 +0100 |
commit | 6ccab620a0e7364ab6c0d902b3ddf58ee988f7fa (patch) | |
tree | 6228427e261efd6187915ab651b78f99d3ff7dd1 /src/gallium/winsys | |
parent | c0beaf6e6d5764531a4cb21d0d0a9a1fd09affee (diff) |
r300g: import the last bits of libdrm and cleanup the whole thing
Based on Dave's branch.
The majority of this commit is a cleanup, mainly renaming things.
There wasn't much code to import, just ioctl calls.
Also done:
- implemented unsynchronized bo_map (important optimization!)
- radeon_bo_is_referenced_by_cs is no longer a refcount hack
- dropped the libdrm_radeon dependency
I'm surprised that this has resulted in less code in the end.
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r-- | src/gallium/winsys/radeon/drm/Makefile | 5 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/SConscript | 3 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 543 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_bo.h (renamed from src/gallium/winsys/radeon/drm/radeon_drm_buffer.h) | 45 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_buffer.c | 535 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_common.c | 58 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 27 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_cs.h | 15 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_r300.c | 181 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_winsys.h | 3 |
10 files changed, 653 insertions, 762 deletions
diff --git a/src/gallium/winsys/radeon/drm/Makefile b/src/gallium/winsys/radeon/drm/Makefile index 7e339a2ecfe..e63ae6f5006 100644 --- a/src/gallium/winsys/radeon/drm/Makefile +++ b/src/gallium/winsys/radeon/drm/Makefile @@ -5,10 +5,9 @@ include $(TOP)/configs/current LIBNAME = radeonwinsys C_SOURCES = \ - radeon_drm_buffer.c \ + radeon_drm_bo.c \ radeon_drm_cs.c \ - radeon_drm_common.c \ - radeon_r300.c + radeon_drm_common.c LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \ $(shell pkg-config libdrm --cflags-only-I) diff --git a/src/gallium/winsys/radeon/drm/SConscript b/src/gallium/winsys/radeon/drm/SConscript index 4ddb0919f6a..b16e03556d3 100644 --- a/src/gallium/winsys/radeon/drm/SConscript +++ b/src/gallium/winsys/radeon/drm/SConscript @@ -3,10 +3,9 @@ Import('*') env = env.Clone() radeon_sources = [ - 'radeon_drm_buffer.c', + 'radeon_drm_bo.c', 'radeon_drm_cs.c', 'radeon_drm_common.c', - 'radeon_r300.c', ] try: diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c new file mode 100644 index 00000000000..1a7804fc6ac --- /dev/null +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -0,0 +1,543 @@ +#define _FILE_OFFSET_BITS 64 +#include "radeon_drm_cs.h" + +#include "util/u_hash_table.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" +#include "os/os_thread.h" + +#include "state_tracker/drm_driver.h" + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <xf86drm.h> +#include <errno.h> + +#define RADEON_BO_FLAGS_MACRO_TILE 1 +#define RADEON_BO_FLAGS_MICRO_TILE 2 +#define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20 + +extern const struct pb_vtbl radeon_bo_vtbl; + + +static INLINE struct radeon_bo *radeon_bo(struct pb_buffer *bo) +{ + assert(bo->vtbl == &radeon_bo_vtbl); + return (struct radeon_bo *)bo; +} + +struct radeon_bomgr { + /* Base class. */ + struct pb_manager base; + + /* Winsys. */ + struct radeon_drm_winsys *rws; + + /* List of buffer handles and its mutex. */ + struct util_hash_table *bo_handles; + pipe_mutex bo_handles_mutex; +}; + +static INLINE struct radeon_bomgr *radeon_bomgr(struct pb_manager *mgr) +{ + return (struct radeon_bomgr *)mgr; +} + +static struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf) +{ + struct radeon_bo *bo = NULL; + + if (_buf->vtbl == &radeon_bo_vtbl) { + bo = radeon_bo(_buf); + } else { + struct pb_buffer *base_buf; + pb_size offset; + pb_get_base_buffer(_buf, &base_buf, &offset); + + if (base_buf->vtbl == &radeon_bo_vtbl) + bo = radeon_bo(base_buf); + } + + return bo; +} + +void radeon_bo_unref(struct radeon_bo *bo) +{ + struct drm_gem_close args = {}; + + if (!p_atomic_dec_zero(&bo->cref)) + return; + + if (bo->name) { + pipe_mutex_lock(bo->mgr->bo_handles_mutex); + util_hash_table_remove(bo->mgr->bo_handles, + (void*)(uintptr_t)bo->name); + pipe_mutex_unlock(bo->mgr->bo_handles_mutex); + } + + if (bo->ptr) + munmap(bo->ptr, bo->size); + + /* Close object. */ + args.handle = bo->handle; + drmIoctl(bo->mgr->rws->fd, DRM_IOCTL_GEM_CLOSE, &args); + FREE(bo); +} + +static void radeon_bo_wait(struct r300_winsys_bo *_buf) +{ + struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); + struct drm_radeon_gem_wait_idle args = {}; + + args.handle = bo->handle; + while (drmCommandWriteRead(bo->mgr->rws->fd, DRM_RADEON_GEM_WAIT_IDLE, + &args, sizeof(args)) == -EBUSY); +} + +static boolean radeon_bo_is_busy(struct r300_winsys_bo *_buf) +{ + struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); + struct drm_radeon_gem_busy args = {}; + + args.handle = bo->handle; + return drmCommandWriteRead(bo->mgr->rws->fd, DRM_RADEON_GEM_BUSY, + &args, sizeof(args)) != 0; +} + +static void radeon_bo_destroy(struct pb_buffer *_buf) +{ + struct radeon_bo *bo = radeon_bo(_buf); + + radeon_bo_unref(bo); +} + +static unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage) +{ + unsigned res = 0; + + if (usage & PIPE_TRANSFER_READ) + res |= PB_USAGE_CPU_READ; + + if (usage & PIPE_TRANSFER_WRITE) + res |= PB_USAGE_CPU_WRITE; + + if (usage & PIPE_TRANSFER_DONTBLOCK) + res |= PB_USAGE_DONTBLOCK; + + if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) + res |= PB_USAGE_UNSYNCHRONIZED; + + return res; +} + +static void *radeon_bo_map_internal(struct pb_buffer *_buf, + unsigned flags, void *flush_ctx) +{ + struct radeon_bo *bo = radeon_bo(_buf); + struct radeon_drm_cs *cs = flush_ctx; + struct drm_radeon_gem_mmap args = {}; + + if (flags & PB_USAGE_DONTBLOCK) { + /* Note how we use radeon_bo_is_referenced_by_cs here. There are + * basically two places this map function can be called from: + * - pb_map + * - create_buffer (in the buffer reuse case) + * + * Since pb managers are per-winsys managers, not per-context managers, + * and we shouldn't reuse buffers if they are in-use in any context, + * we simply ask: is this buffer referenced by *any* CS? + * + * The problem with buffer_create is that it comes from pipe_screen, + * so we have no CS to look at, though luckily the following code + * is sufficient to tell whether the buffer is in use. */ + if (_buf->base.usage & RADEON_PB_USAGE_CACHE) { + if (radeon_bo_is_referenced_by_any_cs(bo)) + return NULL; + } + + if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) { + cs->flush_cs(cs->flush_data); + return NULL; /* It's very unlikely that the buffer is not busy. */ + } + + if (radeon_bo_is_busy((struct r300_winsys_bo*)bo)) { + return NULL; + } + } + + /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */ + if (!(flags & PB_USAGE_UNSYNCHRONIZED)) { + if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) { + cs->flush_cs(cs->flush_data); + } + + radeon_bo_wait((struct r300_winsys_bo*)bo); + } + + /* Map buffer if it's not already mapped. */ + /* XXX We may get a race in bo->ptr. */ + if (!bo->ptr) { + void *ptr; + + args.handle = bo->handle; + args.offset = 0; + args.size = (uint64_t)bo->size; + if (drmCommandWriteRead(bo->mgr->rws->fd, + DRM_RADEON_GEM_MMAP, + &args, + sizeof(args))) { + fprintf(stderr, "radeon: gem_mmap failed: %p 0x%08X\n", + bo, bo->handle); + return NULL; + } + ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, + bo->mgr->rws->fd, args.addr_ptr); + if (ptr == MAP_FAILED) { + fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno); + return NULL; + } + bo->ptr = ptr; + } + + return bo->ptr; +} + +static void radeon_bo_unmap_internal(struct pb_buffer *_buf) +{ + /* NOP */ +} + +static void radeon_bo_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + +static enum pipe_error radeon_bo_validate(struct pb_buffer *_buf, + struct pb_validate *vl, + unsigned flags) +{ + /* Always pinned */ + return PIPE_OK; +} + +static void radeon_bo_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ +} + +const struct pb_vtbl radeon_bo_vtbl = { + radeon_bo_destroy, + radeon_bo_map_internal, + radeon_bo_unmap_internal, + radeon_bo_validate, + radeon_bo_fence, + radeon_bo_get_base_buffer, +}; + +static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr, + pb_size size, + const struct pb_desc *desc) +{ + struct radeon_bomgr *mgr = radeon_bomgr(_mgr); + struct radeon_drm_winsys *rws = mgr->rws; + struct radeon_bo *bo; + struct drm_radeon_gem_create args = {}; + + args.size = size; + args.alignment = desc->alignment; + args.initial_domain = + (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT ? + RADEON_GEM_DOMAIN_GTT : 0) | + (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ? + RADEON_GEM_DOMAIN_VRAM : 0); + + if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_CREATE, + &args, sizeof(args))) { + fprintf(stderr, "Failed to allocate :\n"); + fprintf(stderr, " size : %d bytes\n", size); + fprintf(stderr, " alignment : %d bytes\n", desc->alignment); + fprintf(stderr, " domains : %d\n", args.initial_domain); + return NULL; + } + + bo = CALLOC_STRUCT(radeon_bo); + if (!bo) + return NULL; + + pipe_reference_init(&bo->base.base.reference, 1); + bo->base.base.alignment = desc->alignment; + bo->base.base.usage = desc->usage; + bo->base.base.size = size; + bo->base.vtbl = &radeon_bo_vtbl; + bo->mgr = mgr; + bo->handle = args.handle; + bo->size = size; + + radeon_bo_ref(bo); + return &bo->base; +} + +static void radeon_bomgr_flush(struct pb_manager *mgr) +{ + /* NOP */ +} + +static void radeon_bomgr_destroy(struct pb_manager *_mgr) +{ + struct radeon_bomgr *mgr = radeon_bomgr(_mgr); + util_hash_table_destroy(mgr->bo_handles); + pipe_mutex_destroy(mgr->bo_handles_mutex); + FREE(mgr); +} + +static unsigned handle_hash(void *key) +{ + return (unsigned)key; +} + +static int handle_compare(void *key1, void *key2) +{ + return !((int)key1 == (int)key2); +} + +struct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws) +{ + struct radeon_bomgr *mgr; + + mgr = CALLOC_STRUCT(radeon_bomgr); + if (!mgr) + return NULL; + + mgr->base.destroy = radeon_bomgr_destroy; + mgr->base.create_buffer = radeon_bomgr_create_bo; + mgr->base.flush = radeon_bomgr_flush; + + mgr->rws = rws; + mgr->bo_handles = util_hash_table_create(handle_hash, handle_compare); + pipe_mutex_init(mgr->bo_handles_mutex); + return &mgr->base; +} + +static void *radeon_bo_map(struct r300_winsys_bo *buf, + struct r300_winsys_cs *cs, + enum pipe_transfer_usage usage) +{ + struct pb_buffer *_buf = pb_buffer(buf); + + return pb_map(_buf, get_pb_usage_from_transfer_flags(usage), cs); +} + +static void radeon_bo_get_tiling(struct r300_winsys_bo *_buf, + enum r300_buffer_tiling *microtiled, + enum r300_buffer_tiling *macrotiled) +{ + struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); + struct drm_radeon_gem_set_tiling args = {}; + + args.handle = bo->handle; + + drmCommandWriteRead(bo->mgr->rws->fd, + DRM_RADEON_GEM_GET_TILING, + &args, + sizeof(args)); + + *microtiled = R300_BUFFER_LINEAR; + *macrotiled = R300_BUFFER_LINEAR; + if (args.tiling_flags & RADEON_BO_FLAGS_MICRO_TILE) + *microtiled = R300_BUFFER_TILED; + + if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE) + *macrotiled = R300_BUFFER_TILED; +} + +static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, + enum r300_buffer_tiling microtiled, + enum r300_buffer_tiling macrotiled, + uint32_t pitch) +{ + struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); + struct drm_radeon_gem_set_tiling args = {}; + + if (microtiled == R300_BUFFER_TILED) + args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE; + else if (microtiled == R300_BUFFER_SQUARETILED) + args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE; + + if (macrotiled == R300_BUFFER_TILED) + args.tiling_flags |= RADEON_BO_FLAGS_MACRO_TILE; + + args.handle = bo->handle; + args.pitch = pitch; + + drmCommandWriteRead(bo->mgr->rws->fd, + DRM_RADEON_GEM_SET_TILING, + &args, + sizeof(args)); +} + +static struct r300_winsys_cs_handle *radeon_drm_get_cs_handle( + struct r300_winsys_bo *_buf) +{ + /* return radeon_bo. */ + return (struct r300_winsys_cs_handle*) + get_radeon_bo(pb_buffer(_buf)); +} + +static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage, + enum r300_buffer_domain domain) +{ + unsigned res = 0; + + if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) + res |= RADEON_PB_USAGE_CACHE; + + if (domain & R300_DOMAIN_GTT) + res |= RADEON_PB_USAGE_DOMAIN_GTT; + + if (domain & R300_DOMAIN_VRAM) + res |= RADEON_PB_USAGE_DOMAIN_VRAM; + + return res; +} + +static struct r300_winsys_bo * +radeon_winsys_bo_create(struct r300_winsys_screen *rws, + unsigned size, + unsigned alignment, + unsigned bind, + unsigned usage, + enum r300_buffer_domain domain) +{ + struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); + struct pb_desc desc; + struct pb_manager *provider; + struct pb_buffer *buffer; + + memset(&desc, 0, sizeof(desc)); + desc.alignment = alignment; + desc.usage = get_pb_usage_from_create_flags(bind, usage, domain); + + /* Assign a buffer manager. */ + if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) + provider = ws->cman; + else + provider = ws->kman; + + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + return (struct r300_winsys_bo*)buffer; +} + +static struct r300_winsys_bo *radeon_winsys_bo_from_handle(struct r300_winsys_screen *rws, + struct winsys_handle *whandle, + unsigned *stride, + unsigned *size) +{ + struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); + struct radeon_bo *bo; + struct radeon_bomgr *mgr = radeon_bomgr(ws->kman); + struct drm_gem_open open_arg = {}; + + /* We must maintain a list of pairs <handle, bo>, so that we always return + * the same BO for one particular handle. If we didn't do that and created + * more than one BO for the same handle and then relocated them in a CS, + * we would hit a deadlock in the kernel. + * + * The list of pairs is guarded by a mutex, of course. */ + pipe_mutex_lock(mgr->bo_handles_mutex); + + /* First check if there already is an existing bo for the handle. */ + bo = util_hash_table_get(mgr->bo_handles, (void*)(uintptr_t)whandle->handle); + if (bo) { + /* Increase the refcount. */ + struct pb_buffer *b = NULL; + pb_reference(&b, &bo->base); + goto done; + } + + /* There isn't, create a new one. */ + bo = CALLOC_STRUCT(radeon_bo); + if (!bo) { + goto fail; + } + + /* Open the BO. */ + open_arg.name = whandle->handle; + if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) { + goto fail; + } + bo->handle = open_arg.handle; + bo->size = open_arg.size; + bo->name = whandle->handle; + radeon_bo_ref(bo); + + /* Initialize it. */ + pipe_reference_init(&bo->base.base.reference, 1); + bo->base.base.alignment = 0; + bo->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ; + bo->base.base.size = bo->size; + bo->base.vtbl = &radeon_bo_vtbl; + bo->mgr = mgr; + + util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)whandle->handle, bo); + +done: + pipe_mutex_unlock(mgr->bo_handles_mutex); + + if (stride) + *stride = whandle->stride; + if (size) + *size = bo->base.base.size; + + return (struct r300_winsys_bo*)bo; + +fail: + pipe_mutex_unlock(mgr->bo_handles_mutex); + return NULL; +} + +static boolean radeon_winsys_bo_get_handle(struct r300_winsys_bo *buffer, + unsigned stride, + struct winsys_handle *whandle) +{ + struct drm_gem_flink flink = {}; + struct radeon_bo *bo = get_radeon_bo(pb_buffer(buffer)); + whandle->stride = stride; + + + if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { + if (!bo->flinked) { + flink.handle = bo->handle; + + if (ioctl(bo->mgr->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) { + return FALSE; + } + + bo->flinked = TRUE; + bo->flink = flink.name; + } + whandle->handle = bo->flink; + } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { + whandle->handle = bo->handle; + } + return TRUE; +} + +void radeon_bomgr_init_functions(struct radeon_drm_winsys *ws) +{ + ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle; + ws->base.buffer_set_tiling = radeon_bo_set_tiling; + ws->base.buffer_get_tiling = radeon_bo_get_tiling; + ws->base.buffer_map = radeon_bo_map; + ws->base.buffer_unmap = pb_unmap; + ws->base.buffer_wait = radeon_bo_wait; + ws->base.buffer_is_busy = radeon_bo_is_busy; + ws->base.buffer_create = radeon_winsys_bo_create; + ws->base.buffer_from_handle = radeon_winsys_bo_from_handle; + ws->base.buffer_get_handle = radeon_winsys_bo_get_handle; +} diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.h b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h index 494abdc0b48..092b5e693ee 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h @@ -31,23 +31,48 @@ #define RADEON_DRM_BUFFER_H #include "radeon_winsys.h" +#include "pipebuffer/pb_bufmgr.h" -#define RADEON_PB_USAGE_VERTEX (1 << 28) +#define RADEON_PB_USAGE_CACHE (1 << 28) #define RADEON_PB_USAGE_DOMAIN_GTT (1 << 29) #define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30) +struct radeon_bomgr; + +struct radeon_bo { + struct pb_buffer base; + struct radeon_bomgr *mgr; + + void *ptr; + uint32_t size; + uint32_t handle; + uint32_t name; + + int cref; + + boolean flinked; + uint32_t flink; +}; + +struct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws); +struct pb_buffer *radeon_bomgr_create_bo_from_handle(struct pb_manager *_mgr, + uint32_t handle); +boolean radeon_bomgr_get_handle(struct pb_buffer *_buf, + struct winsys_handle *whandle); +void radeon_bomgr_init_functions(struct radeon_drm_winsys *ws); + +void radeon_bo_unref(struct radeon_bo *buf); + + +static INLINE void radeon_bo_ref(struct radeon_bo *bo) +{ + p_atomic_inc(&bo->cref); +} + static INLINE struct pb_buffer * -radeon_pb_buffer(struct r300_winsys_buffer *buffer) +pb_buffer(struct r300_winsys_bo *buffer) { return (struct pb_buffer *)buffer; } -struct pb_manager *radeon_drm_bufmgr_create(struct radeon_drm_winsys *rws); -struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle); -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); -boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, - struct winsys_handle *whandle); -void radeon_drm_bufmgr_init_functions(struct radeon_drm_winsys *ws); - #endif diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c deleted file mode 100644 index 4b0f688ce9a..00000000000 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c +++ /dev/null @@ -1,535 +0,0 @@ -#include "radeon_drm_buffer.h" -#include "radeon_drm_cs.h" - -#include "util/u_hash_table.h" -#include "util/u_memory.h" -#include "util/u_simple_list.h" -#include "pipebuffer/pb_bufmgr.h" -#include "os/os_thread.h" - -#include "state_tracker/drm_driver.h" - -#include <radeon_drm.h> -#include <radeon_bo_gem.h> -#include <sys/ioctl.h> - -struct radeon_drm_bufmgr; - -struct radeon_drm_buffer { - struct pb_buffer base; - struct radeon_drm_bufmgr *mgr; - - struct radeon_bo *bo; - - boolean flinked; - uint32_t flink; - - struct radeon_drm_buffer *next, *prev; -}; - -extern const struct pb_vtbl radeon_drm_buffer_vtbl; - - -static INLINE struct radeon_drm_buffer * -radeon_drm_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &radeon_drm_buffer_vtbl); - return (struct radeon_drm_buffer *)buf; -} - -struct radeon_drm_bufmgr { - /* Base class. */ - struct pb_manager base; - - /* Winsys. */ - struct radeon_drm_winsys *rws; - - /* List of mapped buffers and its mutex. */ - struct radeon_drm_buffer buffer_map_list; - pipe_mutex buffer_map_list_mutex; - - /* List of buffer handles and its mutex. */ - struct util_hash_table *buffer_handles; - pipe_mutex buffer_handles_mutex; -}; - -static INLINE struct radeon_drm_bufmgr * -radeon_drm_bufmgr(struct pb_manager *mgr) -{ - assert(mgr); - return (struct radeon_drm_bufmgr *)mgr; -} - -static void -radeon_drm_buffer_destroy(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - int name; - - if (buf->bo->ptr != NULL) { - pipe_mutex_lock(buf->mgr->buffer_map_list_mutex); - /* Now test it again inside the mutex. */ - if (buf->bo->ptr != NULL) { - remove_from_list(buf); - radeon_bo_unmap(buf->bo); - buf->bo->ptr = NULL; - } - pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex); - } - name = radeon_gem_name_bo(buf->bo); - if (name) { - pipe_mutex_lock(buf->mgr->buffer_handles_mutex); - util_hash_table_remove(buf->mgr->buffer_handles, - (void*)(uintptr_t)name); - pipe_mutex_unlock(buf->mgr->buffer_handles_mutex); - } - radeon_bo_unref(buf->bo); - - FREE(buf); -} - -static unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage) -{ - unsigned res = 0; - - if (usage & PIPE_TRANSFER_READ) - res |= PB_USAGE_CPU_READ; - - if (usage & PIPE_TRANSFER_WRITE) - res |= PB_USAGE_CPU_WRITE; - - if (usage & PIPE_TRANSFER_DONTBLOCK) - res |= PB_USAGE_DONTBLOCK; - - if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) - res |= PB_USAGE_UNSYNCHRONIZED; - - return res; -} - -static void * -radeon_drm_buffer_map_internal(struct pb_buffer *_buf, - unsigned flags, void *flush_ctx) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - struct radeon_drm_cs *cs = flush_ctx; - int write = 0; - - /* Note how we use radeon_bo_is_referenced_by_cs here. There are - * basically two places this map function can be called from: - * - pb_map - * - create_buffer (in the buffer reuse case) - * - * Since pb managers are per-winsys managers, not per-context managers, - * and we shouldn't reuse buffers if they are in-use in any context, - * we simply ask: is this buffer referenced by *any* CS? - * - * The problem with buffer_create is that it comes from pipe_screen, - * so we have no CS to look at, though luckily the following code - * is sufficient to tell whether the buffer is in use. */ - if (flags & PB_USAGE_DONTBLOCK) { - if (_buf->base.usage & RADEON_PB_USAGE_VERTEX) - if (radeon_bo_is_referenced_by_cs(buf->bo, NULL)) - return NULL; - } - - if (buf->bo->ptr != NULL) { - pipe_mutex_lock(buf->mgr->buffer_map_list_mutex); - /* Now test ptr again inside the mutex. We might have gotten a race - * during the first test. */ - if (buf->bo->ptr != NULL) { - remove_from_list(buf); - } - pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex); - return buf->bo->ptr; - } - - if (flags & PB_USAGE_DONTBLOCK) { - uint32_t domain; - if (radeon_bo_is_busy(buf->bo, &domain)) - return NULL; - } - - /* If we don't have any CS and the buffer is referenced, - * we cannot flush. */ - assert(cs || !radeon_bo_is_referenced_by_cs(buf->bo, NULL)); - - if (cs && radeon_bo_is_referenced_by_cs(buf->bo, NULL)) { - cs->flush_cs(cs->flush_data); - } - - if (flags & PB_USAGE_CPU_WRITE) { - write = 1; - } - - if (radeon_bo_map(buf->bo, write)) { - return NULL; - } - - pipe_mutex_lock(buf->mgr->buffer_map_list_mutex); - remove_from_list(buf); - pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex); - return buf->bo->ptr; -} - -static void -radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - pipe_mutex_lock(buf->mgr->buffer_map_list_mutex); - if (is_empty_list(buf)) { /* = is not inserted... */ - insert_at_tail(&buf->mgr->buffer_map_list, buf); - } - pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex); -} - -static void -radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - *base_buf = buf; - *offset = 0; -} - - -static enum pipe_error -radeon_drm_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - /* Always pinned */ - return PIPE_OK; -} - -static void -radeon_drm_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ -} - -const struct pb_vtbl radeon_drm_buffer_vtbl = { - radeon_drm_buffer_destroy, - radeon_drm_buffer_map_internal, - radeon_drm_buffer_unmap_internal, - radeon_drm_buffer_validate, - radeon_drm_buffer_fence, - radeon_drm_buffer_get_base_buffer, -}; - -static struct pb_buffer * -radeon_drm_bufmgr_create_buffer_from_handle_unsafe(struct pb_manager *_mgr, - uint32_t handle) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_drm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - struct radeon_bo *bo; - - buf = util_hash_table_get(mgr->buffer_handles, (void*)(uintptr_t)handle); - - if (buf) { - struct pb_buffer *b = NULL; - pb_reference(&b, &buf->base); - return b; - } - - bo = radeon_bo_open(rws->bom, handle, 0, - 0, 0, 0); - if (bo == NULL) - return NULL; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) { - radeon_bo_unref(bo); - return NULL; - } - - make_empty_list(buf); - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = 0; - buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ; - buf->base.base.size = bo->size; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - buf->bo = bo; - - util_hash_table_set(mgr->buffer_handles, (void*)(uintptr_t)handle, buf); - - return &buf->base; -} - -struct pb_buffer * -radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct pb_buffer *pb; - - pipe_mutex_lock(mgr->buffer_handles_mutex); - pb = radeon_drm_bufmgr_create_buffer_from_handle_unsafe(_mgr, handle); - pipe_mutex_unlock(mgr->buffer_handles_mutex); - - return pb; -} - -static struct pb_buffer * -radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, - pb_size size, - const struct pb_desc *desc) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_drm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - uint32_t domain; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) - goto error1; - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - make_empty_list(buf); - - domain = - (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) | - (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0); - - buf->bo = radeon_bo_open(rws->bom, 0, size, - desc->alignment, domain, 0); - if (buf->bo == NULL) - goto error2; - - return &buf->base; - - error2: - FREE(buf); - error1: - return NULL; -} - -static void -radeon_drm_bufmgr_flush(struct pb_manager *mgr) -{ - /* NOP */ -} - -static void -radeon_drm_bufmgr_destroy(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - util_hash_table_destroy(mgr->buffer_handles); - pipe_mutex_destroy(mgr->buffer_map_list_mutex); - pipe_mutex_destroy(mgr->buffer_handles_mutex); - FREE(mgr); -} - -static unsigned handle_hash(void *key) -{ - return (unsigned)key; -} - -static int handle_compare(void *key1, void *key2) -{ - return !((int)key1 == (int)key2); -} - -struct pb_manager * -radeon_drm_bufmgr_create(struct radeon_drm_winsys *rws) -{ - struct radeon_drm_bufmgr *mgr; - - mgr = CALLOC_STRUCT(radeon_drm_bufmgr); - if (!mgr) - return NULL; - - mgr->base.destroy = radeon_drm_bufmgr_destroy; - mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer; - mgr->base.flush = radeon_drm_bufmgr_flush; - - mgr->rws = rws; - make_empty_list(&mgr->buffer_map_list); - mgr->buffer_handles = util_hash_table_create(handle_hash, handle_compare); - pipe_mutex_init(mgr->buffer_map_list_mutex); - pipe_mutex_init(mgr->buffer_handles_mutex); - return &mgr->base; -} - -static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = NULL; - - if (_buf->vtbl == &radeon_drm_buffer_vtbl) { - buf = radeon_drm_buffer(_buf); - } else { - struct pb_buffer *base_buf; - pb_size offset; - pb_get_base_buffer(_buf, &base_buf, &offset); - - if (base_buf->vtbl == &radeon_drm_buffer_vtbl) - buf = radeon_drm_buffer(base_buf); - } - - return buf; -} - -static void *radeon_drm_buffer_map(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - struct r300_winsys_cs *cs, - enum pipe_transfer_usage usage) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return pb_map(_buf, get_pb_usage_from_transfer_flags(usage), radeon_drm_cs(cs)); -} - -static void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_unmap(_buf); -} - -boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, - struct winsys_handle *whandle) -{ - struct drm_gem_flink flink; - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - - if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { - if (!buf->flinked) { - flink.handle = buf->bo->handle; - - if (ioctl(buf->mgr->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) { - return FALSE; - } - - buf->flinked = TRUE; - buf->flink = flink.name; - } - whandle->handle = buf->flink; - } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { - whandle->handle = buf->bo->handle; - } - return TRUE; -} - -static void radeon_drm_buffer_get_tiling(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *_buf, - enum r300_buffer_tiling *microtiled, - enum r300_buffer_tiling *macrotiled) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); - uint32_t flags = 0, pitch; - - radeon_bo_get_tiling(buf->bo, &flags, &pitch); - - *microtiled = R300_BUFFER_LINEAR; - *macrotiled = R300_BUFFER_LINEAR; - if (flags & RADEON_BO_FLAGS_MICRO_TILE) - *microtiled = R300_BUFFER_TILED; - - if (flags & RADEON_BO_FLAGS_MACRO_TILE) - *macrotiled = R300_BUFFER_TILED; -} - -static void radeon_drm_buffer_set_tiling(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *_buf, - enum r300_buffer_tiling microtiled, - enum r300_buffer_tiling macrotiled, - uint32_t pitch) -{ -#ifndef RADEON_BO_FLAGS_MICRO_TILE_SQUARE -#define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20 -#endif - - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); - uint32_t flags = 0; - - if (microtiled == R300_BUFFER_TILED) - flags |= RADEON_BO_FLAGS_MICRO_TILE; - else if (microtiled == R300_BUFFER_SQUARETILED) - flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE; - - if (macrotiled == R300_BUFFER_TILED) - flags |= RADEON_BO_FLAGS_MACRO_TILE; - - radeon_bo_set_tiling(buf->bo, flags, pitch); -} - -static struct r300_winsys_cs_buffer *radeon_drm_get_cs_handle( - struct r300_winsys_screen *rws, - struct r300_winsys_buffer *_buf) -{ - /* return pure radeon_bo. */ - return (struct r300_winsys_cs_buffer*) - get_drm_buffer(radeon_pb_buffer(_buf))->bo; -} - -static boolean radeon_drm_is_buffer_referenced(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_buffer *_buf, - enum r300_reference_domain domain) -{ - struct radeon_bo *bo = (struct radeon_bo*)_buf; - uint32_t tmp; - - if (domain & R300_REF_CS) { - if (radeon_bo_is_referenced_by_cs(bo, NULL)) { - return TRUE; - } - } - - if (domain & R300_REF_HW) { - if (radeon_bo_is_busy(bo, &tmp)) { - return TRUE; - } - } - - return FALSE; -} - -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_drm_buffer *rpb, *t_rpb; - - pipe_mutex_lock(mgr->buffer_map_list_mutex); - - foreach_s(rpb, t_rpb, &mgr->buffer_map_list) { - radeon_bo_unmap(rpb->bo); - rpb->bo->ptr = NULL; - remove_from_list(rpb); - } - - make_empty_list(&mgr->buffer_map_list); - - pipe_mutex_unlock(mgr->buffer_map_list_mutex); -} - -static void radeon_drm_buffer_wait(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *_buf) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); - - radeon_bo_wait(buf->bo); -} - -void radeon_drm_bufmgr_init_functions(struct radeon_drm_winsys *ws) -{ - ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle; - ws->base.buffer_set_tiling = radeon_drm_buffer_set_tiling; - ws->base.buffer_get_tiling = radeon_drm_buffer_get_tiling; - ws->base.buffer_map = radeon_drm_buffer_map; - ws->base.buffer_unmap = radeon_drm_buffer_unmap; - ws->base.buffer_wait = radeon_drm_buffer_wait; - ws->base.cs_is_buffer_referenced = radeon_drm_is_buffer_referenced; -} diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_common.c b/src/gallium/winsys/radeon/drm/radeon_drm_common.c index 2ecf1bb014c..f9e595017d1 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_common.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_common.c @@ -30,16 +30,13 @@ */ #include "radeon_winsys.h" -#include "radeon_drm_buffer.h" +#include "radeon_drm_bo.h" #include "radeon_drm_cs.h" #include "radeon_drm_public.h" #include "pipebuffer/pb_bufmgr.h" #include "util/u_memory.h" -#include <radeon_drm.h> -#include <radeon_bo_gem.h> -#include <radeon_cs_gem.h> #include <xf86drm.h> #include <stdio.h> @@ -166,11 +163,47 @@ static void radeon_winsys_destroy(struct r300_winsys_screen *rws) ws->cman->destroy(ws->cman); ws->kman->destroy(ws->kman); - - radeon_bo_manager_gem_dtor(ws->bom); FREE(rws); } +static uint32_t radeon_get_value(struct r300_winsys_screen *rws, + enum r300_value_id id) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws; + + switch(id) { + case R300_VID_PCI_ID: + return ws->pci_id; + case R300_VID_GB_PIPES: + return ws->gb_pipes; + case R300_VID_Z_PIPES: + return ws->z_pipes; + case R300_VID_GART_SIZE: + return ws->gart_size; + case R300_VID_VRAM_SIZE: + return ws->vram_size; + case R300_VID_DRM_MAJOR: + return ws->drm_major; + case R300_VID_DRM_MINOR: + return ws->drm_minor; + case R300_VID_DRM_PATCHLEVEL: + return ws->drm_patchlevel; + case R300_VID_DRM_2_1_0: + return ws->drm_major*100 + ws->drm_minor >= 201; + case R300_VID_DRM_2_3_0: + return ws->drm_major*100 + ws->drm_minor >= 203; + case R300_VID_DRM_2_6_0: + return ws->drm_major*100 + ws->drm_minor >= 206; + case R300_VID_DRM_2_8_0: + return ws->drm_major*100 + ws->drm_minor >= 208; + case R300_CAN_HYPERZ: + return ws->hyperz; + case R300_CAN_AACOMPRESS: + return ws->aacompress; + } + return 0; +} + struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd) { struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); @@ -186,10 +219,7 @@ struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd) } /* Create managers. */ - ws->bom = radeon_bo_manager_gem_ctor(fd); - if (!ws->bom) - goto fail; - ws->kman = radeon_drm_bufmgr_create(ws); + ws->kman = radeon_bomgr_create(ws); if (!ws->kman) goto fail; ws->cman = pb_cache_manager_create(ws->kman, 1000000); @@ -198,22 +228,18 @@ struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd) /* Set functions. */ ws->base.destroy = radeon_winsys_destroy; + ws->base.get_value = radeon_get_value; - radeon_drm_bufmgr_init_functions(ws); + radeon_bomgr_init_functions(ws); radeon_drm_cs_init_functions(ws); - radeon_winsys_init_functions(ws); return &ws->base; fail: - if (ws->bom) - radeon_bo_manager_gem_dtor(ws->bom); - if (ws->cman) ws->cman->destroy(ws->cman); if (ws->kman) ws->kman->destroy(ws->kman); - FREE(ws); return NULL; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 60bc36b0929..6aa3f2ecce1 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -63,13 +63,12 @@ */ #include "radeon_drm_cs.h" -#include "radeon_drm_buffer.h" #include "util/u_memory.h" +#include <stdio.h> #include <stdlib.h> #include <stdint.h> -#include <radeon_bo.h> #include <xf86drm.h> #define RELOC_DWORDS (sizeof(struct drm_radeon_cs_reloc) / sizeof(uint32_t)) @@ -131,8 +130,7 @@ static inline void update_domains(struct drm_radeon_cs_reloc *reloc, } } -static int radeon_get_reloc(struct radeon_drm_cs *cs, - struct radeon_bo *bo) +int radeon_get_reloc(struct radeon_drm_cs *cs, struct radeon_bo *bo) { struct drm_radeon_cs_reloc *reloc; unsigned i; @@ -235,7 +233,7 @@ static void radeon_add_reloc(struct radeon_drm_cs *cs, } static void radeon_drm_cs_add_reloc(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_buffer *buf, + struct r300_winsys_cs_handle *buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd) { @@ -263,7 +261,7 @@ static boolean radeon_drm_cs_validate(struct r300_winsys_cs *rcs) } static void radeon_drm_cs_write_reloc(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_buffer *buf) + struct r300_winsys_cs_handle *buf) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_bo *bo = (struct radeon_bo*)buf; @@ -287,9 +285,6 @@ static void radeon_drm_cs_emit(struct r300_winsys_cs *rcs) int r; if (cs->base.cdw) { - /* Unmap buffers. */ - radeon_drm_bufmgr_flush_maps(cs->ws->kman); - /* Prepare the arguments. */ cs->chunks[0].length_dw = cs->base.cdw; @@ -319,7 +314,7 @@ static void radeon_drm_cs_emit(struct r300_winsys_cs *rcs) /* Unreference buffers, cleanup. */ for (i = 0; i < cs->crelocs; i++) { - radeon_bo_unref((struct radeon_bo*)cs->relocs_bo[i]); + radeon_bo_unref(cs->relocs_bo[i]); cs->relocs_bo[i] = NULL; } @@ -341,13 +336,22 @@ static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) } static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs, - void (*flush)(void *), void *user) + void (*flush)(void *), void *user) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); cs->flush_cs = flush; cs->flush_data = user; } +static boolean radeon_bo_is_referenced(struct r300_winsys_cs *rcs, + struct r300_winsys_cs_handle *_buf) +{ + struct radeon_drm_cs *cs = radeon_drm_cs(rcs); + struct radeon_bo *bo = (struct radeon_bo*)_buf; + + return radeon_bo_is_referenced_by_cs(cs, bo); +} + void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) { ws->base.cs_create = radeon_drm_cs_create; @@ -357,4 +361,5 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) ws->base.cs_write_reloc = radeon_drm_cs_write_reloc; ws->base.cs_flush = radeon_drm_cs_emit; ws->base.cs_set_flush = radeon_drm_cs_set_flush; + ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h index 76046534b65..3913c4e79a3 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h @@ -1,7 +1,7 @@ #ifndef RADEON_DRM_CS_H #define RADEON_DRM_CS_H -#include "radeon_winsys.h" +#include "radeon_drm_bo.h" #include <radeon_drm.h> struct radeon_drm_cs { @@ -31,12 +31,25 @@ struct radeon_drm_cs { unsigned reloc_indices_hashlist[256]; }; +int radeon_get_reloc(struct radeon_drm_cs *cs, struct radeon_bo *bo); + static INLINE struct radeon_drm_cs * radeon_drm_cs(struct r300_winsys_cs *base) { return (struct radeon_drm_cs*)base; } +static INLINE int radeon_bo_is_referenced_by_cs(struct radeon_drm_cs *cs, + struct radeon_bo *bo) +{ + return radeon_get_reloc(cs, bo) != -1; +} + +static INLINE int radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo) +{ + return bo->cref > 1; +} + void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws); #endif diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c deleted file mode 100644 index aebe6a60791..00000000000 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson <[email protected]> - * - * 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 - * on 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 above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 AUTHOR(S) AND/OR THEIR 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. */ - -#include "radeon_drm_buffer.h" - -#include "util/u_memory.h" -#include "pipebuffer/pb_bufmgr.h" - -#include "state_tracker/drm_driver.h" - -static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage, - enum r300_buffer_domain domain) -{ - unsigned res = 0; - - if (bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT)) - res |= PB_USAGE_GPU_WRITE; - - if (bind & PIPE_BIND_SAMPLER_VIEW) - res |= PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE; - - if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) - res |= PB_USAGE_GPU_READ; - - if (bind & PIPE_BIND_TRANSFER_WRITE) - res |= PB_USAGE_CPU_WRITE; - - if (bind & PIPE_BIND_TRANSFER_READ) - res |= PB_USAGE_CPU_READ; - - /* Is usage of any use for us? Probably not. */ - - /* Now add driver-specific usage flags. */ - if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) - res |= RADEON_PB_USAGE_VERTEX; - - if (domain & R300_DOMAIN_GTT) - res |= RADEON_PB_USAGE_DOMAIN_GTT; - - if (domain & R300_DOMAIN_VRAM) - res |= RADEON_PB_USAGE_DOMAIN_VRAM; - - return res; -} - -static struct r300_winsys_buffer * -radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, - unsigned size, - unsigned alignment, - unsigned bind, - unsigned usage, - enum r300_buffer_domain domain) -{ - struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); - struct pb_desc desc; - struct pb_manager *provider; - struct pb_buffer *buffer; - - memset(&desc, 0, sizeof(desc)); - desc.alignment = alignment; - desc.usage = get_pb_usage_from_create_flags(bind, usage, domain); - - /* Assign a buffer manager. */ - if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) - provider = ws->cman; - else - provider = ws->kman; - - buffer = provider->create_buffer(provider, size, &desc); - if (!buffer) - return NULL; - - return (struct r300_winsys_buffer*)buffer; -} - -static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, - struct r300_winsys_buffer **pdst, - struct r300_winsys_buffer *src) -{ - struct pb_buffer *_src = radeon_pb_buffer(src); - struct pb_buffer *_dst = radeon_pb_buffer(*pdst); - - pb_reference(&_dst, _src); - - *pdst = (struct r300_winsys_buffer*)_dst; -} - -static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws, - struct winsys_handle *whandle, - unsigned *stride, - unsigned *size) -{ - struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); - struct pb_buffer *_buf; - - _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle); - - if (stride) - *stride = whandle->stride; - if (size) - *size = _buf->base.size; - - return (struct r300_winsys_buffer*)_buf; -} - -static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buffer, - unsigned stride, - struct winsys_handle *whandle) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buffer); - whandle->stride = stride; - return radeon_drm_bufmgr_get_handle(_buf, whandle); -} - -static uint32_t radeon_get_value(struct r300_winsys_screen *rws, - enum r300_value_id id) -{ - struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws; - - switch(id) { - case R300_VID_PCI_ID: - return ws->pci_id; - case R300_VID_GB_PIPES: - return ws->gb_pipes; - case R300_VID_Z_PIPES: - return ws->z_pipes; - case R300_VID_GART_SIZE: - return ws->gart_size; - case R300_VID_VRAM_SIZE: - return ws->vram_size; - case R300_VID_DRM_MAJOR: - return ws->drm_major; - case R300_VID_DRM_MINOR: - return ws->drm_minor; - case R300_VID_DRM_PATCHLEVEL: - return ws->drm_patchlevel; - case R300_VID_DRM_2_1_0: - return ws->drm_major*100 + ws->drm_minor >= 201; - case R300_VID_DRM_2_3_0: - return ws->drm_major*100 + ws->drm_minor >= 203; - case R300_VID_DRM_2_6_0: - return ws->drm_major*100 + ws->drm_minor >= 206; - case R300_VID_DRM_2_8_0: - return ws->drm_major*100 + ws->drm_minor >= 208; - case R300_CAN_HYPERZ: - return ws->hyperz; - case R300_CAN_AACOMPRESS: - return ws->aacompress; - } - return 0; -} - -void radeon_winsys_init_functions(struct radeon_drm_winsys *ws) -{ - ws->base.get_value = radeon_get_value; - ws->base.buffer_create = radeon_r300_winsys_buffer_create; - ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; - ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle; - ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle; -} diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 743c4fbc4a9..be5614ce3ec 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -37,7 +37,6 @@ struct radeon_drm_winsys { int fd; /* DRM file descriptor */ - struct radeon_bo_manager *bom; /* Radeon BO manager. */ struct pb_manager *kman; struct pb_manager *cman; @@ -63,6 +62,4 @@ radeon_drm_winsys(struct r300_winsys_screen *base) return (struct radeon_drm_winsys*)base; } -void radeon_winsys_init_functions(struct radeon_drm_winsys *ws); - #endif |