diff options
author | Dave Airlie <airlied@redhat.com> | 2010-02-12 15:39:51 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-22 16:23:44 +1000 |
commit | fff5be8e7b4557c221f2425dcafc2e7cbbba76ba (patch) | |
tree | 88c6f78ba1cbe65fcc6db2da13e6427f32d91fb6 /src/gallium/winsys/drm/radeon/core/radeon_r300.c | |
parent | 233290f2031057b37fdadb650873b02be307ebc8 (diff) |
r300g: rebuild winsys/pipe buffer handling and add buffer map
This creates a cleaner winsys and drop the simple screen stuff.
It makes r300g use pb_bufmgr structs and adds usage of the cached
bufmgr for vertex/index buffers.
It also avoids mapping too often.
I'm not 100% sure this is perfect but it won't find its own bugs.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/gallium/winsys/drm/radeon/core/radeon_r300.c')
-rw-r--r-- | src/gallium/winsys/drm/radeon/core/radeon_r300.c | 237 |
1 files changed, 175 insertions, 62 deletions
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index d759beaba1..997abb8f5c 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,29 +22,104 @@ #include "radeon_r300.h" -static void radeon_set_flush_cb(struct radeon_winsys *winsys, +static struct r300_winsys_buffer * +radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct pb_desc desc; + struct pb_manager *provider; + struct pb_buffer *buffer; + + memset(&desc, 0, sizeof(desc)); + desc.alignment = alignment; + desc.usage = usage; + + if (usage == PIPE_BUFFER_USAGE_CONSTANT) + provider = ws->mman; + else if (usage == PIPE_BUFFER_USAGE_VERTEX || + usage == PIPE_BUFFER_USAGE_INDEX) + provider = ws->cman; + else + provider = ws->kman; + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + 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, + boolean microtiled, + boolean macrotiled) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); +} + +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, 0); +} + +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_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 = radeon_libdrm_winsys_buffer(_dst); +} + +static void radeon_set_flush_cb(struct r300_winsys_screen *rws, void (*flush_cb)(void *), void *data) { - winsys->priv->flush_cb = flush_cb; - winsys->priv->flush_data = data; - radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, 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 radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static boolean radeon_add_buffer(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd) { - struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; + struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); - return TRUE; + return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); } -static boolean radeon_validate(struct radeon_winsys* winsys) +static boolean radeon_validate(struct r300_winsys_screen *rws) { - if (radeon_cs_space_check(winsys->priv->cs) < 0) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + if (radeon_cs_space_check(ws->cs) < 0) { return FALSE; } @@ -52,108 +127,146 @@ static boolean radeon_validate(struct radeon_winsys* winsys) return TRUE; } -static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) +static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size) { - struct radeon_cs* cs = winsys->priv->cs; + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_cs *cs = ws->cs; - return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; + return radeon_validate(rws) && cs->cdw + size <= cs->ndw; } -static void radeon_begin_cs(struct radeon_winsys* winsys, +static void radeon_begin_cs(struct r300_winsys_screen *rws, int size, const char* file, const char* function, int line) { - radeon_cs_begin(winsys->priv->cs, size, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_begin(ws->cs, size, file, function, line); } -static void radeon_write_cs_dword(struct radeon_winsys* winsys, +static void radeon_write_cs_dword(struct r300_winsys_screen *rws, uint32_t dword) { - radeon_cs_write_dword(winsys->priv->cs, dword); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_write_dword(ws->cs, dword); } -static void radeon_write_cs_reloc(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd, uint32_t flags) { - int retval = 0; - struct radeon_pipe_buffer* radeon_buffer = - (struct radeon_pipe_buffer*)pbuffer; - - assert(!radeon_buffer->pb); - - retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, - rd, wd, flags); - - if (retval) { - debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", - pbuffer, rd, wd, flags); - } + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); } -static void radeon_reset_bos(struct radeon_winsys *winsys) +static void radeon_reset_bos(struct r300_winsys_screen *rws) { - radeon_cs_space_reset_bos(winsys->priv->cs); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_space_reset_bos(ws->cs); } -static void radeon_end_cs(struct radeon_winsys* winsys, +static void radeon_end_cs(struct r300_winsys_screen *rws, const char* file, const char* function, int line) { - radeon_cs_end(winsys->priv->cs, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_end(ws->cs, file, function, line); } -static void radeon_flush_cs(struct radeon_winsys* winsys) +static void radeon_flush_cs(struct r300_winsys_screen *rws) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); int retval; /* Don't flush a zero-sized CS. */ - if (!winsys->priv->cs->cdw) { + if (!ws->cs->cdw) { return; } + radeon_drm_bufmgr_flush_maps(ws->kman); /* Emit the CS. */ - retval = radeon_cs_emit(winsys->priv->cs); + retval = radeon_cs_emit(ws->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(winsys->priv->cs, stderr); + radeon_cs_print(ws->cs, stderr); } /* Reset CS. * 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(winsys->priv->cs); + radeon_cs_erase(ws->cs); +} + +static uint32_t radeon_get_value(struct r300_winsys_screen *rws, + enum r300_value_id id) +{ + struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_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; + } + return 0; +} + +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); + ws->mman->destroy(ws->mman); + + radeon_bo_manager_gem_dtor(ws->bom); + radeon_cs_manager_gem_dtor(ws->csm); } void -radeon_setup_winsys(int fd, struct radeon_winsys* winsys) +radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) { - struct radeon_winsys_priv* priv = winsys->priv; + ws->csm = radeon_cs_manager_gem_ctor(fd); + + ws->bom = radeon_bo_manager_gem_ctor(fd); + ws->kman = radeon_drm_bufmgr_create(ws); - priv->csm = radeon_cs_manager_gem_ctor(fd); + ws->cman = pb_cache_manager_create(ws->kman, 100000); + ws->mman = pb_malloc_bufmgr_create(); /* Size limit on IBs is 64 kibibytes. */ - priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_GTT, winsys->gart_size); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); - - winsys->add_buffer = radeon_add_buffer; - winsys->validate = radeon_validate; - - winsys->check_cs = radeon_check_cs; - winsys->begin_cs = radeon_begin_cs; - winsys->write_cs_dword = radeon_write_cs_dword; - winsys->write_cs_reloc = radeon_write_cs_reloc; - winsys->end_cs = radeon_end_cs; - winsys->flush_cs = radeon_flush_cs; - winsys->reset_bos = radeon_reset_bos; - winsys->set_flush_cb = radeon_set_flush_cb; + ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); + 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.check_cs = radeon_check_cs; + ws->base.begin_cs = radeon_begin_cs; + ws->base.write_cs_dword = radeon_write_cs_dword; + ws->base.write_cs_reloc = radeon_write_cs_reloc; + ws->base.end_cs = radeon_end_cs; + 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_map = radeon_r300_winsys_buffer_map; + ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; + ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; } |