From: Marek Olšák Date: Fri, 3 Dec 2010 01:48:11 +0000 (+0100) Subject: r300g: use internal BO handle for add_buffer and write_reloc X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ba8843307a909f35f2a04e6be6dcadd760ad82b;p=mesa.git r300g: use internal BO handle for add_buffer and write_reloc Small perf improvement in ipers. radeon_drm_get_cs_handle is exactly what this commit tries to avoid in every write_reloc. --- diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 2b97e4f8e28..93c20a0a6a0 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -282,6 +282,7 @@ struct r300_query { /* The buffer where query results are stored. */ struct r300_winsys_buffer *buffer; + struct r300_winsys_cs_buffer *cs_buffer; /* The size of the buffer. */ unsigned buffer_size; /* The domain of the buffer. */ @@ -313,6 +314,7 @@ struct r300_surface { /* Winsys buffer backing the texture. */ struct r300_winsys_buffer *buffer; + struct r300_winsys_cs_buffer *cs_buffer; enum r300_buffer_domain domain; @@ -396,6 +398,7 @@ struct r300_texture { /* Pipe buffer backing this texture. */ struct r300_winsys_buffer *buffer; + struct r300_winsys_cs_buffer *cs_buffer; /* Registers carrying texture format data. */ /* Only format-independent bits should be filled in. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index c194d6a1b08..ea29fc565b2 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -115,17 +115,17 @@ #define OUT_CS_BUF_RELOC(bo, offset, rd, wd) do { \ assert(bo); \ - OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd); \ + OUT_CS_RELOC(r300_buffer(bo)->cs_buf, offset, rd, wd); \ } while (0) #define OUT_CS_TEX_RELOC(tex, offset, rd, wd) do { \ assert(tex); \ - OUT_CS_RELOC(tex->buffer, offset, rd, wd); \ + OUT_CS_RELOC(tex->cs_buffer, offset, rd, wd); \ } while (0) #define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd) do { \ assert(bo); \ - cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->buf, rd, wd); \ + cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->cs_buf, rd, wd); \ CS_DEBUG(cs_count -= 2;) \ } while (0) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3e6852b7798..31c7b38adfb 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -353,10 +353,10 @@ void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state) if (aa->dest) { OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1); - OUT_CS_RELOC(aa->dest->buffer, aa->dest->offset, 0, aa->dest->domain); + OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->offset, 0, aa->dest->domain); OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1); - OUT_CS_RELOC(aa->dest->buffer, aa->dest->pitch, 0, aa->dest->domain); + OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->pitch, 0, aa->dest->domain); } OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, aa->aaresolve_ctl); @@ -387,10 +387,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) surf = r300_surface(fb->cbufs[i]); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->offset, 0, surf->domain); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->pitch, 0, surf->domain); } /* Set up the ZB part of the CBZB clear. */ @@ -400,10 +400,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_RELOC(surf->buffer, surf->cbzb_midpoint_offset, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_midpoint_offset, 0, surf->domain); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_pitch, 0, surf->domain); DBG(r300, DBG_CBZB, "CBZB clearing cbuf %08x %08x\n", surf->cbzb_format, @@ -416,10 +416,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_ZB_FORMAT, surf->format); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->offset, 0, surf->domain); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); + OUT_CS_RELOC(surf->cs_buffer, surf->pitch, 0, surf->domain); if (can_hyperz) { uint32_t surf_pitch; @@ -559,7 +559,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300, struct r300_query *query) { struct r300_capabilities* caps = &r300->screen->caps; - struct r300_winsys_buffer *buf = r300->query_current->buffer; + struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer; CS_LOCALS(r300); assert(caps->num_frag_pipes); @@ -615,7 +615,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300, static void rv530_emit_query_end_single_z(struct r300_context *r300, struct r300_query *query) { - struct r300_winsys_buffer *buf = r300->query_current->buffer; + struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer; CS_LOCALS(r300); BEGIN_CS(8); @@ -629,7 +629,7 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300, static void rv530_emit_query_end_double_z(struct r300_context *r300, struct r300_query *query) { - struct r300_winsys_buffer *buf = r300->query_current->buffer; + struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer; CS_LOCALS(r300); BEGIN_CS(14); @@ -1188,14 +1188,14 @@ boolean r300_emit_buffer_validate(struct r300_context *r300, for (i = 0; i < fb->nr_cbufs; i++) { tex = r300_texture(fb->cbufs[i]->texture); assert(tex && tex->buffer && "cbuf is marked, but NULL!"); - r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0, + r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, 0, r300_surface(fb->cbufs[i])->domain); } /* ...depth buffer... */ if (fb->zsbuf) { tex = r300_texture(fb->zsbuf->texture); assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); - r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0, + r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, 0, r300_surface(fb->zsbuf)->domain); } /* ...textures... */ @@ -1205,28 +1205,28 @@ boolean r300_emit_buffer_validate(struct r300_context *r300, } tex = r300_texture(texstate->sampler_views[i]->base.texture); - r300->rws->cs_add_buffer(r300->cs, tex->buffer, tex->domain, 0); + r300->rws->cs_add_buffer(r300->cs, tex->cs_buffer, tex->domain, 0); } /* ...occlusion query buffer... */ if (r300->query_current) - r300->rws->cs_add_buffer(r300->cs, r300->query_current->buffer, + r300->rws->cs_add_buffer(r300->cs, r300->query_current->cs_buffer, 0, r300->query_current->domain); /* ...vertex buffer for SWTCL path... */ if (r300->vbo) - r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->buf, + r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->cs_buf, r300_buffer(r300->vbo)->domain, 0); /* ...vertex buffers for HWTCL path... */ if (do_validate_vertex_buffers) { for (i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->buf, + r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->cs_buf, r300_buffer(pbuf)->domain, 0); } } /* ...and index buffer for HWTCL path. */ if (index_buffer) - r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->buf, + r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->cs_buf, r300_buffer(index_buffer)->domain, 0); if (!r300->rws->cs_validate(r300->cs)) { diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index 5f34fcb2744..59cd1e7f794 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -60,6 +60,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe, q->buffer = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096, PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM, q->domain); + q->cs_buffer = r300->rws->buffer_get_cs_handle(r300->rws, q->buffer); return (struct pipe_query*)q; } diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index 98d36ad2729..9b1ee9e068a 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -43,7 +43,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context, if (r300_buffer_is_user_buffer(buf)) return PIPE_UNREFERENCED; - if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain)) + if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain)) return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; return PIPE_UNREFERENCED; @@ -206,6 +206,9 @@ r300_buffer_transfer_map( struct pipe_context *pipe, rbuf->b.b.bind, rbuf->b.b.usage, rbuf->domain); + rbuf->cs_buf = + r300screen->rws->buffer_get_cs_handle(r300screen->rws, + rbuf->buf); break; } } @@ -310,6 +313,8 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, rbuf->b.b.width0, alignment, rbuf->b.b.bind, rbuf->b.b.usage, rbuf->domain); + rbuf->cs_buf = + r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf); if (!rbuf->buf) { util_slab_free(&r300screen->pool_buffers, rbuf); diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h index cafa9f96f20..a184ead3a35 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -51,6 +51,7 @@ struct r300_buffer uint32_t magic; struct r300_winsys_buffer *buf; + struct r300_winsys_cs_buffer *cs_buf; enum r300_buffer_domain domain; @@ -86,11 +87,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context, static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer) { - if (buffer) { - assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); - return (struct r300_buffer *)buffer; - } - return NULL; + return (struct r300_buffer *)buffer; } static INLINE boolean r300_buffer_is_user_buffer(struct pipe_resource *buffer) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 0f563703c06..d4e20635586 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -626,7 +626,7 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300, /* Tiling determines how DRM treats the buffer data. * We must flush CS when changing it if the buffer is referenced. */ if (r300->rws->cs_is_buffer_referenced(r300->cs, - tex->buffer, R300_REF_CS)) + tex->cs_buffer, R300_REF_CS)) r300->context.flush(&r300->context, 0, NULL); r300->rws->buffer_set_tiling(r300->rws, tex->buffer, diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 4b7b3e03564..70fc5d96d83 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -675,7 +675,7 @@ static unsigned r300_texture_is_referenced(struct pipe_context *context, struct r300_texture *rtex = (struct r300_texture *)texture; if (r300->rws->cs_is_buffer_referenced(r300->cs, - rtex->buffer, R300_REF_CS)) + rtex->cs_buffer, R300_REF_CS)) return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; return PIPE_UNREFERENCED; @@ -777,6 +777,8 @@ r300_texture_create_object(struct r300_screen *rscreen, } } + tex->cs_buffer = rws->buffer_get_cs_handle(rws, tex->buffer); + rws->buffer_set_tiling(rws, tex->buffer, tex->desc.microtile, tex->desc.macrotile[0], tex->desc.stride_in_bytes[0]); @@ -876,6 +878,7 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx, surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer; surface->buffer = tex->buffer; + surface->cs_buffer = tex->cs_buffer; /* Prefer VRAM if there are multiple domains to choose from. */ surface->domain = tex->domain; diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 755aff8380c..3b95af79bcf 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -90,13 +90,13 @@ r300_texture_get_transfer(struct pipe_context *ctx, referenced_cs = r300->rws->cs_is_buffer_referenced(r300->cs, - tex->buffer, R300_REF_CS); + tex->cs_buffer, R300_REF_CS); if (referenced_cs) { referenced_hw = TRUE; } else { referenced_hw = r300->rws->cs_is_buffer_referenced(r300->cs, - tex->buffer, R300_REF_HW); + tex->cs_buffer, R300_REF_HW); } blittable = ctx->screen->is_format_supported( diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 4597332399a..c45888dbf38 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -36,7 +36,8 @@ struct winsys_handle; struct r300_winsys_screen; -struct r300_winsys_buffer; +struct r300_winsys_buffer; /* for map/unmap etc. */ +struct r300_winsys_cs_buffer; /* for write_reloc etc. */ struct r300_winsys_cs { uint32_t *ptr; /* Pointer to the beginning of the CS. */ @@ -102,6 +103,10 @@ struct r300_winsys_screen { unsigned usage, enum r300_buffer_domain domain); + struct r300_winsys_cs_buffer *(*buffer_get_cs_handle)( + struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf); + /** * Reference a buffer object (assign with reference counting). * @@ -242,7 +247,7 @@ struct r300_winsys_screen { * of the R300_DOMAIN_* flags. */ void (*cs_add_buffer)(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd); @@ -263,7 +268,7 @@ struct r300_winsys_screen { * \param wd A write domain containing a bitmask of the R300_DOMAIN_* flags. */ void (*cs_write_reloc)(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd); @@ -303,7 +308,7 @@ struct r300_winsys_screen { * \param domain A bitmask of the R300_REF_* enums. */ boolean (*cs_is_buffer_referenced)(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_reference_domain domain); }; diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h index a8137d85e83..59edbcadbc9 100644 --- a/src/gallium/winsys/radeon/drm/radeon_buffer.h +++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h @@ -63,12 +63,12 @@ struct pb_manager * radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd); void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd); @@ -92,7 +92,7 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf, struct winsys_handle *whandle); boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *cs, - struct r300_winsys_buffer *buf, + struct r300_winsys_cs_buffer *buf, enum r300_reference_domain domain); void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws, @@ -106,4 +106,8 @@ void *radeon_drm_buffer_map(struct r300_winsys_screen *ws, void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws, struct r300_winsys_buffer *buf); +struct r300_winsys_cs_buffer *radeon_drm_get_cs_handle( + struct r300_winsys_screen *rws, + 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 78723948d41..294d4fac7cd 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c @@ -477,54 +477,63 @@ static uint32_t get_gem_domain(enum r300_buffer_domain domain) } void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs, - struct r300_winsys_buffer *_buf, + struct r300_winsys_cs_buffer *_buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd) { struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); + struct radeon_bo *bo = (struct radeon_bo*)_buf; uint32_t gem_rd = get_gem_domain(rd); uint32_t gem_wd = get_gem_domain(wd); - radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd); + radeon_cs_space_add_persistent_bo(cs->cs, bo, gem_rd, gem_wd); } void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs, - struct r300_winsys_buffer *_buf, + struct r300_winsys_cs_buffer *_buf, enum r300_buffer_domain rd, enum r300_buffer_domain wd) { struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); + struct radeon_bo *bo = (struct radeon_bo*)_buf; int retval; uint32_t gem_rd = get_gem_domain(rd); uint32_t gem_wd = get_gem_domain(wd); cs->cs->cdw = cs->base.cdw; - retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0); + retval = radeon_cs_write_reloc(cs->cs, 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, 0); + bo, gem_rd, gem_wd, 0); } } +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; +} + boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs, - struct r300_winsys_buffer *_buf, + struct r300_winsys_cs_buffer *_buf, enum r300_reference_domain domain) { struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs); - struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf)); + struct radeon_bo *bo = (struct radeon_bo*)_buf; uint32_t tmp; if (domain & R300_REF_CS) { - if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) { + if (radeon_bo_is_referenced_by_cs(bo, cs->cs)) { return TRUE; } } if (domain & R300_REF_HW) { - if (radeon_bo_is_busy(buf->bo, &tmp)) { + if (radeon_bo_is_busy(bo, &tmp)) { return TRUE; } } diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index 3b3e2c2f281..412f3adca46 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -286,6 +286,7 @@ boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) ws->base.get_value = radeon_get_value; ws->base.buffer_create = radeon_r300_winsys_buffer_create; + ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle; 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;