diff options
Diffstat (limited to 'src/gallium/winsys/radeon/drm/radeon_drm_buffer.c')
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_buffer.c | 535 |
1 files changed, 0 insertions, 535 deletions
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 4b0f688ce9..0000000000 --- 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; -} |