From fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 14 Jul 2010 01:59:57 +0200 Subject: r300g: rebuild winsys and command submission to support multiple contexts --- src/gallium/winsys/radeon/drm/radeon_buffer.h | 41 ++- src/gallium/winsys/radeon/drm/radeon_drm_buffer.c | 149 ++++++---- src/gallium/winsys/radeon/drm/radeon_r300.c | 320 +++++++++------------- src/gallium/winsys/radeon/drm/radeon_winsys.h | 23 +- 4 files changed, 275 insertions(+), 258 deletions(-) (limited to 'src/gallium/winsys/radeon') diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h index 73cb6a579b..a8137d85e8 100644 --- a/src/gallium/winsys/radeon/drm/radeon_buffer.h +++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h @@ -43,10 +43,9 @@ #include "radeon_winsys.h" -#define RADEON_USAGE_DOMAIN_GTT (1 << 29) -#define RADEON_USAGE_DOMAIN_VRAM (1 << 30) - -#define RADEON_MAX_BOS 24 +#define RADEON_PB_USAGE_VERTEX (1 << 28) +#define RADEON_PB_USAGE_DOMAIN_GTT (1 << 29) +#define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30) static INLINE struct pb_buffer * radeon_pb_buffer(struct r300_winsys_buffer *buffer) @@ -63,24 +62,26 @@ radeon_libdrm_winsys_buffer(struct pb_buffer *buffer) struct pb_manager * radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd); - +void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *cs, + struct r300_winsys_buffer *buf, + enum r300_buffer_domain rd, + enum r300_buffer_domain wd); -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, +void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *cs, + struct r300_winsys_buffer *buf, enum r300_buffer_domain rd, - enum r300_buffer_domain wd, - uint32_t flags); + enum r300_buffer_domain wd); struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, uint32_t handle); -void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf, +void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf, enum r300_buffer_tiling *microtiled, enum r300_buffer_tiling *macrotiled); -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, +void radeon_drm_bufmgr_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); @@ -90,9 +91,19 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, struct winsys_handle *whandle); -boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf, +boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *cs, + struct r300_winsys_buffer *buf, enum r300_reference_domain domain); -void radeon_drm_bufmgr_wait(struct pb_buffer *_buf); +void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf); + +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); + +void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf); #endif diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c index c5f133e7b2..5ea5912089 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c @@ -20,6 +20,9 @@ struct radeon_drm_buffer { struct radeon_bo *bo; + /* The CS associated with the last buffer_map. */ + struct radeon_libdrm_cs *cs; + boolean flinked; uint32_t flink; @@ -65,34 +68,53 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf) 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(struct pb_buffer *_buf, +radeon_drm_buffer_map_internal(struct pb_buffer *_buf, unsigned flags) { struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + struct radeon_libdrm_cs *cs = buf->cs; int write = 0; - if (flags & PIPE_TRANSFER_DONTBLOCK) { - if ((_buf->base.usage & PIPE_BIND_VERTEX_BUFFER) || - (_buf->base.usage & PIPE_BIND_INDEX_BUFFER)) - if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) + if (flags & PB_USAGE_DONTBLOCK) { + if (_buf->base.usage & RADEON_PB_USAGE_VERTEX) + if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) return NULL; } if (buf->bo->ptr != NULL) return buf->bo->ptr; - if (flags & PIPE_TRANSFER_DONTBLOCK) { + if (flags & PB_USAGE_DONTBLOCK) { uint32_t domain; if (radeon_bo_is_busy(buf->bo, &domain)) return NULL; } - if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { - buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data); + if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) { + cs->flush_cs(cs->flush_data); } - if (flags & PIPE_TRANSFER_WRITE) { + if (flags & PB_USAGE_CPU_WRITE) { write = 1; } @@ -104,7 +126,7 @@ radeon_drm_buffer_map(struct pb_buffer *_buf, } static void -radeon_drm_buffer_unmap(struct pb_buffer *_buf) +radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf) { (void)_buf; } @@ -136,8 +158,8 @@ radeon_drm_buffer_fence(struct pb_buffer *buf, const struct pb_vtbl radeon_drm_buffer_vtbl = { radeon_drm_buffer_destroy, - radeon_drm_buffer_map, - radeon_drm_buffer_unmap, + radeon_drm_buffer_map_internal, + radeon_drm_buffer_unmap_internal, radeon_drm_buffer_validate, radeon_drm_buffer_fence, radeon_drm_buffer_get_base_buffer, @@ -166,7 +188,7 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager pipe_reference_init(&buf->base.base.reference, 1); buf->base.base.alignment = 0; - buf->base.base.usage = PIPE_BIND_SAMPLER_VIEW; + buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ; buf->base.base.size = 0; buf->base.vtbl = &radeon_drm_buffer_vtbl; buf->mgr = mgr; @@ -200,8 +222,8 @@ radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, make_empty_list(buf); domain = - (desc->usage & RADEON_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) | - (desc->usage & RADEON_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0); + (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); @@ -249,7 +271,8 @@ radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws) static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) { - struct radeon_drm_buffer *buf; + struct radeon_drm_buffer *buf = NULL; + if (_buf->vtbl == &radeon_drm_buffer_vtbl) { buf = radeon_drm_buffer(_buf); } else { @@ -257,11 +280,35 @@ static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) pb_size offset; pb_get_base_buffer(_buf, &base_buf, &offset); - buf = radeon_drm_buffer(base_buf); + if (base_buf->vtbl == &radeon_drm_buffer_vtbl) + buf = radeon_drm_buffer(base_buf); } + return buf; } +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); + struct radeon_drm_buffer *rbuf = get_drm_buffer(_buf); + + if (rbuf) + rbuf->cs = radeon_libdrm_cs(cs); + + return pb_map(_buf, get_pb_usage_from_transfer_flags(usage)); +} + +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) { @@ -286,11 +333,12 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, return TRUE; } -void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf, +void radeon_drm_bufmgr_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(_buf); + 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); @@ -304,12 +352,13 @@ void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf, *macrotiled = R300_BUFFER_TILED; } -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, +void radeon_drm_bufmgr_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) { - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + 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; @@ -324,56 +373,60 @@ void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, radeon_bo_set_tiling(buf->bo, flags, pitch); } -static uint32_t gem_domain(enum r300_buffer_domain dom) +static uint32_t get_gem_domain(enum r300_buffer_domain domain) { uint32_t res = 0; - if (dom & R300_DOMAIN_GTT) + if (domain & R300_DOMAIN_GTT) res |= RADEON_GEM_DOMAIN_GTT; - if (dom & R300_DOMAIN_VRAM) + if (domain & R300_DOMAIN_VRAM) res |= RADEON_GEM_DOMAIN_VRAM; return res; } -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd) +void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs, + struct r300_winsys_buffer *_buf, + enum r300_buffer_domain rd, + enum r300_buffer_domain wd) { - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - uint32_t gem_rd = gem_domain(rd); - uint32_t gem_wd = gem_domain(wd); + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); + uint32_t gem_rd = get_gem_domain(rd); + uint32_t gem_wd = get_gem_domain(wd); - radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo, - gem_rd, gem_wd); - return TRUE; + radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd); } -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, +void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs, + struct r300_winsys_buffer *_buf, enum r300_buffer_domain rd, - enum r300_buffer_domain wd, - uint32_t flags) + enum r300_buffer_domain wd) { - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); int retval; - uint32_t gem_rd = gem_domain(rd); - uint32_t gem_wd = gem_domain(wd); + uint32_t gem_rd = get_gem_domain(rd); + uint32_t gem_wd = get_gem_domain(wd); - retval = radeon_cs_write_reloc(buf->mgr->rws->cs, - buf->bo, gem_rd, gem_wd, flags); + cs->cs->cdw = cs->base.cdw; + retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0); + cs->base.cdw = cs->cs->cdw; if (retval) { fprintf(stderr, "radeon: Relocation of %p (%d, %d, %d) failed!\n", - buf, gem_rd, gem_wd, flags); + buf, gem_rd, gem_wd, 0); } } -boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf, +boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs, + struct r300_winsys_buffer *_buf, enum r300_reference_domain domain) { - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); uint32_t tmp; if (domain & R300_REF_CS) { - if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { + if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) { return TRUE; } } @@ -387,7 +440,6 @@ boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf, return FALSE; } - void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) { struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); @@ -402,9 +454,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) make_empty_list(&mgr->buffer_map_list); } -void radeon_drm_bufmgr_wait(struct pb_buffer *_buf) +void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *_buf) { - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); radeon_bo_wait(buf->bo); } diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index af35497fd7..4e89c07083 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -27,37 +27,69 @@ #include "radeon_cs_gem.h" #include "state_tracker/drm_driver.h" +#include "util/u_memory.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 alignment, - unsigned usage, - enum r300_buffer_domain domain, - unsigned size) + unsigned size, + unsigned alignment, + unsigned bind, + unsigned usage, + enum r300_buffer_domain domain) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws); struct pb_desc desc; struct pb_manager *provider; struct pb_buffer *buffer; - /* XXX this is hackish, but it's the only way to pass these flags - * to the real create function. */ - usage &= ~(RADEON_USAGE_DOMAIN_GTT | RADEON_USAGE_DOMAIN_VRAM); - if (domain & R300_DOMAIN_GTT) - usage |= RADEON_USAGE_DOMAIN_GTT; - if (domain & R300_DOMAIN_VRAM) - usage |= RADEON_USAGE_DOMAIN_VRAM; - memset(&desc, 0, sizeof(desc)); desc.alignment = alignment; - desc.usage = usage; + desc.usage = get_pb_usage_from_create_flags(bind, usage, domain); - if (usage & PIPE_BIND_CONSTANT_BUFFER) + /* Assign a buffer manager. */ + if (bind & PIPE_BIND_CONSTANT_BUFFER) provider = ws->mman; - else if ((usage & PIPE_BIND_VERTEX_BUFFER) || - (usage & PIPE_BIND_INDEX_BUFFER)) + else 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; @@ -65,55 +97,6 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, return radeon_libdrm_winsys_buffer(buffer); } -static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_destroy(_buf); -} -static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - uint32_t pitch, - enum r300_buffer_tiling microtiled, - enum r300_buffer_tiling macrotiled) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); -} - -static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - enum r300_buffer_tiling *microtiled, - enum r300_buffer_tiling *macrotiled) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_get_tiling(_buf, microtiled, macrotiled); -} - -static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - unsigned usage) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return pb_map(_buf, usage); -} - -static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_unmap(_buf); -} - -static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_wait(_buf); -} - static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, struct r300_winsys_buffer **pdst, struct r300_winsys_buffer *src) @@ -126,20 +109,11 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, *pdst = radeon_libdrm_winsys_buffer(_dst); } -static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - enum r300_reference_domain domain) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return radeon_drm_bufmgr_is_buffer_referenced(_buf, domain); -} - static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws, struct winsys_handle *whandle, unsigned *stride) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws); struct pb_buffer *_buf; *stride = whandle->stride; @@ -150,111 +124,57 @@ static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws, struct r300_winsys_buffer *buffer, - struct winsys_handle *whandle, - unsigned stride) + 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 void radeon_set_flush_cb(struct r300_winsys_screen *rws, - void (*flush_cb)(void *), - void *data) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - ws->flush_cb = flush_cb; - ws->flush_data = data; - radeon_cs_space_set_flush(ws->cs, flush_cb, data); -} - -static boolean radeon_add_buffer(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); -} - -static boolean radeon_validate(struct r300_winsys_screen *rws) +static void radeon_r300_winsys_cs_set_flush(struct r300_winsys_cs *rcs, + void (*flush)(void *), + void *user) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - if (radeon_cs_space_check(ws->cs) < 0) { - return FALSE; - } - - /* Things are fine, we can proceed as normal. */ - return TRUE; + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + cs->flush_cs = flush; + cs->flush_data = user; + radeon_cs_space_set_flush(cs->cs, flush, user); } -static unsigned radeon_get_cs_free_dwords(struct r300_winsys_screen *rws) +static boolean radeon_r300_winsys_cs_validate(struct r300_winsys_cs *rcs) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct radeon_cs *cs = ws->cs; + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); - return cs->ndw - cs->cdw; + return radeon_cs_space_check(cs->cs) >= 0; } -static uint32_t *radeon_get_cs_pointer(struct r300_winsys_screen *rws, - unsigned count) +static void radeon_r300_winsys_cs_reset_buffers(struct r300_winsys_cs *rcs) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct radeon_cs *cs = ws->cs; - uint32_t *ptr = cs->packets + cs->cdw; - - cs->cdw += count; - return ptr; + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + radeon_cs_space_reset_bos(cs->cs); } -static void radeon_write_cs_dword(struct r300_winsys_screen *rws, - uint32_t dword) +static void radeon_r300_winsys_cs_flush(struct r300_winsys_cs *rcs) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_write_dword(ws->cs, dword); -} - -static void radeon_write_cs_table(struct r300_winsys_screen *rws, - const void *table, unsigned count) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_write_table(ws->cs, table, count); -} - -static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd, - uint32_t flags) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); -} - -static void radeon_reset_bos(struct r300_winsys_screen *rws) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_space_reset_bos(ws->cs); -} - -static void radeon_flush_cs(struct r300_winsys_screen *rws) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); int retval; /* Don't flush a zero-sized CS. */ - if (!ws->cs->cdw) { + if (!cs->base.cdw) { return; } - radeon_drm_bufmgr_flush_maps(ws->kman); + cs->cs->cdw = cs->base.cdw; + + radeon_drm_bufmgr_flush_maps(cs->ws->kman); + /* Emit the CS. */ - retval = radeon_cs_emit(ws->cs); + retval = radeon_cs_emit(cs->cs); if (retval) { if (debug_get_bool_option("RADEON_DUMP_CS", FALSE)) { fprintf(stderr, "radeon: The kernel rejected CS, dumping...\n"); - radeon_cs_print(ws->cs, stderr); + radeon_cs_print(cs->cs, stderr); } else { fprintf(stderr, "radeon: The kernel rejected CS, " "see dmesg for more information.\n"); @@ -265,11 +185,15 @@ static void radeon_flush_cs(struct r300_winsys_screen *rws) * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(ws->cs); + radeon_cs_erase(cs->cs); + + cs->base.ptr = cs->cs->packets; + cs->base.cdw = cs->cs->cdw; + cs->base.ndw = cs->cs->ndw; } static uint32_t radeon_get_value(struct r300_winsys_screen *rws, - enum r300_value_id id) + enum r300_value_id id) { struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; @@ -288,11 +212,42 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws, return 0; } -static void -radeon_winsys_destroy(struct r300_winsys_screen *rws) +static struct r300_winsys_cs *radeon_r300_winsys_cs_create(struct r300_winsys_screen *rws) +{ + struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws); + struct radeon_libdrm_cs *cs = CALLOC_STRUCT(radeon_libdrm_cs); + + if (!cs) + return NULL; + + /* Size limit on IBs is 64 kibibytes. */ + cs->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); + if (!cs->cs) { + FREE(cs); + return NULL; + } + + radeon_cs_set_limit(cs->cs, + RADEON_GEM_DOMAIN_GTT, ws->gart_size); + radeon_cs_set_limit(cs->cs, + RADEON_GEM_DOMAIN_VRAM, ws->vram_size); + + cs->ws = ws; + cs->base.ptr = cs->cs->packets; + cs->base.cdw = cs->cs->cdw; + cs->base.ndw = cs->cs->ndw; + return &cs->base; +} + +static void radeon_r300_winsys_cs_destroy(struct r300_winsys_cs *rcs) +{ + struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); + radeon_cs_destroy(cs->cs); +} + +static void radeon_winsys_destroy(struct r300_winsys_screen *rws) { struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; - radeon_cs_destroy(ws->cs); ws->cman->destroy(ws->cman); ws->kman->destroy(ws->kman); @@ -302,10 +257,8 @@ radeon_winsys_destroy(struct r300_winsys_screen *rws) radeon_cs_manager_gem_dtor(ws->csm); } -boolean -radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) +boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) { - ws->csm = radeon_cs_manager_gem_ctor(fd); if (!ws->csm) goto fail; @@ -324,39 +277,28 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) if (!ws->mman) goto fail; - /* Size limit on IBs is 64 kibibytes. */ - ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); - if (!ws->cs) - goto fail; - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_GTT, ws->gart_size); - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_VRAM, ws->vram_size); - - ws->base.add_buffer = radeon_add_buffer; - ws->base.validate = radeon_validate; ws->base.destroy = radeon_winsys_destroy; - ws->base.get_cs_free_dwords = radeon_get_cs_free_dwords; - ws->base.get_cs_pointer = radeon_get_cs_pointer; - ws->base.write_cs_dword = radeon_write_cs_dword; - ws->base.write_cs_table = radeon_write_cs_table; - ws->base.write_cs_reloc = radeon_write_cs_reloc; - ws->base.flush_cs = radeon_flush_cs; - ws->base.reset_bos = radeon_reset_bos; - ws->base.set_flush_cb = radeon_set_flush_cb; ws->base.get_value = radeon_get_value; ws->base.buffer_create = radeon_r300_winsys_buffer_create; - ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy; - ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling; - ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling; - ws->base.buffer_map = radeon_r300_winsys_buffer_map; - ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; - ws->base.buffer_wait = radeon_r300_winsys_buffer_wait; + ws->base.buffer_set_tiling = radeon_drm_bufmgr_set_tiling; + ws->base.buffer_get_tiling = radeon_drm_bufmgr_get_tiling; + ws->base.buffer_map = radeon_drm_buffer_map; + ws->base.buffer_unmap = radeon_drm_buffer_unmap; + ws->base.buffer_wait = radeon_drm_bufmgr_wait; 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; - ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced; + + ws->base.cs_create = radeon_r300_winsys_cs_create; + ws->base.cs_destroy = radeon_r300_winsys_cs_destroy; + ws->base.cs_add_buffer = radeon_drm_bufmgr_add_buffer; + ws->base.cs_validate = radeon_r300_winsys_cs_validate; + ws->base.cs_write_reloc = radeon_drm_bufmgr_write_reloc; + ws->base.cs_flush = radeon_r300_winsys_cs_flush; + ws->base.cs_reset_buffers = radeon_r300_winsys_cs_reset_buffers; + ws->base.cs_set_flush = radeon_r300_winsys_cs_set_flush; + ws->base.cs_is_buffer_referenced = radeon_drm_bufmgr_is_buffer_referenced; return TRUE; fail: @@ -373,7 +315,5 @@ fail: if (ws->mman) ws->mman->destroy(ws->mman); - if (ws->cs) - radeon_cs_destroy(ws->cs); return FALSE; } diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index ca789be8e9..9a25e7679c 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -75,19 +75,32 @@ struct radeon_libdrm_winsys { /* Radeon CS manager. */ struct radeon_cs_manager *csm; +}; + +struct radeon_libdrm_cs { + struct r300_winsys_cs base; + + /* The winsys. */ + struct radeon_libdrm_winsys *ws; - /* Current CS. */ + /* The libdrm command stream. */ struct radeon_cs *cs; - /* Flush CB */ - void (*flush_cb)(void *); + /* Flush CS. */ + void (*flush_cs)(void *); void *flush_data; }; +static INLINE struct radeon_libdrm_cs * +radeon_libdrm_cs(struct r300_winsys_cs *base) +{ + return (struct radeon_libdrm_cs*)base; +} + static INLINE struct radeon_libdrm_winsys * -radeon_winsys_screen(struct r300_winsys_screen *base) +radeon_libdrm_winsys(struct r300_winsys_screen *base) { - return (struct radeon_libdrm_winsys *)base; + return (struct radeon_libdrm_winsys*)base; } #endif -- cgit v1.2.3