diff options
Diffstat (limited to 'src/gallium/drivers')
233 files changed, 6797 insertions, 6828 deletions
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 8769b826b5f..c92f8e5cba2 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -21,7 +21,6 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a SOURCES = \ cell_batch.c \ - cell_buffer.c \ cell_clear.c \ cell_context.c \ cell_draw_arrays.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.c b/src/gallium/drivers/cell/ppu/cell_buffer.c deleted file mode 100644 index f56a28d62e2..00000000000 --- a/src/gallium/drivers/cell/ppu/cell_buffer.c +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 VMWARE AND/OR ITS 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 "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "cell_screen.h" -#include "cell_buffer.h" - - -static void * -cell_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned flags) -{ - struct cell_buffer *cell_buf = cell_buffer(buf); - return cell_buf->data; -} - - -static void -cell_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ -} - - -static void -cell_buffer_destroy(struct pipe_buffer *buf) -{ - struct cell_buffer *sbuf = cell_buffer(buf); - - if (!sbuf->userBuffer) - align_free(sbuf->data); - - FREE(sbuf); -} - - -static struct pipe_buffer * -cell_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct cell_buffer *buffer = CALLOC_STRUCT(cell_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.alignment = MAX2(alignment, 16); - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -cell_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct cell_buffer *buffer; - - buffer = CALLOC_STRUCT(cell_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -void -cell_init_screen_buffer_funcs(struct pipe_screen *screen) -{ - screen->buffer_create = cell_buffer_create; - screen->user_buffer_create = cell_user_buffer_create; - screen->buffer_map = cell_buffer_map; - screen->buffer_unmap = cell_buffer_unmap; - screen->buffer_destroy = cell_buffer_destroy; -} diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index f6cb1fc9be7..49cece58b8f 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -99,8 +99,8 @@ static const struct debug_named_value cell_debug_flags[] = { }; static unsigned int -cell_is_texture_referenced( struct pipe_context *pipe, - struct pipe_texture *texture, +cell_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, unsigned face, unsigned level) { /** @@ -110,16 +110,6 @@ cell_is_texture_referenced( struct pipe_context *pipe, return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; } -static unsigned int -cell_is_buffer_referenced( struct pipe_context *pipe, - struct pipe_buffer *buf) -{ - /** - * FIXME: Optimize. - */ - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} struct pipe_context * cell_create_context(struct pipe_screen *screen, @@ -144,8 +134,7 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.clear = cell_clear; cell->pipe.flush = cell_flush; - cell->pipe.is_texture_referenced = cell_is_texture_referenced; - cell->pipe.is_buffer_referenced = cell_is_buffer_referenced; + cell->pipe.is_resource_referenced = cell_is_resource_referenced; #if 0 cell->pipe.begin_query = cell_begin_query; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index f7e2284445d..07b6eebc69c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -122,11 +122,11 @@ struct cell_context struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - struct pipe_buffer *constants[2]; + struct pipe_resource *constants[2]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct cell_texture *texture[PIPE_MAX_SAMPLERS]; + struct cell_resource *texture[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; uint num_textures; struct pipe_viewport_state viewport; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 15d4e8338f4..80e94a79df7 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -39,7 +39,7 @@ #include "cell_draw_arrays.h" #include "cell_state.h" #include "cell_flush.h" -#include "cell_buffer.h" +#include "cell_texture.h" #include "draw/draw_context.h" @@ -57,7 +57,7 @@ */ static void cell_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -78,12 +78,12 @@ cell_draw_range_elements(struct pipe_context *pipe, * Map vertex buffers */ for (i = 0; i < cell->num_vertex_buffers; i++) { - void *buf = cell_buffer(cell->vertex_buffer[i].buffer)->data; + void *buf = cell_resource(cell->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = cell_buffer(indexBuffer)->data; + void *mapped_indexes = cell_resource(indexBuffer)->data; draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { @@ -116,7 +116,7 @@ cell_draw_range_elements(struct pipe_context *pipe, static void cell_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index 035ef41b898..eac798e8cf6 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -82,7 +82,7 @@ cell_fence_finish(const struct cell_context *cell, struct cell_buffer_node { - struct pipe_buffer *buffer; + struct pipe_resource *buffer; struct cell_buffer_node *next; }; @@ -90,12 +90,12 @@ struct cell_buffer_node static void cell_add_buffer_to_list(struct cell_context *cell, struct cell_buffer_list *list, - struct pipe_buffer *buffer) + struct pipe_resource *buffer) { struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node); /* create new list node which references the buffer, insert at head */ if (node) { - pipe_buffer_reference(&node->buffer, buffer); + pipe_resource_reference(&node->buffer, buffer); node->next = list->head; list->head = node; } @@ -129,7 +129,7 @@ cell_free_fenced_buffers(struct cell_context *cell, if (node->buffer->reference.count == 1) printf(" Delete!\n"); #endif - pipe_buffer_reference(&node->buffer, NULL); + pipe_resource_reference(&node->buffer, NULL); FREE(node); node = next; } @@ -150,7 +150,7 @@ cell_add_fenced_textures(struct cell_context *cell) uint i; for (i = 0; i < cell->num_textures; i++) { - struct cell_texture *ct = cell->texture[i]; + struct cell_resource *ct = cell->texture[i]; if (ct) { #if 0 printf("Adding texture %p buffer %p to list\n", diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 059ce8597bc..8c975c6ae2a 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -271,12 +271,12 @@ cell_set_fragment_sampler_views(struct pipe_context *pipe, struct pipe_sampler_view *old_view = cell->fragment_sampler_views[i]; if (old_view != new_view) { - struct pipe_texture *new_tex = new_view ? new_view->texture : NULL; + struct pipe_resource *new_tex = new_view ? new_view->texture : NULL; pipe_sampler_view_reference(&cell->fragment_sampler_views[i], views[i]); - pipe_texture_reference((struct pipe_texture **) &cell->texture[i], - (struct pipe_texture *) new_tex); + pipe_resource_reference((struct pipe_resource **) &cell->texture[i], + (struct pipe_resource *) new_tex); changed |= (1 << i); } @@ -293,7 +293,7 @@ cell_set_fragment_sampler_views(struct pipe_context *pipe, static struct pipe_sampler_view * cell_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -302,7 +302,7 @@ cell_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -314,7 +314,7 @@ static void cell_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } @@ -333,7 +333,7 @@ cell_map_surfaces(struct cell_context *cell) for (i = 0; i < 1; i++) { struct pipe_surface *ps = cell->framebuffer.cbufs[i]; if (ps) { - struct cell_texture *ct = cell_texture(ps->texture); + struct cell_resource *ct = cell_resource(ps->texture); #if 0 cell->cbuf_map[i] = screen->buffer_map(screen, ct->buffer, @@ -348,7 +348,7 @@ cell_map_surfaces(struct cell_context *cell) { struct pipe_surface *ps = cell->framebuffer.zsbuf; if (ps) { - struct cell_texture *ct = cell_texture(ps->texture); + struct cell_resource *ct = cell_resource(ps->texture); #if 0 cell->zsbuf_map = screen->buffer_map(screen, ct->buffer, @@ -374,7 +374,7 @@ cell_unmap_surfaces(struct cell_context *cell) for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { struct pipe_surface *ps = cell->framebuffer.cbufs[i]; if (ps && cell->cbuf_map[i]) { - /*struct cell_texture *ct = cell_texture(ps->texture);*/ + /*struct cell_resource *ct = cell_resource(ps->texture);*/ assert(ps->texture); /*assert(ct->buffer);*/ @@ -386,7 +386,7 @@ cell_unmap_surfaces(struct cell_context *cell) { struct pipe_surface *ps = cell->framebuffer.zsbuf; if (ps && cell->zsbuf_map) { - /*struct cell_texture *ct = cell_texture(ps->texture);*/ + /*struct cell_resource *ct = cell_resource(ps->texture);*/ /*screen->buffer_unmap(screen, ct->buffer);*/ cell->zsbuf_map = NULL; } diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index aaa16945c58..b4fd8d7235c 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -35,7 +35,6 @@ #include "cell_context.h" #include "cell_screen.h" #include "cell_texture.h" -#include "cell_buffer.h" #include "cell_public.h" #include "state_tracker/sw_winsys.h" @@ -138,12 +137,11 @@ cell_is_format_supported( struct pipe_screen *screen, unsigned tex_usage, unsigned geom_flags ) { - struct sw_winsys *winsys = cell_screen(screen)->winsys; - if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if (tex_usage & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } @@ -201,7 +199,6 @@ cell_create_screen(struct sw_winsys *winsys) screen->base.context_create = cell_create_context; cell_init_screen_texture_funcs(&screen->base); - cell_init_screen_buffer_funcs(&screen->base); return &screen->base; } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 424e2628a95..bb11c68fa24 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -241,7 +241,7 @@ cell_emit_state(struct cell_context *cell) if (cell->dirty & (CELL_NEW_FS_CONSTANTS)) { const uint shader = PIPE_SHADER_FRAGMENT; - const uint num_const = cell->constants[shader]->size / sizeof(float); + const uint num_const = cell->constants[shader]->width0 / sizeof(float); uint i, j; float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float))); uint32_t *ibuf = (uint32_t *) buf; @@ -293,7 +293,7 @@ cell_emit_state(struct cell_context *cell) texture->opcode[0] = CELL_CMD_STATE_TEXTURE; texture->unit = i; if (cell->texture[i]) { - struct cell_texture *ct = cell->texture[i]; + struct cell_resource *ct = cell->texture[i]; uint level; for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) { texture->start[level] = (ct->mapped + diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 9e29ddc2d45..ddf14772689 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -34,7 +34,7 @@ #include "cell_context.h" #include "cell_state.h" #include "cell_gen_fp.h" -#include "cell_buffer.h" +#include "cell_texture.h" /** cast wrapper */ @@ -183,11 +183,11 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs) static void cell_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *constants) + struct pipe_resource *constants) { struct cell_context *cell = cell_context(pipe); - unsigned size = constants ? constants->size : 0; - const void *data = constants ? cell_buffer(constants)->data : NULL; + unsigned size = constants ? constants->width0 : 0; + const void *data = constants ? cell_resource(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -198,7 +198,7 @@ cell_set_constant_buffer(struct pipe_context *pipe, draw_flush(cell->draw); /* note: reference counting */ - pipe_buffer_reference(&cell->constants[shader], constants); + pipe_resource_reference(&cell->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0, diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 6d746ebe0ae..8a379154d1b 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -42,17 +42,17 @@ #include "cell_context.h" #include "cell_screen.h" #include "cell_state.h" -#include "cell_texture.h" +#include "cell_resource.h" #include "state_tracker/sw_winsys.h" static boolean -cell_texture_layout(struct pipe_screen *screen, - struct cell_texture *ct) +cell_resource_layout(struct pipe_screen *screen, + struct cell_resource *ct) { - struct pipe_texture *pt = &ct->base; + struct pipe_resource *pt = &ct->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; @@ -98,14 +98,14 @@ cell_texture_layout(struct pipe_screen *screen, */ static boolean cell_displaytarget_layout(struct pipe_screen *screen, - struct cell_texture * ct) + struct cell_resource * ct) { struct sw_winsys *winsys = cell_screen(screen)->winsys; /* Round up the surface size to a multiple of the tile size? */ ct->dt = winsys->displaytarget_create(winsys, - ct->base.tex_usage, + ct->base.bind, ct->base.format, ct->base.width0, ct->base.height0, @@ -115,11 +115,11 @@ cell_displaytarget_layout(struct pipe_screen *screen, return ct->dt != NULL; } -static struct pipe_texture * -cell_texture_create(struct pipe_screen *screen, - const struct pipe_texture *templat) +static struct pipe_resource * +cell_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templat) { - struct cell_texture *ct = CALLOC_STRUCT(cell_texture); + struct cell_resource *ct = CALLOC_STRUCT(cell_resource); if (!ct) return NULL; @@ -130,14 +130,14 @@ cell_texture_create(struct pipe_screen *screen, /* Create both a displaytarget (linear) and regular texture * (twiddled). Convert twiddled->linear at flush_frontbuffer time. */ - if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if (ct->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if (!cell_displaytarget_layout(screen, ct)) goto fail; } - if (!cell_texture_layout(screen, ct)) + if (!cell_resource_layout(screen, ct)) goto fail; return &ct->base; @@ -155,18 +155,19 @@ fail: static void -cell_texture_destroy(struct pipe_texture *pt) +cell_resource_destroy(struct pipe_resource *pt) { struct cell_screen *screen = cell_screen(pt->screen); struct sw_winsys *winsys = screen->winsys; - struct cell_texture *ct = cell_texture(pt); + struct cell_resource *ct = cell_resource(pt); if (ct->dt) { /* display target */ winsys->displaytarget_destroy(winsys, ct->dt); } - - align_free(ct->data); + else if (!ct->userBuffer) { + align_free(ct->data); + } FREE(ct); } @@ -304,17 +305,17 @@ untwiddle_image_uint(uint w, uint h, uint tile_size, uint *dst, static struct pipe_surface * cell_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage) { - struct cell_texture *ct = cell_texture(pt); + struct cell_resource *ct = cell_resource(pt); struct pipe_surface *ps; ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); @@ -345,7 +346,7 @@ cell_get_tex_surface(struct pipe_screen *screen, static void cell_tex_surface_destroy(struct pipe_surface *surf) { - pipe_texture_reference(&surf->texture, NULL); + pipe_resource_reference(&surf->texture, NULL); FREE(surf); } @@ -356,46 +357,48 @@ cell_tex_surface_destroy(struct pipe_surface *surf) * back out for glGetTexImage). */ static struct pipe_transfer * -cell_get_tex_transfer(struct pipe_context *ctx, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +cell_get_transfer(struct pipe_context *ctx, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { - struct cell_texture *ct = cell_texture(texture); + struct cell_resource *ct = cell_resource(resource); struct cell_transfer *ctrans; + enum pipe_format *format = resource->format; + + assert(resource); + assert(level <= resource->last_level); - assert(texture); - assert(level <= texture->last_level); + /* make sure the requested region is in the image bounds */ + assert(box->x + box->width <= u_minify(resource->width0, sr.level)); + assert(box->y + box->height <= u_minify(resource->height0, sr.level)); + assert(box->z + box->depth <= u_minify(resource->depth0, sr.level)); ctrans = CALLOC_STRUCT(cell_transfer); if (ctrans) { struct pipe_transfer *pt = &ctrans->base; - pipe_texture_reference(&pt->texture, texture); - pt->x = x; - pt->y = y; - pt->width = w; - pt->height = h; - pt->stride = ct->stride[level]; + pipe_resource_reference(&pt->resource, resource); + pt->sr = sr; pt->usage = usage; - pt->face = face; - pt->level = level; - pt->zslice = zslice; + pt->box = *box; + pt->stride = ct->stride[sr.level]; - ctrans->offset = ct->level_offset[level]; + ctrans->offset = ct->level_offset[sr.level]; - if (texture->target == PIPE_TEXTURE_CUBE) { - unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE); - ctrans->offset += face * util_format_get_nblocksy(texture->format, h_tile) * pt->stride; + if (resource->target == PIPE_TEXTURE_CUBE) { + unsigned h_tile = align(u_minify(resource->height0, sr.level), TILE_SIZE); + ctrans->offset += sr.face * util_format_get_nblocksy(format, h_tile) * pt->stride; } - else if (texture->target == PIPE_TEXTURE_3D) { - unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE); - ctrans->offset += zslice * util_format_get_nblocksy(texture->format, h_tile) * pt->stride; + else if (resource->target == PIPE_TEXTURE_3D) { + unsigned h_tile = align(u_minify(resource->height0, sr.level), TILE_SIZE); + ctrans->offset += box->z * util_format_get_nblocksy(format, h_tile) * pt->stride; } else { - assert(face == 0); - assert(zslice == 0); + assert(sr.face == 0); + assert(box->z == 0); } + return pt; } return NULL; @@ -403,15 +406,15 @@ cell_get_tex_transfer(struct pipe_context *ctx, static void -cell_tex_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *t) +cell_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *t) { struct cell_transfer *transfer = cell_transfer(t); /* Effectively do the texture_update work here - if texture images * needed post-processing to put them into hardware layout, this is * where it would happen. For cell, nothing to do. */ - assert (transfer->base.texture); - pipe_texture_reference(&transfer->base.texture, NULL); + assert (transfer->base.resource); + pipe_resource_reference(&transfer->base.resource, NULL); FREE(transfer); } @@ -423,44 +426,63 @@ static void * cell_transfer_map(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct cell_transfer *ctrans = cell_transfer(transfer); - struct pipe_texture *pt = transfer->texture; - struct cell_texture *ct = cell_texture(pt); - const uint level = ctrans->base.level; - const uint texWidth = u_minify(pt->width0, level); - const uint texHeight = u_minify(pt->height0, level); - const uint stride = ct->stride[level]; - unsigned size; + struct pipe_resource *pt = transfer->resource; + struct cell_resource *ct = cell_resource(pt); - assert(transfer->texture); + assert(transfer->resource); if (ct->mapped == NULL) { ct->mapped = ct->data; } - /* - * Create a buffer of ordinary memory for the linear texture. - * This is the memory that the user will read/write. + + /* Better test would be resource->is_linear */ - size = util_format_get_stride(pt->format, align(texWidth, TILE_SIZE)) * - util_format_get_nblocksy(pt->format, align(texHeight, TILE_SIZE)); - - ctrans->map = align_malloc(size, 16); - if (!ctrans->map) - return NULL; /* out of memory */ - - if (transfer->usage & PIPE_TRANSFER_READ) { - /* need to untwiddle the texture to make a linear version */ - const uint bpp = util_format_get_blocksize(ct->base.format); - if (bpp == 4) { - const uint *src = (uint *) (ct->mapped + ctrans->offset); - uint *dst = ctrans->map; - untwiddle_image_uint(texWidth, texHeight, TILE_SIZE, - dst, stride, src); - } - else { - // xxx fix + if (transfer->resource->target != PIPE_BUFFER) { + const uint level = ctrans->base.sr.level; + const uint texWidth = u_minify(pt->width0, level); + const uint texHeight = u_minify(pt->height0, level); + unsigned size; + + + /* + * Create a buffer of ordinary memory for the linear texture. + * This is the memory that the user will read/write. + */ + size = (util_format_get_stride(pt->format, align(texWidth, TILE_SIZE)) * + util_format_get_nblocksy(pt->format, align(texHeight, TILE_SIZE))); + + ctrans->map = align_malloc(size, 16); + if (!ctrans->map) + return NULL; /* out of memory */ + + if (transfer->usage & PIPE_TRANSFER_READ) { + /* Textures always stored twiddled, need to untwiddle the + * texture to make a linear version. + */ + const uint bpp = util_format_get_blocksize(ct->base.format); + if (bpp == 4) { + const uint *src = (uint *) (ct->mapped + ctrans->offset); + uint *dst = ctrans->map; + untwiddle_image_uint(texWidth, texHeight, TILE_SIZE, + dst, transfer->stride, src); + } + else { + // xxx fix + } } } + else { + unsigned stride = transfer->stride; + enum pipe_format format = pt->format; + unsigned blocksize = util_format_get_blocksize(format); + + ctrans->map = (ct->mapped + + ctrans->offset + + ctrans->base.box.y / util_format_get_blockheight(format) * stride + + ctrans->base.box.x / util_format_get_blockwidth(format) * blocksize); + } + return ctrans->map; } @@ -476,9 +498,9 @@ cell_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct cell_transfer *ctrans = cell_transfer(transfer); - struct pipe_texture *pt = transfer->texture; - struct cell_texture *ct = cell_texture(pt); - const uint level = ctrans->base.level; + struct pipe_resource *pt = transfer->resource; + struct cell_resource *ct = cell_resource(pt); + const uint level = ctrans->base.sr.level; const uint texWidth = u_minify(pt->width0, level); const uint texHeight = u_minify(pt->height0, level); const uint stride = ct->stride[level]; @@ -488,22 +510,28 @@ cell_transfer_unmap(struct pipe_context *ctx, return; } - if (transfer->usage & PIPE_TRANSFER_WRITE) { - /* The user wrote new texture data into the mapped buffer. - * We need to convert the new linear data into the twiddled/tiled format. - */ - const uint bpp = util_format_get_blocksize(ct->base.format); - if (bpp == 4) { - const uint *src = ctrans->map; - uint *dst = (uint *) (ct->mapped + ctrans->offset); - twiddle_image_uint(texWidth, texHeight, TILE_SIZE, dst, stride, src); - } - else { - // xxx fix + if (pt->target != PIPE_BUFFER) { + if (transfer->usage & PIPE_TRANSFER_WRITE) { + /* The user wrote new texture data into the mapped buffer. + * We need to convert the new linear data into the twiddled/tiled format. + */ + const uint bpp = util_format_get_blocksize(ct->base.format); + if (bpp == 4) { + const uint *src = ctrans->map; + uint *dst = (uint *) (ct->mapped + ctrans->offset); + twiddle_image_uint(texWidth, texHeight, TILE_SIZE, dst, stride, src); + } + else { + // xxx fix + } } + + align_free(ctrans->map); + } + else { + /* nothing to do */ } - align_free(ctrans->map); ctrans->map = NULL; } @@ -525,7 +553,7 @@ cell_flush_frontbuffer(struct pipe_screen *_screen, { struct cell_screen *screen = cell_screen(_screen); struct sw_winsys *winsys = screen->winsys; - struct cell_texture *ct = cell_texture(surface->texture); + struct cell_resource *ct = cell_resource(surface->texture); if (!ct->dt) return; @@ -534,8 +562,8 @@ cell_flush_frontbuffer(struct pipe_screen *_screen, */ { unsigned *map = winsys->displaytarget_map(winsys, ct->dt, - (PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE)); + (PIPE_TRANSFER_READ | + PIPE_TRANSFER_WRITE)); unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]); untwiddle_image_uint(surface->width, @@ -552,11 +580,48 @@ cell_flush_frontbuffer(struct pipe_screen *_screen, } + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_resource * +cell_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags) +{ + struct cell_resource *buffer; + + buffer = CALLOC_STRUCT(cell_resource); + if(!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buffer->base.bind = PIPE_BIND_TRANSFER_READ | bind_flags; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.flags = 0; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + + + void cell_init_screen_texture_funcs(struct pipe_screen *screen) { - screen->texture_create = cell_texture_create; - screen->texture_destroy = cell_texture_destroy; + screen->resource_create = cell_resource_create; + screen->resource_destroy = cell_resource_destroy; + screen->resource_from_handle = cell_resource_from_handle; + screen->resource_get_handle = cell_resource_get_handle; + screen->user_buffer_create = cell_user_buffer_create; screen->get_tex_surface = cell_get_tex_surface; screen->tex_surface_destroy = cell_tex_surface_destroy; @@ -565,10 +630,13 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen) } void -cell_init_texture_transfer_funcs(struct cell_context *cell) +cell_init_transfer_funcs(struct cell_context *cell) { - cell->pipe.get_tex_transfer = cell_get_tex_transfer; - cell->pipe.tex_transfer_destroy = cell_tex_transfer_destroy; + cell->pipe.get_transfer = cell_get_transfer; + cell->pipe.transfer_destroy = cell_transfer_destroy; cell->pipe.transfer_map = cell_transfer_map; cell->pipe.transfer_unmap = cell_transfer_unmap; + + cell->pipe.transfer_flush_region = u_default_transfer_flush_region; + cell->pipe.transfer_inline_write = u_default_transfer_inline_write; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index ac0b9167750..bd8224b3b7b 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -31,21 +31,21 @@ #include "cell/common.h" struct cell_context; -struct pipe_texture; +struct pipe_resource; /** - * Subclass of pipe_texture + * Subclass of pipe_resource */ -struct cell_texture +struct cell_resource { - struct pipe_texture base; + struct pipe_resource base; unsigned long level_offset[CELL_MAX_TEXTURE_LEVELS]; unsigned long stride[CELL_MAX_TEXTURE_LEVELS]; /** - * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * Display target, for textures with the PIPE_BIND_DISPLAY_TARGET * usage. */ struct sw_displaytarget *dt; @@ -55,6 +55,7 @@ struct cell_texture * Malloc'ed data for regular textures, or a mapping to dt above. */ void *data; + boolean userBuffer; /* Size of the linear buffer?? */ @@ -77,10 +78,10 @@ struct cell_transfer /** cast wrapper */ -static INLINE struct cell_texture * -cell_texture(struct pipe_texture *pt) +static INLINE struct cell_resource * +cell_resource(struct pipe_resource *pt) { - return (struct cell_texture *) pt; + return (struct cell_resource *) pt; } diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h index 0ca92af248d..da9626024e7 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.h +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -75,7 +75,7 @@ struct softpipe_tile_cache; /**< Opaque to TGSI */ struct spu_sampler { const struct pipe_sampler_state *state; - struct pipe_texture *texture; + struct pipe_resource *texture; /** Get samples for four fragments in a quad */ void (*get_samples)(struct spu_sampler *sampler, const float s[QUAD_SIZE], diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 659e40cbf03..325a1009541 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -51,7 +51,7 @@ void failover_fail_over( struct failover_context *failover ) static void failover_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexResource, unsigned indexSize, unsigned prim, unsigned start, @@ -70,7 +70,7 @@ static void failover_draw_elements( struct pipe_context *pipe, */ if (failover->mode == FO_HW) { failover->hw->draw_elements( failover->hw, - indexBuffer, + indexResource, indexSize, prim, start, @@ -87,7 +87,7 @@ static void failover_draw_elements( struct pipe_context *pipe, } failover->sw->draw_elements( failover->sw, - indexBuffer, + indexResource, indexSize, prim, start, @@ -109,26 +109,15 @@ static void failover_draw_arrays( struct pipe_context *pipe, } static unsigned int -failover_is_texture_referenced( struct pipe_context *_pipe, - struct pipe_texture *texture, - unsigned face, unsigned level) +failover_is_resource_referenced( struct pipe_context *_pipe, + struct pipe_resource *resource, + unsigned face, unsigned level) { struct failover_context *failover = failover_context( _pipe ); struct pipe_context *pipe = (failover->mode == FO_HW) ? failover->hw : failover->sw; - return pipe->is_texture_referenced(pipe, texture, face, level); -} - -static unsigned int -failover_is_buffer_referenced( struct pipe_context *_pipe, - struct pipe_buffer *buf) -{ - struct failover_context *failover = failover_context( _pipe ); - struct pipe_context *pipe = (failover->mode == FO_HW) ? - failover->hw : failover->sw; - - return pipe->is_buffer_referenced(pipe, buf); + return pipe->is_resource_referenced(pipe, resource, face, level); } struct pipe_context *failover_create( struct pipe_context *hw, @@ -175,8 +164,7 @@ struct pipe_context *failover_create( struct pipe_context *hw, #endif failover->pipe.flush = hw->flush; - failover->pipe.is_texture_referenced = failover_is_texture_referenced; - failover->pipe.is_buffer_referenced = failover_is_buffer_referenced; + failover->pipe.is_resource_referenced = failover_is_resource_referenced; failover->dirty = 0; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 73031321d98..88ae5ad60d5 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -134,7 +134,7 @@ failover_context( struct pipe_context *pipe ) void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf); + struct pipe_resource *resource); #endif /* FO_CONTEXT_H */ diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 25c62735705..b682ce6750e 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -449,7 +449,7 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) static struct pipe_sampler_view * failover_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct fo_sampler_view *view = malloc(sizeof(struct fo_sampler_view)); @@ -461,7 +461,7 @@ failover_create_sampler_view(struct pipe_context *pipe, view->base = *templ; view->base.reference.count = 1; view->base.texture = NULL; - pipe_texture_reference(&view->base.texture, texture); + pipe_resource_reference(&view->base.texture, texture); view->base.context = pipe; return &view->base; @@ -477,7 +477,7 @@ failover_sampler_view_destroy(struct pipe_context *pipe, failover->sw->sampler_view_destroy(failover->sw, fo_view->sw); failover->hw->sampler_view_destroy(failover->hw, fo_view->hw); - pipe_texture_reference(&fo_view->base.texture, NULL); + pipe_resource_reference(&fo_view->base.texture, NULL); free(fo_view); } @@ -572,15 +572,15 @@ failover_set_vertex_buffers(struct pipe_context *pipe, void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_resource *res) { struct failover_context *failover = failover_context(pipe); assert(shader < PIPE_SHADER_TYPES); assert(index == 0); - failover->sw->set_constant_buffer(failover->sw, shader, index, buf); - failover->hw->set_constant_buffer(failover->hw, shader, index, buf); + failover->sw->set_constant_buffer(failover->sw, shader, index, res); + failover->hw->set_constant_buffer(failover->hw, shader, index, res); } diff --git a/src/gallium/drivers/i915/Makefile b/src/gallium/drivers/i915/Makefile index e33c74d02f7..2cefe708500 100644 --- a/src/gallium/drivers/i915/Makefile +++ b/src/gallium/drivers/i915/Makefile @@ -5,7 +5,6 @@ LIBNAME = i915 C_SOURCES = \ i915_blit.c \ - i915_buffer.c \ i915_clear.c \ i915_flush.c \ i915_context.c \ @@ -20,7 +19,9 @@ C_SOURCES = \ i915_screen.c \ i915_prim_emit.c \ i915_prim_vbuf.c \ - i915_texture.c \ + i915_resource.c \ + i915_resource_texture.c \ + i915_resource_buffer.c \ i915_fpc_emit.c \ i915_fpc_translate.c \ i915_surface.c diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript index 5a1c47c88db..7b69681096d 100644 --- a/src/gallium/drivers/i915/SConscript +++ b/src/gallium/drivers/i915/SConscript @@ -6,7 +6,7 @@ i915 = env.ConvenienceLibrary( target = 'i915', source = [ 'i915_blit.c', - 'i915_buffer.c', + 'i915_resource_buffer.c', 'i915_clear.c', 'i915_context.c', 'i915_debug.c', @@ -24,7 +24,8 @@ i915 = env.ConvenienceLibrary( 'i915_state_immediate.c', 'i915_state_sampler.c', 'i915_surface.c', - 'i915_texture.c', + 'i915_resource.c', + 'i915_resource_texture.c', ]) Export('i915') diff --git a/src/gallium/drivers/i915/i915_buffer.c b/src/gallium/drivers/i915/i915_buffer.c deleted file mode 100644 index 1247de320d4..00000000000 --- a/src/gallium/drivers/i915/i915_buffer.c +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 Jakob Bornecrantz - * - * 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 "util/u_inlines.h" -#include "util/u_memory.h" -#include "i915_screen.h" -#include "i915_buffer.h" - -struct i915_winsys_buffer; - -struct i915_buffer -{ - struct pipe_buffer base; - - struct i915_winsys_buffer *ibuf; /** hw buffer */ - - void *data; /**< user and malloc data */ - boolean own; /**< we own the data incase of malloc */ -}; - -static INLINE struct i915_buffer * -i915_buffer(struct pipe_buffer *buffer) -{ - return (struct i915_buffer *)buffer; -} - -static struct pipe_buffer * -i915_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); - - if (!buf) - return NULL; - - pipe_reference_init(&buf->base.reference, 1); - buf->base.alignment = alignment; - buf->base.screen = screen; - buf->base.usage = usage; - buf->base.size = size; - buf->data = MALLOC(size); - buf->own = TRUE; - - if (!buf->data) - goto err; - - return &buf->base; - -err: - FREE(buf); - return NULL; -} - -static struct pipe_buffer * -i915_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); - - if (!buf) - return NULL; - - pipe_reference_init(&buf->base.reference, 1); - buf->base.alignment = 0; - buf->base.screen = screen; - buf->base.usage = 0; - buf->base.size = bytes; - buf->data = ptr; - buf->own = FALSE; - - return &buf->base; -} - -static void * -i915_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned usage) -{ - struct i915_buffer *buf = i915_buffer(buffer); - assert(!buf->ibuf); - return buf->data; -} - -static void -i915_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buffer) -{ - struct i915_buffer *buf = i915_buffer(buffer); - assert(!buf->ibuf); - (void) buf; -} - -static void -i915_buffer_destroy(struct pipe_buffer *buffer) -{ - struct i915_buffer *buf = i915_buffer(buffer); - assert(!buf->ibuf); - - if (buf->own) - FREE(buf->data); - FREE(buf); -} - -void i915_init_screen_buffer_functions(struct i915_screen *screen) -{ - screen->base.buffer_create = i915_buffer_create; - screen->base.user_buffer_create = i915_user_buffer_create; - screen->base.buffer_map = i915_buffer_map; - screen->base.buffer_map_range = NULL; - screen->base.buffer_flush_mapped_range = NULL; - screen->base.buffer_unmap = i915_buffer_unmap; - screen->base.buffer_destroy = i915_buffer_destroy; -} diff --git a/src/gallium/drivers/i915/i915_buffer.h b/src/gallium/drivers/i915/i915_buffer.h deleted file mode 100644 index 80fda7c62fd..00000000000 --- a/src/gallium/drivers/i915/i915_buffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 Jakob Bornecrantz - * - * 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - **************************************************************************/ - -#ifndef I915_BUFFER_H -#define I915_BUFFER_H - -void i915_init_screen_buffer_functions(struct i915_screen *screen); - -#endif diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 130519ffa50..4ae52911158 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -28,7 +28,9 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_screen.h" +#include "i915_surface.h" #include "i915_batch.h" +#include "i915_resource.h" #include "draw/draw_context.h" #include "pipe/p_defines.h" @@ -44,7 +46,7 @@ static void i915_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -61,8 +63,7 @@ i915_draw_range_elements(struct pipe_context *pipe, * Map vertex buffers */ for (i = 0; i < i915->num_vertex_buffers; i++) { - void *buf = pipe_buffer_map(pipe->screen, i915->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *buf = i915_buffer(i915->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } @@ -70,8 +71,7 @@ i915_draw_range_elements(struct pipe_context *pipe, * Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = pipe_buffer_map(pipe->screen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *mapped_indexes = i915_buffer(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, min_index, max_index, @@ -95,19 +95,17 @@ i915_draw_range_elements(struct pipe_context *pipe, * unmap vertex/index buffers */ for (i = 0; i < i915->num_vertex_buffers; i++) { - pipe_buffer_unmap(pipe->screen, i915->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, NULL); } if (indexBuffer) { - pipe_buffer_unmap(pipe->screen, indexBuffer); - draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); + draw_set_mapped_element_buffer(draw, 0, NULL); } } static void i915_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned prim, unsigned start, unsigned count) { @@ -125,37 +123,6 @@ i915_draw_arrays(struct pipe_context *pipe, } -/* - * Is referenced functions - */ - - -static unsigned int -i915_is_texture_referenced(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - /** - * FIXME: Return the corrent result. We can't alays return referenced - * since it causes a double flush within the vbo module. - */ -#if 0 - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -#else - return 0; -#endif -} - -static unsigned int -i915_is_buffer_referenced(struct pipe_context *pipe, - struct pipe_buffer *buf) -{ - /* - * Since we never expose hardware buffers to the state tracker - * they can never be referenced, so this isn't a lie - */ - return 0; -} /* @@ -204,9 +171,6 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->base.draw_elements = i915_draw_elements; i915->base.draw_range_elements = i915_draw_range_elements; - i915->base.is_texture_referenced = i915_is_texture_referenced; - i915->base.is_buffer_referenced = i915_is_buffer_referenced; - /* * Create drawing context and plug our rendering stage into it. */ @@ -221,7 +185,7 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915_init_surface_functions(i915); i915_init_state_functions(i915); i915_init_flush_functions(i915); - i915_init_texture_functions(i915); + i915_init_resource_functions(i915); draw_install_aaline_stage(i915->draw, &i915->base); draw_install_aapoint_stage(i915->draw, &i915->base); diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 8df4dce8653..acc0ffe037f 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -192,35 +192,6 @@ struct i915_velems_state { struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; }; -#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */ -#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */ - -struct i915_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned stride; - unsigned depth_stride; /* per-image on i945? */ - unsigned total_nblocksy; - - unsigned sw_tiled; /**< tiled with software flags */ - unsigned hw_tiled; /**< tiled with hardware fences */ - - unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */ - - /* The data is held here: - */ - struct i915_winsys_buffer *buffer; -}; struct i915_context { @@ -243,7 +214,7 @@ struct i915_context struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; /* XXX unneded */ - struct pipe_buffer *constants[PIPE_SHADER_TYPES]; + struct pipe_resource *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -333,10 +304,8 @@ void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba, /*********************************************************************** - * i915_surface.c: + * */ -void i915_init_surface_functions( struct i915_context *i915 ); - void i915_init_state_functions( struct i915_context *i915 ); void i915_init_flush_functions( struct i915_context *i915 ); void i915_init_string_functions( struct i915_context *i915 ); @@ -349,10 +318,6 @@ struct pipe_context *i915_create_context(struct pipe_screen *screen, void *priv); -/*********************************************************************** - * i915_texture.c - */ -void i915_init_texture_functions(struct i915_context *i915 ); /*********************************************************************** diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c new file mode 100644 index 00000000000..499233ceb9b --- /dev/null +++ b/src/gallium/drivers/i915/i915_resource.c @@ -0,0 +1,51 @@ +#include "util/u_debug.h" + +#include "i915_resource.h" +#include "i915_context.h" +#include "i915_screen.h" + + +static struct pipe_resource * +i915_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return i915_buffer_create(screen, template); + else + return i915_texture_create(screen, template); + +} + +static struct pipe_resource * +i915_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return i915_texture_from_handle(screen, template, whandle); +} + + +void +i915_init_resource_functions(struct i915_context *i915 ) +{ + i915->base.is_resource_referenced = u_default_is_resource_referenced; + i915->base.get_transfer = u_get_transfer_vtbl; + i915->base.transfer_map = u_transfer_map_vtbl; + i915->base.transfer_flush_region = u_transfer_flush_region_vtbl; + i915->base.transfer_unmap = u_transfer_unmap_vtbl; + i915->base.transfer_destroy = u_transfer_destroy_vtbl; + i915->base.transfer_inline_write = u_transfer_inline_write_vtbl; +} + +void +i915_init_screen_resource_functions(struct i915_screen *is) +{ + is->base.resource_create = i915_resource_create; + is->base.resource_from_handle = i915_resource_from_handle; + is->base.resource_get_handle = u_resource_get_handle_vtbl; + is->base.resource_destroy = u_resource_destroy_vtbl; + is->base.user_buffer_create = i915_user_buffer_create; +} diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h new file mode 100644 index 00000000000..e5951395845 --- /dev/null +++ b/src/gallium/drivers/i915/i915_resource.h @@ -0,0 +1,114 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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. + * + **************************************************************************/ + +#ifndef I915_RESOURCE_H +#define I915_RESOURCE_H + +struct i915_screen; + +#include "util/u_transfer.h" +#include "util/u_debug.h" + + +struct i915_context; +struct i915_screen; + + +struct i915_buffer { + struct u_resource b; + uint8_t *data; + boolean free_on_destroy; +}; + +#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */ +#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */ + + + +struct i915_texture { + struct u_resource b; + + unsigned stride; + unsigned depth_stride; /* per-image on i945? */ + unsigned total_nblocksy; + + unsigned sw_tiled; /**< tiled with software flags */ + unsigned hw_tiled; /**< tiled with hardware fences */ + + unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. + */ + unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */ + + /* The data is held here: + */ + struct i915_winsys_buffer *buffer; +}; + +void i915_init_screen_resource_functions(struct i915_screen *is); +void i915_init_resource_functions(struct i915_context *i915 ); + +extern struct u_resource_vtbl i915_buffer_vtbl; +extern struct u_resource_vtbl i915_texture_vtbl; + +static INLINE struct i915_texture *i915_texture( struct pipe_resource *resource ) +{ + struct i915_texture *tex = (struct i915_texture *)resource; + assert(tex->b.vtbl == &i915_texture_vtbl); + return tex; +} + +static INLINE struct i915_buffer *i915_buffer( struct pipe_resource *resource ) +{ + struct i915_buffer *tex = (struct i915_buffer *)resource; + assert(tex->b.vtbl == &i915_buffer_vtbl); + return tex; +} + +struct pipe_resource * +i915_texture_create(struct pipe_screen *screen, + const struct pipe_resource *template); + +struct pipe_resource * +i915_texture_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle); + + +struct pipe_resource * +i915_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + +struct pipe_resource * +i915_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template); + +#endif /* I915_RESOURCE_H */ diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c new file mode 100644 index 00000000000..3f3c658e47c --- /dev/null +++ b/src/gallium/drivers/i915/i915_resource_buffer.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <[email protected]> + * Michel Dänzer <[email protected]> + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "i915_context.h" +#include "i915_resource.h" +#include "i915_screen.h" + + + +static boolean +i915_buffer_get_handle(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle) +{ + return FALSE; +} + +static void +i915_buffer_destroy(struct pipe_screen *screen, + struct pipe_resource *resource) +{ + struct i915_buffer *buffer = i915_buffer(resource); + if (buffer->free_on_destroy) + align_free(buffer->data); + FREE(buffer); +} + + +static void * +i915_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct i915_buffer *buffer = i915_buffer(transfer->resource); + return buffer->data + transfer->box.x; +} + + +static void +i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ + struct i915_buffer *buffer = i915_buffer(resource); + + memcpy(buffer->data + box->x, + data, + box->width); +} + + +struct u_resource_vtbl i915_buffer_vtbl = +{ + i915_buffer_get_handle, /* get_handle */ + i915_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + i915_buffer_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + u_default_transfer_unmap, /* transfer_unmap */ + i915_buffer_transfer_inline_write /* transfer_inline_write */ +}; + + + +struct pipe_resource * +i915_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); + + if (!buf) + return NULL; + + buf->b.b = *template; + buf->b.vtbl = &i915_buffer_vtbl; + pipe_reference_init(&buf->b.b.reference, 1); + buf->b.b.screen = screen; + + buf->data = MALLOC(template->width0); + buf->free_on_destroy = TRUE; + + if (!buf->data) + goto err; + + return &buf->b.b; + +err: + FREE(buf); + return NULL; +} + + + +struct pipe_resource * +i915_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind) +{ + struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); + + if (!buf) + return NULL; + + pipe_reference_init(&buf->b.b.reference, 1); + buf->b.vtbl = &i915_buffer_vtbl; + buf->b.b.screen = screen; + buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buf->b.b._usage = PIPE_USAGE_IMMUTABLE; + buf->b.b.bind = bind; + buf->b.b.flags = 0; + buf->b.b.width0 = bytes; + buf->b.b.height0 = 1; + buf->b.b.depth0 = 1; + + buf->data = ptr; + buf->free_on_destroy = FALSE; + + return &buf->b.b; +} diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 8c405c2443e..b2599688353 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -39,7 +39,7 @@ #include "util/u_memory.h" #include "i915_context.h" -#include "i915_texture.h" +#include "i915_resource.h" #include "i915_screen.h" #include "i915_winsys.h" @@ -91,7 +91,7 @@ power_of_two(unsigned x) static void -i915_miptree_set_level_info(struct i915_texture *tex, +i915_texture_set_level_info(struct i915_texture *tex, unsigned level, unsigned nr_images, unsigned w, unsigned h, unsigned d) @@ -120,7 +120,7 @@ i915_miptree_set_level_info(struct i915_texture *tex, } static void -i915_miptree_set_image_offset(struct i915_texture *tex, +i915_texture_set_image_offset(struct i915_texture *tex, unsigned level, unsigned img, unsigned x, unsigned y) { if (img == 0 && level == 0) @@ -128,7 +128,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); - tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->base.format); + tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->b.b.format); /* printf("%s level %d img %d pos %d,%d image_offset %x\n", @@ -148,16 +148,16 @@ i915_miptree_set_image_offset(struct i915_texture *tex, static boolean i915_scanout_layout(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4) return FALSE; - i915_miptree_set_level_info(tex, 0, 1, + i915_texture_set_level_info(tex, 0, 1, pt->width0, pt->height0, 1); - i915_miptree_set_image_offset(tex, 0, 0, 0, 0); + i915_texture_set_image_offset(tex, 0, 0, 0, 0); if (pt->width0 >= 240) { tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0)); @@ -183,7 +183,7 @@ i915_scanout_layout(struct i915_texture *tex) static boolean i915_display_target_layout(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4) return FALSE; @@ -192,11 +192,11 @@ i915_display_target_layout(struct i915_texture *tex) if (pt->width0 < 240) return FALSE; - i915_miptree_set_level_info(tex, 0, 1, + i915_texture_set_level_info(tex, 0, 1, pt->width0, pt->height0, 1); - i915_miptree_set_image_offset(tex, 0, 0, 0, 0); + i915_texture_set_image_offset(tex, 0, 0, 0, 0); tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0)); tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8); @@ -210,21 +210,26 @@ i915_display_target_layout(struct i915_texture *tex) } static void -i915_miptree_layout_2d(struct i915_texture *tex) +i915_texture_layout_2d(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0); /* used for scanouts that need special layouts */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) + if (pt->bind & PIPE_BIND_SCANOUT) if (i915_scanout_layout(tex)) return; - /* shared buffers needs to be compatible with X servers */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED) + /* shared buffers needs to be compatible with X servers + * + * XXX: need a better name than shared for this if it is to be part + * of core gallium, and probably move the flag to resource.flags, + * rather than bindings. + */ + if (pt->bind & PIPE_BIND_SHARED) if (i915_display_target_layout(tex)) return; @@ -232,8 +237,8 @@ i915_miptree_layout_2d(struct i915_texture *tex) tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 1, width, height, 1); - i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy); + i915_texture_set_level_info(tex, level, 1, width, height, 1); + i915_texture_set_image_offset(tex, level, 0, 0, tex->total_nblocksy); nblocksy = align(MAX2(2, nblocksy), 2); @@ -246,9 +251,9 @@ i915_miptree_layout_2d(struct i915_texture *tex) } static void -i915_miptree_layout_3d(struct i915_texture *tex) +i915_texture_layout_3d(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; unsigned level; unsigned width = pt->width0; @@ -264,7 +269,7 @@ i915_miptree_layout_3d(struct i915_texture *tex) /* XXX: hardware expects/requires 9 levels at minimum. */ for (level = 0; level <= MAX2(8, pt->last_level); level++) { - i915_miptree_set_level_info(tex, level, depth, width, height, depth); + i915_texture_set_level_info(tex, level, depth, width, height, depth); stack_nblocksy += MAX2(2, nblocksy); @@ -278,7 +283,7 @@ i915_miptree_layout_3d(struct i915_texture *tex) for (level = 0; level <= pt->last_level; level++) { unsigned i; for (i = 0; i < depth; i++) - i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy); + i915_texture_set_image_offset(tex, level, i, 0, i * stack_nblocksy); depth = u_minify(depth, 1); } @@ -291,9 +296,9 @@ i915_miptree_layout_3d(struct i915_texture *tex) } static void -i915_miptree_layout_cube(struct i915_texture *tex) +i915_texture_layout_cube(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; unsigned width = pt->width0, height = pt->height0; const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0); unsigned level; @@ -306,7 +311,7 @@ i915_miptree_layout_cube(struct i915_texture *tex) tex->total_nblocksy = nblocks * 4; for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, width, height, 1); + i915_texture_set_level_info(tex, level, 6, width, height, 1); width /= 2; height /= 2; } @@ -317,7 +322,7 @@ i915_miptree_layout_cube(struct i915_texture *tex) unsigned d = nblocks; for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_image_offset(tex, level, face, x, y); + i915_texture_set_image_offset(tex, level, face, x, y); d >>= 1; x += step_offsets[face][0] * d; y += step_offsets[face][1] * d; @@ -326,20 +331,20 @@ i915_miptree_layout_cube(struct i915_texture *tex) } static boolean -i915_miptree_layout(struct i915_texture * tex) +i915_texture_layout(struct i915_texture * tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; switch (pt->target) { case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: - i915_miptree_layout_2d(tex); + i915_texture_layout_2d(tex); break; case PIPE_TEXTURE_3D: - i915_miptree_layout_3d(tex); + i915_texture_layout_3d(tex); break; case PIPE_TEXTURE_CUBE: - i915_miptree_layout_cube(tex); + i915_texture_layout_cube(tex); break; default: assert(0); @@ -356,9 +361,9 @@ i915_miptree_layout(struct i915_texture * tex) static void -i945_miptree_layout_2d(struct i915_texture *tex) +i945_texture_layout_2d(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; const int align_x = 2, align_y = 4; unsigned level; unsigned x = 0; @@ -369,12 +374,12 @@ i945_miptree_layout_2d(struct i915_texture *tex) unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0); /* used for scanouts that need special layouts */ - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) + if (tex->b.b.bind & PIPE_BIND_SCANOUT) if (i915_scanout_layout(tex)) return; /* shared buffers needs to be compatible with X servers */ - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED) + if (tex->b.b.bind & PIPE_BIND_SHARED) if (i915_display_target_layout(tex)) return; @@ -400,8 +405,8 @@ i945_miptree_layout_2d(struct i915_texture *tex) tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 1, width, height, 1); - i915_miptree_set_image_offset(tex, level, 0, x, y); + i915_texture_set_level_info(tex, level, 1, width, height, 1); + i915_texture_set_image_offset(tex, level, 0, x, y); nblocksy = align(nblocksy, align_y); @@ -427,9 +432,9 @@ i945_miptree_layout_2d(struct i915_texture *tex) } static void -i945_miptree_layout_3d(struct i915_texture *tex) +i945_texture_layout_3d(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; unsigned width = pt->width0; unsigned height = pt->height0; unsigned depth = pt->depth0; @@ -450,11 +455,11 @@ i945_miptree_layout_3d(struct i915_texture *tex) int y = 0; unsigned q, j; - i915_miptree_set_level_info(tex, level, depth, width, height, depth); + i915_texture_set_level_info(tex, level, depth, width, height, depth); for (q = 0; q < depth;) { for (j = 0; j < pack_x_nr && q < depth; j++, q++) { - i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); + i915_texture_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); x += pack_x_pitch; } @@ -482,9 +487,9 @@ i945_miptree_layout_3d(struct i915_texture *tex) } static void -i945_miptree_layout_cube(struct i915_texture *tex) +i945_texture_layout_cube(struct i915_texture *tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; unsigned level; const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0); @@ -516,7 +521,7 @@ i945_miptree_layout_cube(struct i915_texture *tex) /* Set all the levels to effectively occupy the whole rectangular region. */ for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, width, height, 1); + i915_texture_set_level_info(tex, level, 6, width, height, 1); width /= 2; height /= 2; } @@ -538,7 +543,7 @@ i945_miptree_layout_cube(struct i915_texture *tex) #endif for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_image_offset(tex, level, face, x, y); + i915_texture_set_image_offset(tex, level, face, x, y); d >>= 1; @@ -583,20 +588,20 @@ i945_miptree_layout_cube(struct i915_texture *tex) } static boolean -i945_miptree_layout(struct i915_texture * tex) +i945_texture_layout(struct i915_texture * tex) { - struct pipe_texture *pt = &tex->base; + struct pipe_resource *pt = &tex->b.b; switch (pt->target) { case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: - i945_miptree_layout_2d(tex); + i945_texture_layout_2d(tex); break; case PIPE_TEXTURE_3D: - i945_miptree_layout_3d(tex); + i945_texture_layout_3d(tex); break; case PIPE_TEXTURE_CUBE: - i945_miptree_layout_cube(tex); + i945_texture_layout_cube(tex); break; default: assert(0); @@ -607,14 +612,135 @@ i945_miptree_layout(struct i915_texture * tex) } + /* * Screen texture functions */ -static struct pipe_texture * + +static boolean +i915_texture_get_handle(struct pipe_screen * screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) +{ + struct i915_screen *is = i915_screen(screen); + struct i915_texture *tex = i915_texture(texture); + struct i915_winsys *iws = is->iws; + + return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride); +} + + +static void +i915_texture_destroy(struct pipe_screen *screen, + struct pipe_resource *pt) +{ + struct i915_texture *tex = i915_texture(pt); + struct i915_winsys *iws = i915_screen(screen)->iws; + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); + */ + + iws->buffer_destroy(iws, tex->buffer); + + for (i = 0; i < Elements(tex->image_offset); i++) + if (tex->image_offset[i]) + FREE(tex->image_offset[i]); + + FREE(tex); +} + +static struct pipe_transfer * +i915_texture_get_transfer(struct pipe_context *context, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct i915_texture *tex = i915_texture(resource); + struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer); + if (transfer == NULL) + return NULL; + + transfer->resource = resource; + transfer->sr = sr; + transfer->usage = usage; + transfer->box = *box; + transfer->stride = tex->stride; + + return transfer; +} + + +static void * +i915_texture_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct pipe_resource *resource = transfer->resource; + struct i915_texture *tex = i915_texture(resource); + struct i915_winsys *iws = i915_screen(pipe->screen)->iws; + struct pipe_subresource sr = transfer->sr; + struct pipe_box *box = &transfer->box; + enum pipe_format format = resource->format; + unsigned offset; + char *map; + + if (resource->target == PIPE_TEXTURE_CUBE) { + offset = tex->image_offset[sr.level][sr.face]; + } + else if (resource->target == PIPE_TEXTURE_3D) { + offset = tex->image_offset[sr.level][box->z]; + } + else { + offset = tex->image_offset[sr.level][0]; + assert(sr.face == 0); + assert(box->z == 0); + } + + map = iws->buffer_map(iws, + tex->buffer, + (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE); + if (map == NULL) + return NULL; + + return map + offset + + box->y / util_format_get_blockheight(format) * transfer->stride + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); +} + +static void +i915_texture_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct i915_texture *tex = i915_texture(transfer->resource); + struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws; + iws->buffer_unmap(iws, tex->buffer); +} + + + +struct u_resource_vtbl i915_texture_vtbl = +{ + i915_texture_get_handle, /* get_handle */ + i915_texture_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + i915_texture_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + i915_texture_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + i915_texture_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + + +struct pipe_resource * i915_texture_create(struct pipe_screen *screen, - const struct pipe_texture *templat) + const struct pipe_resource *template) { struct i915_screen *is = i915_screen(screen); struct i915_winsys *iws = is->iws; @@ -625,24 +751,27 @@ i915_texture_create(struct pipe_screen *screen, if (!tex) return NULL; - tex->base = *templat; - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; + tex->b.b = *template; + tex->b.vtbl = &i915_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; if (is->is_i945) { - if (!i945_miptree_layout(tex)) + if (!i945_texture_layout(tex)) goto fail; } else { - if (!i915_miptree_layout(tex)) + if (!i915_texture_layout(tex)) goto fail; } tex_size = tex->stride * tex->total_nblocksy; - - /* for scanouts and cursors, cursors arn't scanouts */ - if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64) + + /* XXX: use a custom flag for cursors, don't rely on magically + * guessing that this is Xorg asking for a cursor + */ + if ((template->bind & PIPE_BIND_SCANOUT) && template->width0 != 64) buf_usage = I915_NEW_SCANOUT; else buf_usage = I915_NEW_TEXTURE; @@ -665,17 +794,17 @@ i915_texture_create(struct pipe_screen *screen, ws->buffer_unmap(ws, tex->buffer); #endif - return &tex->base; + return &tex->b.b; fail: FREE(tex); return NULL; } -static struct pipe_texture * +struct pipe_resource * i915_texture_from_handle(struct pipe_screen * screen, - const struct pipe_texture *templat, - struct winsys_handle *whandle) + const struct pipe_resource *template, + struct winsys_handle *whandle) { struct i915_screen *is = i915_screen(screen); struct i915_texture *tex; @@ -688,9 +817,9 @@ i915_texture_from_handle(struct pipe_screen * screen, buffer = iws->buffer_from_handle(iws, whandle, &stride); /* Only supports one type */ - if (templat->target != PIPE_TEXTURE_2D || - templat->last_level != 0 || - templat->depth0 != 1) { + if (template->target != PIPE_TEXTURE_2D || + template->last_level != 0 || + template->depth0 != 1) { return NULL; } @@ -698,204 +827,18 @@ i915_texture_from_handle(struct pipe_screen * screen, if (!tex) return NULL; - tex->base = *templat; - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; + tex->b.b = *template; + tex->b.vtbl = &i915_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; tex->stride = stride; - i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1); - i915_miptree_set_image_offset(tex, 0, 0, 0, 0); + i915_texture_set_level_info(tex, 0, 1, template->width0, template->height0, 1); + i915_texture_set_image_offset(tex, 0, 0, 0, 0); tex->buffer = buffer; - return &tex->base; -} - -static boolean -i915_texture_get_handle(struct pipe_screen * screen, - struct pipe_texture *texture, - struct winsys_handle *whandle) -{ - struct i915_screen *is = i915_screen(screen); - struct i915_texture *tex = (struct i915_texture *)texture; - struct i915_winsys *iws = is->iws; - - return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride); -} - - -static void -i915_texture_destroy(struct pipe_texture *pt) -{ - struct i915_texture *tex = (struct i915_texture *)pt; - struct i915_winsys *iws = i915_screen(pt->screen)->iws; - uint i; - - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); - */ - - iws->buffer_destroy(iws, tex->buffer); - - for (i = 0; i < Elements(tex->image_offset); i++) - if (tex->image_offset[i]) - FREE(tex->image_offset[i]); - - FREE(tex); -} - - -/* - * Screen surface functions - */ - - -static struct pipe_surface * -i915_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct i915_texture *tex = (struct i915_texture *)pt; - struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset = tex->image_offset[level][face]; - } - else if (pt->target == PIPE_TEXTURE_3D) { - offset = tex->image_offset[level][zslice]; - } - else { - offset = tex->image_offset[level][0]; - assert(face == 0); - assert(zslice == 0); - } - - ps = CALLOC_STRUCT(pipe_surface); - if (ps) { - pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); - ps->format = pt->format; - ps->width = u_minify(pt->width0, level); - ps->height = u_minify(pt->height0, level); - ps->offset = offset; - ps->usage = flags; - } - return ps; -} - -static void -i915_tex_surface_destroy(struct pipe_surface *surf) -{ - pipe_texture_reference(&surf->texture, NULL); - FREE(surf); -} - - -/* - * Texture transfer functions - */ - - -static struct pipe_transfer * -i915_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, unsigned x, unsigned y, - unsigned w, unsigned h) -{ - struct i915_texture *tex = (struct i915_texture *)texture; - struct i915_transfer *trans; - unsigned offset; /* in bytes */ - - if (texture->target == PIPE_TEXTURE_CUBE) { - offset = tex->image_offset[level][face]; - } - else if (texture->target == PIPE_TEXTURE_3D) { - offset = tex->image_offset[level][zslice]; - } - else { - offset = tex->image_offset[level][0]; - assert(face == 0); - assert(zslice == 0); - } - - trans = CALLOC_STRUCT(i915_transfer); - if (trans) { - pipe_texture_reference(&trans->base.texture, texture); - trans->base.x = x; - trans->base.y = y; - trans->base.width = w; - trans->base.height = h; - trans->base.stride = tex->stride; - trans->offset = offset; - trans->base.usage = usage; - } - return &trans->base; -} - -static void * -i915_transfer_map(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct i915_texture *tex = (struct i915_texture *)transfer->texture; - struct i915_winsys *iws = i915_screen(tex->base.screen)->iws; - char *map; - boolean write = FALSE; - enum pipe_format format = tex->base.format; - - if (transfer->usage & PIPE_TRANSFER_WRITE) - write = TRUE; - - map = iws->buffer_map(iws, tex->buffer, write); - if (map == NULL) - return NULL; - - return map + i915_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); -} - -static void -i915_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct i915_texture *tex = (struct i915_texture *)transfer->texture; - struct i915_winsys *iws = i915_screen(tex->base.screen)->iws; - iws->buffer_unmap(iws, tex->buffer); -} - -static void -i915_tex_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *trans) -{ - pipe_texture_reference(&trans->texture, NULL); - FREE(trans); -} - - -/* - * Other texture functions - */ - -void -i915_init_texture_functions(struct i915_context *i915 ) -{ - i915->base.get_tex_transfer = i915_get_tex_transfer; - i915->base.transfer_map = i915_transfer_map; - i915->base.transfer_unmap = i915_transfer_unmap; - i915->base.tex_transfer_destroy = i915_tex_transfer_destroy; + return &tex->b.b; } -void -i915_init_screen_texture_functions(struct i915_screen *is) -{ - is->base.texture_create = i915_texture_create; - is->base.texture_from_handle = i915_texture_from_handle; - is->base.texture_get_handle = i915_texture_get_handle; - is->base.texture_destroy = i915_texture_destroy; - is->base.get_tex_surface = i915_get_tex_surface; - is->base.tex_surface_destroy = i915_tex_surface_destroy; -} diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 4ccc66b0373..9086f9fc3b1 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -33,8 +33,8 @@ #include "i915_reg.h" #include "i915_context.h" #include "i915_screen.h" -#include "i915_buffer.h" -#include "i915_texture.h" +#include "i915_surface.h" +#include "i915_resource.h" #include "i915_winsys.h" @@ -190,7 +190,7 @@ i915_is_format_supported(struct pipe_screen *screen, const enum pipe_format *list; uint i; - if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) + if(tex_usage & PIPE_BIND_RENDER_TARGET) list = surface_supported; else list = tex_supported; @@ -308,8 +308,8 @@ i915_create_screen(struct i915_winsys *iws, uint pci_id) is->base.fence_signalled = i915_fence_signalled; is->base.fence_finish = i915_fence_finish; - i915_init_screen_texture_functions(is); - i915_init_screen_buffer_functions(is); + i915_init_screen_resource_functions(is); + i915_init_screen_surface_functions(is); return &is->base; } diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 0f7395246cc..bc2f1b268a0 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -39,6 +39,7 @@ #include "i915_reg.h" #include "i915_state_inlines.h" #include "i915_fpc.h" +#include "i915_resource.h" /* The i915 (and related graphics cores) do not support GL_CLAMP. The * Intel drivers for "other operating systems" implement GL_CLAMP as @@ -523,10 +524,10 @@ static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) static void i915_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_resource *buf) { struct i915_context *i915 = i915_context(pipe); - struct pipe_screen *screen = pipe->screen; + struct i915_buffer *ir = i915_buffer(buf); draw_flush(i915->draw); assert(shader < PIPE_SHADER_TYPES); @@ -542,19 +543,14 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, * N constants, leaving any extras from shader translation alone. */ if (buf) { - void *mapped; - if (buf->size && - (mapped = pipe_buffer_map(screen, buf, - PIPE_BUFFER_USAGE_CPU_READ))) { - memcpy(i915->current.constants[shader], mapped, buf->size); - pipe_buffer_unmap(screen, buf); - i915->current.num_user_constants[shader] - = buf->size / (4 * sizeof(float)); - } - else { - i915->current.num_user_constants[shader] = 0; - } + memcpy(i915->current.constants[shader], ir->data, ir->b.b.width0); + i915->current.num_user_constants[shader] = (ir->b.b.width0 / + 4 * sizeof(float)); } + else { + i915->current.num_user_constants[shader] = 0; + } + i915->dirty |= I915_NEW_CONSTANTS; } @@ -593,7 +589,7 @@ static void i915_set_fragment_sampler_views(struct pipe_context *pipe, static struct pipe_sampler_view * i915_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -602,7 +598,7 @@ i915_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -614,7 +610,7 @@ static void i915_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 2d212abfb9d..4d069fffa85 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -30,6 +30,7 @@ #include "i915_context.h" #include "i915_batch.h" #include "i915_reg.h" +#include "i915_resource.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -211,8 +212,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) if (cbuf_surface) { unsigned ctile = BUF_3D_USE_FENCE; - struct i915_texture *tex = (struct i915_texture *) - cbuf_surface->texture; + struct i915_texture *tex = i915_texture(cbuf_surface->texture); assert(tex); if (tex && tex->sw_tiled) { @@ -234,8 +234,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) */ if (depth_surface) { unsigned ztile = BUF_3D_USE_FENCE; - struct i915_texture *tex = (struct i915_texture *) - depth_surface->texture; + struct i915_texture *tex = i915_texture(depth_surface->texture); assert(tex); if (tex && tex->sw_tiled) { @@ -290,7 +289,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_BATCH(enabled); for (unit = 0; unit < I915_TEX_UNITS; unit++) { if (enabled & (1 << unit)) { - struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); struct i915_winsys_buffer *buf = texture->buffer; uint offset = 0; assert(buf); diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 270d4f21e10..73e61b66240 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -32,6 +32,7 @@ #include "i915_context.h" #include "i915_reg.h" #include "i915_state.h" +#include "i915_resource.h" /* @@ -77,7 +78,7 @@ static void update_sampler(struct i915_context *i915, const struct i915_texture *tex, unsigned state[3] ) { - const struct pipe_texture *pt = &tex->base; + const struct pipe_resource *pt = &tex->b.b; unsigned minlod, lastlod; /* Need to do this after updating the maps, which call the @@ -149,7 +150,7 @@ void i915_update_samplers( struct i915_context *i915 ) /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->fragment_sampler_views[unit]) { - struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); update_sampler( i915, unit, @@ -238,7 +239,7 @@ i915_update_texture(struct i915_context *i915, const struct i915_sampler_state *sampler, uint state[6]) { - const struct pipe_texture *pt = &tex->base; + const struct pipe_resource *pt = &tex->b.b; uint format, pitch; const uint width = pt->width0, height = pt->height0, depth = pt->depth0; const uint num_levels = pt->last_level; @@ -296,7 +297,7 @@ i915_update_textures(struct i915_context *i915) /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->fragment_sampler_views[unit]) { - struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); i915_update_texture( i915, unit, diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index 1ff6b9f4c63..453437b8090 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -25,10 +25,15 @@ * **************************************************************************/ -#include "i915_context.h" +#include "i915_surface.h" +#include "i915_resource.h" #include "i915_blit.h" +#include "i915_screen.h" #include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "util/u_math.h" #include "util/u_format.h" +#include "util/u_memory.h" /* Assumes all values are within bounds -- no checking at this level - @@ -41,10 +46,10 @@ i915_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - struct i915_texture *dst_tex = (struct i915_texture *)dst->texture; - struct i915_texture *src_tex = (struct i915_texture *)src->texture; - struct pipe_texture *dpt = &dst_tex->base; - struct pipe_texture *spt = &src_tex->base; + struct i915_texture *dst_tex = i915_texture(dst->texture); + struct i915_texture *src_tex = i915_texture(src->texture); + struct pipe_resource *dpt = &dst_tex->b.b; + struct pipe_resource *spt = &src_tex->b.b; assert( dst != src ); assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) ); @@ -68,8 +73,8 @@ i915_surface_fill(struct pipe_context *pipe, unsigned dstx, unsigned dsty, unsigned width, unsigned height, unsigned value) { - struct i915_texture *tex = (struct i915_texture *)dst->texture; - struct pipe_texture *pt = &tex->base; + struct i915_texture *tex = i915_texture(dst->texture); + struct pipe_resource *pt = &tex->b.b; assert(util_format_get_blockwidth(pt->format) == 1); assert(util_format_get_blockheight(pt->format) == 1); @@ -84,9 +89,68 @@ i915_surface_fill(struct pipe_context *pipe, } +/* + * Screen surface functions + */ + + +static struct pipe_surface * +i915_get_tex_surface(struct pipe_screen *screen, + struct pipe_resource *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct i915_texture *tex = i915_texture(pt); + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset = tex->image_offset[level][face]; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset = tex->image_offset[level][zslice]; + } + else { + offset = tex->image_offset[level][0]; + assert(face == 0); + assert(zslice == 0); + } + + ps = CALLOC_STRUCT(pipe_surface); + if (ps) { + pipe_reference_init(&ps->reference, 1); + pipe_resource_reference(&ps->texture, pt); + ps->format = pt->format; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); + ps->offset = offset; + ps->usage = flags; + } + return ps; +} + +static void +i915_tex_surface_destroy(struct pipe_surface *surf) +{ + pipe_resource_reference(&surf->texture, NULL); + FREE(surf); +} + + +/* Probably going to make blits work on textures rather than surfaces. + */ void i915_init_surface_functions(struct i915_context *i915) { i915->base.surface_copy = i915_surface_copy; i915->base.surface_fill = i915_surface_fill; } + +/* No good reason for these to be in the screen. + */ +void +i915_init_screen_surface_functions(struct i915_screen *is) +{ + is->base.get_tex_surface = i915_get_tex_surface; + is->base.tex_surface_destroy = i915_tex_surface_destroy; +} diff --git a/src/gallium/drivers/i915/i915_texture.h b/src/gallium/drivers/i915/i915_surface.h index 51a1dd984c8..448106d5662 100644 --- a/src/gallium/drivers/i915/i915_texture.h +++ b/src/gallium/drivers/i915/i915_surface.h @@ -25,12 +25,14 @@ * **************************************************************************/ -#ifndef I915_TEXTURE_H -#define I915_TEXTURE_H +#ifndef I915_SURFACE_H +#define I915_SURFACE_H +struct i915_context; struct i915_screen; -extern void -i915_init_screen_texture_functions(struct i915_screen *is); +void i915_init_surface_functions( struct i915_context *i915 ); +void i915_init_screen_surface_functions( struct i915_screen *is ); -#endif /* I915_TEXTURE_H */ + +#endif /* I915_SCREEN_H */ diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h index 246e95b00d6..8a6f579ad97 100644 --- a/src/gallium/drivers/i915/i915_winsys.h +++ b/src/gallium/drivers/i915/i915_winsys.h @@ -31,7 +31,7 @@ struct i915_winsys; struct i915_winsys_buffer; struct i915_winsys_batchbuffer; -struct pipe_texture; +struct pipe_resource; struct pipe_fence_handle; struct winsys_handle; @@ -133,7 +133,7 @@ struct i915_winsys { /** * Creates a buffer from a handle. - * Used to implement pipe_screen::texture_from_handle. + * Used to implement pipe_screen::resource_from_handle. * Also provides the stride information needed for the * texture via the stride argument. */ @@ -143,7 +143,7 @@ struct i915_winsys { unsigned *stride); /** - * Used to implement pipe_screen::texture_get_handle. + * Used to implement pipe_screen::resource_get_handle. * The winsys might need the stride information. */ boolean (*buffer_get_handle)(struct i915_winsys *iws, diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index 95fd3cd69bd..b0b09703384 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -36,6 +36,7 @@ C_SOURCES = \ brw_pipe_vertex.c \ brw_pipe_clear.c \ brw_pipe_rast.c \ + brw_resource.c \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ @@ -46,7 +47,6 @@ C_SOURCES = \ brw_structs_dump.c \ brw_swtnl.c \ brw_urb.c \ - brw_util.c \ brw_vs.c \ brw_vs_emit.c \ brw_vs_state.c \ @@ -63,9 +63,9 @@ C_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c \ brw_screen.c \ - brw_screen_buffers.c \ - brw_screen_tex_layout.c \ - brw_screen_texture.c \ + brw_resource_buffer.c \ + brw_resource_texture.c \ + brw_resource_texture_layout.c \ brw_screen_surface.c \ brw_batchbuffer.c \ brw_winsys_debug.c \ diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript index d900ea25968..85c4d7ed22e 100644 --- a/src/gallium/drivers/i965/SConscript +++ b/src/gallium/drivers/i965/SConscript @@ -38,11 +38,12 @@ i965 = env.ConvenienceLibrary( 'brw_pipe_sampler.c', 'brw_pipe_shader.c', 'brw_pipe_vertex.c', - 'brw_screen_buffers.c', + 'brw_resource.c', + 'brw_resource_buffer.c', + 'brw_resource_texture.c', + 'brw_resource_texture_layout.c', 'brw_screen.c', 'brw_screen_surface.c', - 'brw_screen_tex_layout.c', - 'brw_screen_texture.c', 'brw_structs_dump.c', 'brw_sf.c', 'brw_sf_emit.c', @@ -53,7 +54,6 @@ i965 = env.ConvenienceLibrary( 'brw_state_upload.c', 'brw_swtnl.c', 'brw_urb.c', - 'brw_util.c', 'brw_vs.c', 'brw_vs_emit.c', 'brw_vs_state.c', diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index 4bcdcdd17eb..227bc790deb 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -39,6 +39,7 @@ #include "brw_state.h" #include "brw_batchbuffer.h" #include "brw_winsys.h" +#include "brw_resource.h" #include "brw_screen.h" @@ -118,7 +119,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen, brw->sws = brw_screen(screen)->sws; brw->chipset = brw_screen(screen)->chipset; - brw_tex_init( brw ); + brw_init_resource_functions( brw ); brw_pipe_blend_init( brw ); brw_pipe_depth_stencil_init( brw ); brw_pipe_framebuffer_init( brw ); diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index dab881fea24..94c9c443f05 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -561,8 +561,8 @@ struct brw_context struct pipe_stencil_ref stencil_ref; struct pipe_framebuffer_state fb; struct pipe_clip_state ucp; - struct pipe_buffer *vertex_constants; - struct pipe_buffer *fragment_constants; + struct pipe_resource *vertex_constants; + struct pipe_resource *fragment_constants; struct brw_blend_constant_color bcc; struct brw_cc1 cc1_stencil_ref; @@ -574,7 +574,7 @@ struct brw_context * * Updates are signaled by PIPE_NEW_INDEX_BUFFER. */ - struct pipe_buffer *index_buffer; + struct pipe_resource *index_buffer; unsigned index_size; /* Updates are signalled by PIPE_NEW_INDEX_RANGE: diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index 4b215a001c4..323af16b145 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -160,7 +160,6 @@ static GLfloat fixed_plane[6][4] = { */ static enum pipe_error prepare_curbe_buffer(struct brw_context *brw) { - struct pipe_screen *screen = brw->base.screen; const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); enum pipe_error ret; @@ -196,15 +195,11 @@ static enum pipe_error prepare_curbe_buffer(struct brw_context *brw) nr_const = fs->info.file_max[TGSI_FILE_CONSTANT] + 1; /* nr_const = brw->wm.prog_data->nr_params; */ if (nr_const) { - const GLfloat *value = screen->buffer_map( screen, - brw->curr.fragment_constants, - PIPE_BUFFER_USAGE_CPU_READ); - - memcpy(&buf[offset], value, - nr_const * 4 * sizeof(float)); - - screen->buffer_unmap( screen, - brw->curr.fragment_constants ); + pipe_buffer_read( &brw->base, + brw->curr.fragment_constants, + 0, + nr_const * 4 * sizeof(float), + &buf[offset]); } } @@ -258,15 +253,14 @@ static enum pipe_error prepare_curbe_buffer(struct brw_context *brw) * buffer objects. If we want to keep on putting them into the * curbe, makes sense to treat constbuf's specially with malloc. */ - const GLfloat *value = screen->buffer_map( screen, - brw->curr.vertex_constants, - PIPE_BUFFER_USAGE_CPU_READ); /* XXX: what if user's constant buffer is too small? */ - memcpy(&buf[offset], value, nr_const * 4 * sizeof(float)); - - screen->buffer_unmap( screen, brw->curr.vertex_constants ); + pipe_buffer_read(&brw->base, + brw->curr.vertex_constants, + 0, + nr_const * 4 * sizeof(float), + &buf[offset]); } } diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 9bad61ef72e..eb73ec2f272 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -142,7 +142,7 @@ static int brw_emit_prim(struct brw_context *brw, */ static int try_draw_range_elements(struct brw_context *brw, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned hw_prim, unsigned start, unsigned count) { @@ -178,7 +178,7 @@ try_draw_range_elements(struct brw_context *brw, static void brw_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned min_index, unsigned max_index, @@ -201,7 +201,7 @@ brw_draw_range_elements(struct pipe_context *pipe, */ if (brw->curr.index_buffer != index_buffer || brw->curr.index_size != index_size) { - pipe_buffer_reference( &brw->curr.index_buffer, index_buffer ); + pipe_resource_reference( &brw->curr.index_buffer, index_buffer ); brw->curr.index_size = index_size; brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; } @@ -232,7 +232,7 @@ brw_draw_range_elements(struct pipe_context *pipe, static void brw_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned mode, unsigned start, unsigned count) @@ -263,17 +263,17 @@ boolean brw_draw_init( struct brw_context *brw ) /* Create helpers for uploading data in user buffers: */ - brw->vb.upload_vertex = u_upload_create( brw->base.screen, + brw->vb.upload_vertex = u_upload_create( &brw->base, 128 * 1024, 64, - PIPE_BUFFER_USAGE_VERTEX ); + PIPE_BIND_VERTEX_BUFFER ); if (brw->vb.upload_vertex == NULL) return FALSE; - brw->vb.upload_index = u_upload_create( brw->base.screen, + brw->vb.upload_index = u_upload_create( &brw->base, 32 * 1024, 64, - PIPE_BUFFER_USAGE_INDEX ); + PIPE_BIND_INDEX_BUFFER ); if (brw->vb.upload_index == NULL) return FALSE; diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 0820ba20a08..337eee8cd9c 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -38,6 +38,7 @@ #include "brw_screen.h" #include "brw_batchbuffer.h" #include "brw_debug.h" +#include "brw_resource.h" @@ -67,7 +68,7 @@ static int brw_prepare_vertices(struct brw_context *brw) for (i = 0; i < brw->curr.num_vertex_buffers; i++) { struct pipe_vertex_buffer *vb = &brw->curr.vertex_buffer[i]; struct brw_winsys_buffer *bo; - struct pipe_buffer *upload_buf = NULL; + struct pipe_resource *upload_buf = NULL; unsigned offset; if (BRW_DEBUG & DEBUG_VERTS) @@ -75,7 +76,7 @@ static int brw_prepare_vertices(struct brw_context *brw) __FUNCTION__, i, brw_buffer_is_user_buffer(vb->buffer), vb->buffer_offset, - vb->buffer->size, + vb->buffer->width0, vb->stride); if (brw_buffer_is_user_buffer(vb->buffer)) { @@ -85,8 +86,8 @@ static int brw_prepare_vertices(struct brw_context *brw) * add support for >1 constant buffer) instead. */ unsigned size = (vb->stride == 0 ? - vb->buffer->size - vb->buffer_offset : - MAX2(vb->buffer->size - vb->buffer_offset, + vb->buffer->width0 - vb->buffer_offset : + MAX2(vb->buffer->width0 - vb->buffer_offset, vb->stride * (max_index + 1 - min_index))); ret = u_upload_buffer( brw->vb.upload_vertex, @@ -123,7 +124,7 @@ static int brw_prepare_vertices(struct brw_context *brw) /* Don't need to retain this reference. We have a reference on * the underlying winsys buffer: */ - pipe_buffer_reference( &upload_buf, NULL ); + pipe_resource_reference( &upload_buf, NULL ); } brw->vb.nr_vb = i; @@ -226,8 +227,8 @@ const struct brw_tracked_state brw_vertices = { static int brw_prepare_indices(struct brw_context *brw) { - struct pipe_buffer *index_buffer = brw->curr.index_buffer; - struct pipe_buffer *upload_buf = NULL; + struct pipe_resource *index_buffer = brw->curr.index_buffer; + struct pipe_resource *upload_buf = NULL; struct brw_winsys_buffer *bo = NULL; GLuint offset; GLuint index_size; @@ -241,9 +242,9 @@ static int brw_prepare_indices(struct brw_context *brw) debug_printf("%s: index_size:%d index_buffer->size:%d\n", __FUNCTION__, brw->curr.index_size, - brw->curr.index_buffer->size); + brw->curr.index_buffer->width0); - ib_size = index_buffer->size; + ib_size = index_buffer->width0; index_size = brw->curr.index_size; /* Turn userbuffer into a proper hardware buffer? @@ -297,7 +298,7 @@ static int brw_prepare_indices(struct brw_context *brw) brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; } - pipe_buffer_reference( &upload_buf, NULL ); + pipe_resource_reference( &upload_buf, NULL ); brw_add_validated_bo(brw, brw->ib.bo); return 0; } diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c index fdc4814b221..fa2b64fd261 100644 --- a/src/gallium/drivers/i965/brw_pipe_flush.c +++ b/src/gallium/drivers/i965/brw_pipe_flush.c @@ -1,10 +1,11 @@ -#include "util/u_upload_mgr.h" - #include "brw_context.h" #include "brw_screen.h" #include "brw_batchbuffer.h" +#include "util/u_upload_mgr.h" + + /* All batchbuffer flushes must go through this function. @@ -46,35 +47,9 @@ brw_flush( struct pipe_context *pipe, *fence = NULL; } -static unsigned brw_is_buffer_referenced(struct pipe_context *pipe, - struct pipe_buffer *buffer) -{ - struct brw_context *brw = brw_context(pipe); - struct brw_screen *bscreen = brw_screen(brw->base.screen); - - return brw_is_buffer_referenced_by_bo( bscreen, - buffer, - brw->batch->buf ); -} - -static unsigned brw_is_texture_referenced(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, - unsigned level) -{ - struct brw_context *brw = brw_context(pipe); - struct brw_screen *bscreen = brw_screen(brw->base.screen); - - return brw_is_texture_referenced_by_bo( bscreen, - texture, face, level, - brw->batch->buf ); -} - void brw_pipe_flush_init( struct brw_context *brw ) { brw->base.flush = brw_flush; - brw->base.is_buffer_referenced = brw_is_buffer_referenced; - brw->base.is_texture_referenced = brw_is_texture_referenced; } diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index d2aa2bc9f35..3fe753ec42c 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -214,7 +214,7 @@ static void brw_bind_vertex_sampler_state(struct pipe_context *pipe, static struct pipe_sampler_view * brw_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -223,7 +223,7 @@ brw_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -235,7 +235,7 @@ static void brw_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c index fe445b9982e..d9bee96c11f 100644 --- a/src/gallium/drivers/i965/brw_pipe_shader.c +++ b/src/gallium/drivers/i965/brw_pipe_shader.c @@ -262,20 +262,20 @@ static void brw_delete_vs_state( struct pipe_context *pipe, void *prog ) static void brw_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_resource *buf) { struct brw_context *brw = brw_context(pipe); assert(index == 0); if (shader == PIPE_SHADER_FRAGMENT) { - pipe_buffer_reference( &brw->curr.fragment_constants, + pipe_resource_reference( &brw->curr.fragment_constants, buf ); brw->state.dirty.mesa |= PIPE_NEW_FRAGMENT_CONSTANTS; } else { - pipe_buffer_reference( &brw->curr.vertex_constants, + pipe_resource_reference( &brw->curr.vertex_constants, buf ); brw->state.dirty.mesa |= PIPE_NEW_VERTEX_CONSTANTS; @@ -298,6 +298,6 @@ void brw_pipe_shader_init( struct brw_context *brw ) void brw_pipe_shader_cleanup( struct brw_context *brw ) { - pipe_buffer_reference( &brw->curr.fragment_constants, NULL ); - pipe_buffer_reference( &brw->curr.vertex_constants, NULL ); + pipe_resource_reference( &brw->curr.fragment_constants, NULL ); + pipe_resource_reference( &brw->curr.vertex_constants, NULL ); } diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index d6a840857ec..4a120a51dad 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -259,11 +259,11 @@ static void brw_set_vertex_buffers(struct pipe_context *pipe, /* Adjust refcounts */ for (i = 0; i < count; i++) - pipe_buffer_reference(&brw->curr.vertex_buffer[i].buffer, + pipe_resource_reference(&brw->curr.vertex_buffer[i].buffer, buffers[i].buffer); for ( ; i < brw->curr.num_vertex_buffers; i++) - pipe_buffer_reference(&brw->curr.vertex_buffer[i].buffer, + pipe_resource_reference(&brw->curr.vertex_buffer[i].buffer, NULL); /* Copy remaining data */ diff --git a/src/gallium/drivers/i965/brw_resource.c b/src/gallium/drivers/i965/brw_resource.c new file mode 100644 index 00000000000..d601f42dd16 --- /dev/null +++ b/src/gallium/drivers/i965/brw_resource.c @@ -0,0 +1,50 @@ +#include "util/u_debug.h" + +#include "brw_resource.h" +#include "brw_context.h" +#include "brw_screen.h" + + +static struct pipe_resource * +brw_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return brw_buffer_create(screen, template); + else + return brw_resource_create(screen, template); + +} + +static struct pipe_resource * +brw_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return brw_texture_from_handle(screen, template, whandle); +} + + +void +brw_init_resource_functions(struct brw_context *brw ) +{ + brw->base.get_transfer = u_get_transfer_vtbl; + brw->base.transfer_map = u_transfer_map_vtbl; + brw->base.transfer_flush_region = u_transfer_flush_region_vtbl; + brw->base.transfer_unmap = u_transfer_unmap_vtbl; + brw->base.transfer_destroy = u_transfer_destroy_vtbl; + brw->base.transfer_inline_write = u_transfer_inline_write_vtbl; +} + +void +brw_init_screen_resource_functions(struct brw_screen *is) +{ + is->base.resource_create = brw_resource_create; + is->base.resource_from_handle = brw_resource_from_handle; + is->base.resource_get_handle = u_resource_get_handle_vtbl; + is->base.resource_destroy = u_resource_destroy_vtbl; + is->base.user_buffer_create = brw_user_buffer_create; +} diff --git a/src/gallium/drivers/i965/brw_resource.h b/src/gallium/drivers/i965/brw_resource.h new file mode 100644 index 00000000000..3390c270d42 --- /dev/null +++ b/src/gallium/drivers/i965/brw_resource.h @@ -0,0 +1,151 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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. + * + **************************************************************************/ + +#ifndef BRW_RESOURCE_H +#define BRW_RESOURCE_H + +struct brw_screen; + +#include "util/u_transfer.h" +#include "util/u_debug.h" + +#include "brw_screen.h" /* for brw_surface */ + +struct brw_context; +struct brw_screen; + + +struct brw_buffer { + struct u_resource b; + + /* One of either bo or user_buffer will be non-null, depending on + * whether this is a hardware or user buffer. + */ + struct brw_winsys_buffer *bo; + void *user_buffer; + + /* Mapped pointer?? + */ + void *ptr; +}; + +#define BRW_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */ +#define BRW_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */ + + + +struct brw_texture { + struct u_resource b; + struct brw_winsys_buffer *bo; + struct brw_surface_state ss; + + unsigned *image_offset[BRW_MAX_TEXTURE_2D_LEVELS]; + unsigned nr_images[BRW_MAX_TEXTURE_2D_LEVELS]; + unsigned level_offset[BRW_MAX_TEXTURE_2D_LEVELS]; + + boolean compressed; + unsigned brw_target; + unsigned pitch; + unsigned tiling; + unsigned cpp; + unsigned total_height; + + struct brw_surface views[2]; +}; + + +void brw_init_screen_resource_functions(struct brw_screen *is); +void brw_init_resource_functions(struct brw_context *brw ); + +extern struct u_resource_vtbl brw_buffer_vtbl; +extern struct u_resource_vtbl brw_texture_vtbl; + +static INLINE struct brw_texture *brw_texture( struct pipe_resource *resource ) +{ + struct brw_texture *tex = (struct brw_texture *)resource; + assert(tex->b.vtbl == &brw_texture_vtbl); + return tex; +} + +static INLINE struct brw_buffer *brw_buffer( struct pipe_resource *resource ) +{ + struct brw_buffer *tex = (struct brw_buffer *)resource; + assert(tex->b.vtbl == &brw_buffer_vtbl); + return tex; +} + +struct pipe_resource * +brw_texture_create(struct pipe_screen *screen, + const struct pipe_resource *template); + +struct pipe_resource * +brw_texture_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle); + + +struct pipe_resource * +brw_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + +struct pipe_resource * +brw_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template); + + +/* +boolean +brw_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ); +*/ + +/* Pipe buffer helpers + */ +static INLINE boolean +brw_buffer_is_user_buffer( const struct pipe_resource *buf ) +{ + return ((const struct brw_buffer *)buf)->user_buffer != NULL; +} + + +/*********************************************************************** + * Internal functions + */ +GLboolean brw_texture_layout(struct brw_screen *brw_screen, + struct brw_texture *tex ); + +void brw_update_texture( struct brw_screen *brw_screen, + struct brw_texture *tex ); + + + +#endif /* BRW_RESOURCE_H */ diff --git a/src/gallium/drivers/i965/brw_resource_buffer.c b/src/gallium/drivers/i965/brw_resource_buffer.c new file mode 100644 index 00000000000..488fe13c714 --- /dev/null +++ b/src/gallium/drivers/i965/brw_resource_buffer.c @@ -0,0 +1,201 @@ + +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" + +#include "brw_resource.h" +#include "brw_context.h" +#include "brw_batchbuffer.h" +#include "brw_winsys.h" + +static boolean +brw_buffer_get_handle(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle) +{ + return FALSE; +} + + +static void +brw_buffer_destroy(struct pipe_screen *screen, + struct pipe_resource *resource) +{ + struct brw_buffer *buf = brw_buffer( resource ); + + bo_reference(&buf->bo, NULL); + FREE(buf); +} + + +static void * +brw_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct brw_screen *bscreen = brw_screen(pipe->screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer(transfer->resource); + unsigned offset = transfer->box.x; + unsigned length = transfer->box.width; + unsigned usage = transfer->usage; + uint8_t *map; + + if (buf->user_buffer) + map = buf->user_buffer; + else + map = sws->bo_map( buf->bo, + BRW_DATA_OTHER, + offset, + length, + (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE, + (usage & PIPE_TRANSFER_DISCARD) ? TRUE : FALSE, + (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) ? TRUE : FALSE); + + return map + offset; +} + + +static void +brw_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct brw_screen *bscreen = brw_screen(pipe->screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer(transfer->resource); + unsigned offset = box->x; + unsigned length = box->width; + + if (buf->user_buffer) + return; + + sws->bo_flush_range( buf->bo, + offset, + length ); +} + + +static void +brw_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct brw_screen *bscreen = brw_screen(pipe->screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer( transfer->resource ); + + if (buf->bo) + sws->bo_unmap(buf->bo); +} + + +static unsigned brw_buffer_is_referenced( struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned face, + unsigned level) +{ + struct brw_context *brw = brw_context(pipe); + struct brw_winsys_buffer *batch_bo = brw->batch->buf; + struct brw_buffer *buf = brw_buffer(resource); + + if (buf->bo == NULL) + return PIPE_UNREFERENCED; + + if (!brw_screen(pipe->screen)->sws->bo_references( batch_bo, buf->bo )) + return PIPE_UNREFERENCED; + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + + +struct u_resource_vtbl brw_buffer_vtbl = +{ + brw_buffer_get_handle, /* get_handle */ + brw_buffer_destroy, /* resource_destroy */ + brw_buffer_is_referenced, /* is_resource_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + brw_buffer_transfer_map, /* transfer_map */ + brw_buffer_transfer_flush_region, /* transfer_flush_region */ + brw_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + +struct pipe_resource * +brw_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf; + unsigned buffer_type; + enum pipe_error ret; + + buf = CALLOC_STRUCT(brw_buffer); + if (!buf) + return NULL; + + buf->b.b = *template; + buf->b.vtbl = &brw_buffer_vtbl; + pipe_reference_init(&buf->b.b.reference, 1); + buf->b.b.screen = screen; + + switch (template->bind & (PIPE_BIND_VERTEX_BUFFER | + PIPE_BIND_INDEX_BUFFER | + PIPE_BIND_CONSTANT_BUFFER)) + { + case PIPE_BIND_VERTEX_BUFFER: + case PIPE_BIND_INDEX_BUFFER: + case (PIPE_BIND_VERTEX_BUFFER|PIPE_BIND_INDEX_BUFFER): + buffer_type = BRW_BUFFER_TYPE_VERTEX; + break; + + case PIPE_BIND_CONSTANT_BUFFER: + buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS; + break; + + default: + buffer_type = BRW_BUFFER_TYPE_GENERIC; + break; + } + + ret = sws->bo_alloc( sws, buffer_type, + template->width0, + 64, /* alignment */ + &buf->bo ); + if (ret != PIPE_OK) + return NULL; + + return &buf->b.b; +} + + +struct pipe_resource * +brw_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind) +{ + struct brw_buffer *buf; + + buf = CALLOC_STRUCT(brw_buffer); + if (!buf) + return NULL; + + pipe_reference_init(&buf->b.b.reference, 1); + buf->b.vtbl = &brw_buffer_vtbl; + buf->b.b.screen = screen; + buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buf->b.b._usage = PIPE_USAGE_IMMUTABLE; + buf->b.b.bind = bind; + buf->b.b.width0 = bytes; + buf->b.b.height0 = 1; + buf->b.b.depth0 = 1; + + buf->user_buffer = ptr; + + return &buf->b.b; +} diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c index 17bf3152dcc..a6f27b8a413 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_resource_texture.c @@ -37,9 +37,26 @@ #include "brw_defines.h" #include "brw_structs.h" #include "brw_winsys.h" +#include "brw_batchbuffer.h" #include "brw_context.h" +#include "brw_resource.h" +/** + * Subclass of pipe_transfer + */ +struct brw_transfer +{ + struct pipe_transfer base; + + unsigned offset; +}; + +static INLINE struct brw_transfer * +brw_transfer(struct pipe_transfer *transfer) +{ + return (struct brw_transfer *)transfer; +} static GLuint translate_tex_target( unsigned target ) @@ -182,12 +199,176 @@ static GLuint translate_tex_format( enum pipe_format pf ) } +static boolean +brw_texture_get_handle(struct pipe_screen *screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_texture *tex = brw_texture(texture); + unsigned stride; + + stride = tex->pitch * tex->cpp; + + return bscreen->sws->bo_get_handle(tex->bo, whandle, stride); +} + + + +static void brw_texture_destroy(struct pipe_screen *screen, + struct pipe_resource *pt) +{ + struct brw_texture *tex = brw_texture(pt); + bo_reference(&tex->bo, NULL); + FREE(pt); +} + + + + +static unsigned brw_texture_is_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, + unsigned face, + unsigned level ) +{ + struct brw_context *brw = brw_context(pipe); + struct brw_screen *bscreen = brw_screen(pipe->screen); + struct brw_winsys_buffer *batch_bo = brw->batch->buf; + struct brw_texture *tex = brw_texture(texture); + struct brw_surface *surf; + int i; + + /* XXX: this is subject to false positives if the underlying + * texture BO is referenced, we can't tell whether the sub-region + * we care about participates in that. + */ + if (bscreen->sws->bo_references( batch_bo, tex->bo )) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + + /* Find any view on this texture for this face/level and see if it + * is referenced: + */ + for (i = 0; i < 2; i++) { + foreach (surf, &tex->views[i]) { + if (surf->bo == tex->bo) + continue; + + if (surf->id.bits.face != face || + surf->id.bits.level != level) + continue; + + if (bscreen->sws->bo_references( batch_bo, surf->bo)) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + } + } + + return PIPE_UNREFERENCED; +} + + +/* + * Transfer functions + */ + + +static struct pipe_transfer * +brw_texture_get_transfer(struct pipe_context *context, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct brw_texture *tex = brw_texture(resource); + struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer); + if (transfer == NULL) + return NULL; + + transfer->resource = resource; + transfer->sr = sr; + transfer->usage = usage; + transfer->box = *box; + transfer->stride = tex->pitch * tex->cpp; + + return transfer; +} + + +static void * +brw_texture_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct pipe_resource *resource = transfer->resource; + struct brw_texture *tex = brw_texture(transfer->resource); + struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws; + struct pipe_subresource sr = transfer->sr; + struct pipe_box *box = &transfer->box; + enum pipe_format format = resource->format; + unsigned usage = transfer->usage; + unsigned offset; + char *map; + + if (resource->target == PIPE_TEXTURE_CUBE) { + offset = tex->image_offset[sr.level][sr.face]; + } + else if (resource->target == PIPE_TEXTURE_3D) { + offset = tex->image_offset[sr.level][box->z]; + } + else { + offset = tex->image_offset[sr.level][0]; + assert(sr.face == 0); + assert(box->z == 0); + } + + map = sws->bo_map(tex->bo, + BRW_DATA_OTHER, + 0, + tex->bo->size, + (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE, + (usage & 0) ? TRUE : FALSE, + (usage & 0) ? TRUE : FALSE); + + if (!map) + return NULL; + + return map + offset + + box->y / util_format_get_blockheight(format) * transfer->stride + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); +} + +static void +brw_texture_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct brw_texture *tex = brw_texture(transfer->resource); + struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws; + + sws->bo_unmap(tex->bo); +} + + + + + +struct u_resource_vtbl brw_texture_vtbl = +{ + brw_texture_get_handle, /* get_handle */ + brw_texture_destroy, /* resource_destroy */ + brw_texture_is_referenced, /* is_resource_referenced */ + brw_texture_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + brw_texture_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + brw_texture_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; -static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, - const struct pipe_texture *templ ) + +struct pipe_resource * +brw_texture_create( struct pipe_screen *screen, + const struct pipe_resource *template ) { struct brw_screen *bscreen = brw_screen(screen); struct brw_texture *tex; @@ -199,14 +380,15 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, if (tex == NULL) return NULL; - memcpy(&tex->base, templ, sizeof *templ); - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; + tex->b.b = *template; + tex->b.vtbl = &brw_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; /* XXX: compressed textures need special treatment here */ - tex->cpp = util_format_get_blocksize(tex->base.format); - tex->compressed = util_format_is_s3tc(tex->base.format); + tex->cpp = util_format_get_blocksize(tex->b.b.format); + tex->compressed = util_format_is_s3tc(tex->b.b.format); make_empty_list(&tex->views[0]); make_empty_list(&tex->views[1]); @@ -217,7 +399,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, !bscreen->no_tiling) { if (bscreen->chipset.is_965 && - util_format_is_depth_or_stencil(templ->format)) + util_format_is_depth_or_stencil(template->format)) tex->tiling = BRW_TILING_Y; else tex->tiling = BRW_TILING_X; @@ -227,14 +409,12 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, } - - if (!brw_texture_layout( bscreen, tex )) goto fail; - if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if (template->bind & (PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { buffer_type = BRW_BUFFER_TYPE_SCANOUT; } else { @@ -250,9 +430,9 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, goto fail; tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; - tex->ss.ss0.surface_type = translate_tex_target(tex->base.target); + tex->ss.ss0.surface_type = translate_tex_target(tex->b.b.target); - format = translate_tex_format(tex->base.format); + format = translate_tex_format(tex->b.b.format); assert(format != BRW_SURFACEFORMAT_INVALID); tex->ss.ss0.surface_format = format; @@ -264,9 +444,9 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, /* XXX: what happens when tex->bo->offset changes??? */ tex->ss.ss1.base_addr = 0; /* reloc */ - tex->ss.ss2.mip_count = tex->base.last_level; - tex->ss.ss2.width = tex->base.width0 - 1; - tex->ss.ss2.height = tex->base.height0 - 1; + tex->ss.ss2.mip_count = tex->b.b.last_level; + tex->ss.ss2.width = tex->b.b.width0 - 1; + tex->ss.ss2.height = tex->b.b.height0 - 1; switch (tex->tiling) { case BRW_TILING_NONE: @@ -284,11 +464,11 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, } tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1; - tex->ss.ss3.depth = tex->base.depth0 - 1; + tex->ss.ss3.depth = tex->b.b.depth0 - 1; tex->ss.ss4.min_lod = 0; - if (tex->base.target == PIPE_TEXTURE_CUBE) { + if (tex->b.b.target == PIPE_TEXTURE_CUBE) { tex->ss.ss0.cube_pos_x = 1; tex->ss.ss0.cube_pos_y = 1; tex->ss.ss0.cube_pos_z = 1; @@ -297,7 +477,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, tex->ss.ss0.cube_neg_z = 1; } - return &tex->base; + return &tex->b.b; fail: bo_reference(&tex->bo, NULL); @@ -305,9 +485,10 @@ fail: return NULL; } -static struct pipe_texture * + +struct pipe_resource * brw_texture_from_handle(struct pipe_screen *screen, - const struct pipe_texture *templ, + const struct pipe_resource *template, struct winsys_handle *whandle) { struct brw_screen *bscreen = brw_screen(screen); @@ -317,12 +498,12 @@ brw_texture_from_handle(struct pipe_screen *screen, unsigned pitch; GLuint format; - if (templ->target != PIPE_TEXTURE_2D || - templ->last_level != 0 || - templ->depth0 != 1) + if (template->target != PIPE_TEXTURE_2D || + template->last_level != 0 || + template->depth0 != 1) return NULL; - if (util_format_is_s3tc(templ->format)) + if (util_format_is_s3tc(template->format)) return NULL; tex = CALLOC_STRUCT(brw_texture); @@ -332,13 +513,14 @@ brw_texture_from_handle(struct pipe_screen *screen, if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK) goto fail; - memcpy(&tex->base, templ, sizeof *templ); - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; + tex->b.b = *template; + tex->b.vtbl = &brw_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; /* XXX: cpp vs. blocksize */ - tex->cpp = util_format_get_blocksize(tex->base.format); + tex->cpp = util_format_get_blocksize(tex->b.b.format); tex->tiling = tiling; make_empty_list(&tex->views[0]); @@ -362,11 +544,12 @@ brw_texture_from_handle(struct pipe_screen *screen, #endif tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; - tex->ss.ss0.surface_type = translate_tex_target(tex->base.target); + tex->ss.ss0.surface_type = translate_tex_target(tex->b.b.target); - format = translate_tex_format(tex->base.format); + format = translate_tex_format(tex->b.b.format); assert(format != BRW_SURFACEFORMAT_INVALID); tex->ss.ss0.surface_format = format; + assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID); /* This is ok for all textures with channel width 8bit or less: */ @@ -376,9 +559,9 @@ brw_texture_from_handle(struct pipe_screen *screen, /* XXX: what happens when tex->bo->offset changes??? */ tex->ss.ss1.base_addr = 0; /* reloc */ - tex->ss.ss2.mip_count = tex->base.last_level; - tex->ss.ss2.width = tex->base.width0 - 1; - tex->ss.ss2.height = tex->base.height0 - 1; + tex->ss.ss2.mip_count = tex->b.b.last_level; + tex->ss.ss2.width = tex->b.b.width0 - 1; + tex->ss.ss2.height = tex->b.b.height0 - 1; switch (tex->tiling) { case BRW_TILING_NONE: @@ -396,187 +579,25 @@ brw_texture_from_handle(struct pipe_screen *screen, } tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1; - tex->ss.ss3.depth = tex->base.depth0 - 1; + tex->ss.ss3.depth = tex->b.b.depth0 - 1; tex->ss.ss4.min_lod = 0; - return &tex->base; + return &tex->b.b; fail: FREE(tex); return NULL; } -static boolean -brw_texture_get_handle(struct pipe_screen *screen, - struct pipe_texture *texture, - struct winsys_handle *whandle) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_texture *tex = brw_texture(texture); - unsigned stride; - - stride = tex->pitch * tex->cpp; - return bscreen->sws->bo_get_handle(tex->bo, whandle, stride); -} - - - -static void brw_texture_destroy(struct pipe_texture *pt) -{ - struct brw_texture *tex = brw_texture(pt); - bo_reference(&tex->bo, NULL); - FREE(pt); -} - - -static boolean brw_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, - unsigned geom_flags ) +#if 0 +boolean brw_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { return translate_tex_format(format) != BRW_SURFACEFORMAT_INVALID; } - - -boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen, - struct pipe_texture *texture, - unsigned face, - unsigned level, - struct brw_winsys_buffer *bo ) -{ - struct brw_texture *tex = brw_texture(texture); - struct brw_surface *surf; - int i; - - /* XXX: this is subject to false positives if the underlying - * texture BO is referenced, we can't tell whether the sub-region - * we care about participates in that. - */ - if (brw_screen->sws->bo_references( bo, tex->bo )) - return TRUE; - - /* Find any view on this texture for this face/level and see if it - * is referenced: - */ - for (i = 0; i < 2; i++) { - foreach (surf, &tex->views[i]) { - if (surf->bo == tex->bo) - continue; - - if (surf->id.bits.face != face || - surf->id.bits.level != level) - continue; - - if (brw_screen->sws->bo_references( bo, surf->bo)) - return TRUE; - } - } - - return FALSE; -} - - -/* - * Transfer functions - */ - -static struct pipe_transfer* -brw_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, unsigned x, unsigned y, - unsigned w, unsigned h) -{ - struct brw_texture *tex = brw_texture(texture); - struct brw_transfer *trans; - unsigned offset; /* in bytes */ - - if (texture->target == PIPE_TEXTURE_CUBE) { - offset = tex->image_offset[level][face]; - } else if (texture->target == PIPE_TEXTURE_3D) { - offset = tex->image_offset[level][zslice]; - } else { - offset = tex->image_offset[level][0]; - assert(face == 0); - assert(zslice == 0); - } - - trans = CALLOC_STRUCT(brw_transfer); - if (trans) { - pipe_texture_reference(&trans->base.texture, texture); - trans->base.x = x; - trans->base.y = y; - trans->base.width = w; - trans->base.height = h; - trans->base.stride = tex->pitch * tex->cpp; - trans->offset = offset; - trans->base.usage = usage; - } - return &trans->base; -} - -static void * -brw_transfer_map(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct brw_texture *tex = brw_texture(transfer->texture); - struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws; - char *map; - unsigned usage = transfer->usage; - - map = sws->bo_map(tex->bo, - BRW_DATA_OTHER, - 0, - tex->bo->size, - (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE, - (usage & 0) ? TRUE : FALSE, - (usage & 0) ? TRUE : FALSE); - - if (!map) - return NULL; - - /* XXX: blocksize and compressed textures - */ - return map + brw_transfer(transfer)->offset + - transfer->y /* / transfer->block.height */ * transfer->stride + - transfer->x /* / transfer->block.width */ * brw_texture(transfer->texture)->cpp; -} - -static void -brw_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct brw_texture *tex = brw_texture(transfer->texture); - struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws; - - sws->bo_unmap(tex->bo); -} - -static void -brw_tex_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *trans) -{ - pipe_texture_reference(&trans->texture, NULL); - FREE(trans); -} - - -void brw_tex_init( struct brw_context *brw ) -{ - brw->base.get_tex_transfer = brw_get_tex_transfer; - brw->base.transfer_map = brw_transfer_map; - brw->base.transfer_unmap = brw_transfer_unmap; - brw->base.tex_transfer_destroy = brw_tex_transfer_destroy; -} - -void brw_screen_tex_init( struct brw_screen *brw_screen ) -{ - brw_screen->base.is_format_supported = brw_is_format_supported; - brw_screen->base.texture_create = brw_texture_create; - brw_screen->base.texture_from_handle = brw_texture_from_handle; - brw_screen->base.texture_get_handle = brw_texture_get_handle; - brw_screen->base.texture_destroy = brw_texture_destroy; -} +#endif diff --git a/src/gallium/drivers/i965/brw_screen_tex_layout.c b/src/gallium/drivers/i965/brw_resource_texture_layout.c index 894f4bea401..2187bdd82ce 100644 --- a/src/gallium/drivers/i965/brw_screen_tex_layout.c +++ b/src/gallium/drivers/i965/brw_resource_texture_layout.c @@ -30,7 +30,7 @@ #include "util/u_math.h" #include "util/u_memory.h" -#include "brw_screen.h" +#include "brw_resource.h" #include "brw_debug.h" #include "brw_winsys.h" @@ -143,14 +143,14 @@ static void brw_layout_2d( struct brw_texture *tex ) GLuint level; GLuint x = 0; GLuint y = 0; - GLuint width = tex->base.width0; - GLuint height = tex->base.height0; + GLuint width = tex->b.b.width0; + GLuint height = tex->b.b.height0; - tex->pitch = tex->base.width0; - brw_tex_alignment_unit(tex->base.format, &align_w, &align_h); + tex->pitch = tex->b.b.width0; + brw_tex_alignment_unit(tex->b.b.format, &align_w, &align_h); if (tex->compressed) { - tex->pitch = align(tex->base.width0, align_w); + tex->pitch = align(tex->b.b.width0, align_w); } /* May need to adjust pitch to accomodate the placement of @@ -158,15 +158,15 @@ static void brw_layout_2d( struct brw_texture *tex ) * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (tex->base.last_level > 0) { + if (tex->b.b.last_level > 0) { GLuint mip1_width; if (tex->compressed) { - mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + - align(u_minify(tex->base.width0, 2), align_w)); + mip1_width = (align(u_minify(tex->b.b.width0, 1), align_w) + + align(u_minify(tex->b.b.width0, 2), align_w)); } else { - mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + - u_minify(tex->base.width0, 2)); + mip1_width = (align(u_minify(tex->b.b.width0, 1), align_w) + + u_minify(tex->b.b.width0, 2)); } if (mip1_width > tex->pitch) { @@ -180,7 +180,7 @@ static void brw_layout_2d( struct brw_texture *tex ) tex->pitch = brw_tex_pitch_align (tex, tex->pitch); tex->total_height = 0; - for ( level = 0 ; level <= tex->base.last_level ; level++ ) { + for ( level = 0 ; level <= tex->b.b.last_level ; level++ ) { GLuint img_height; brw_tex_set_level_info(tex, level, 1, x, y, width, height, 1); @@ -218,28 +218,28 @@ brw_layout_cubemap_idgng( struct brw_texture *tex ) GLuint level; GLuint x = 0; GLuint y = 0; - GLuint width = tex->base.width0; - GLuint height = tex->base.height0; + GLuint width = tex->b.b.width0; + GLuint height = tex->b.b.height0; GLuint qpitch = 0; GLuint y_pitch = 0; - tex->pitch = tex->base.width0; - brw_tex_alignment_unit(tex->base.format, &align_w, &align_h); + tex->pitch = tex->b.b.width0; + brw_tex_alignment_unit(tex->b.b.format, &align_w, &align_h); y_pitch = align(height, align_h); if (tex->compressed) { - tex->pitch = align(tex->base.width0, align_w); + tex->pitch = align(tex->b.b.width0, align_w); } - if (tex->base.last_level != 0) { + if (tex->b.b.last_level != 0) { GLuint mip1_width; if (tex->compressed) { - mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + - align(u_minify(tex->base.width0, 2), align_w)); + mip1_width = (align(u_minify(tex->b.b.width0, 1), align_w) + + align(u_minify(tex->b.b.width0, 2), align_w)); } else { - mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + - u_minify(tex->base.width0, 2)); + mip1_width = (align(u_minify(tex->b.b.width0, 1), align_w) + + u_minify(tex->b.b.width0, 2)); } if (mip1_width > tex->pitch) { @@ -267,7 +267,7 @@ brw_layout_cubemap_idgng( struct brw_texture *tex ) 11 * align_h) * 6; } - for (level = 0; level <= tex->base.last_level; level++) { + for (level = 0; level <= tex->b.b.last_level; level++) { GLuint img_height; GLuint nr_images = 6; GLuint q = 0; @@ -300,9 +300,9 @@ brw_layout_cubemap_idgng( struct brw_texture *tex ) static boolean brw_layout_3d_cube( struct brw_texture *tex ) { - GLuint width = tex->base.width0; - GLuint height = tex->base.height0; - GLuint depth = tex->base.depth0; + GLuint width = tex->b.b.width0; + GLuint height = tex->b.b.height0; + GLuint depth = tex->b.b.depth0; GLuint pack_x_pitch, pack_x_nr; GLuint pack_y_pitch; GLuint level; @@ -310,21 +310,21 @@ brw_layout_3d_cube( struct brw_texture *tex ) GLuint align_w = 4; tex->total_height = 0; - brw_tex_alignment_unit(tex->base.format, &align_w, &align_h); + brw_tex_alignment_unit(tex->b.b.format, &align_w, &align_h); if (tex->compressed) { tex->pitch = align(width, align_w); pack_y_pitch = (height + 3) / 4; } else { - tex->pitch = brw_tex_pitch_align(tex, tex->base.width0); - pack_y_pitch = align(tex->base.height0, align_h); + tex->pitch = brw_tex_pitch_align(tex, tex->b.b.width0); + pack_y_pitch = align(tex->b.b.height0, align_h); } pack_x_pitch = width; pack_x_nr = 1; - for (level = 0 ; level <= tex->base.last_level ; level++) { - GLuint nr_images = tex->base.target == PIPE_TEXTURE_3D ? depth : 6; + for (level = 0 ; level <= tex->b.b.last_level ; level++) { + GLuint nr_images = tex->b.b.target == PIPE_TEXTURE_3D ? depth : 6; GLint x = 0; GLint y = 0; GLint q, j; @@ -375,7 +375,7 @@ brw_layout_3d_cube( struct brw_texture *tex ) * memory. As a result, the docs say in Surface Padding Requirements: * Sampling Engine Surfaces that two extra rows of padding are required. */ - if (tex->base.target == PIPE_TEXTURE_CUBE) + if (tex->b.b.target == PIPE_TEXTURE_CUBE) tex->total_height += 2; return TRUE; @@ -386,7 +386,7 @@ brw_layout_3d_cube( struct brw_texture *tex ) GLboolean brw_texture_layout(struct brw_screen *brw_screen, struct brw_texture *tex ) { - switch (tex->base.target) { + switch (tex->b.b.target) { case PIPE_TEXTURE_CUBE: if (brw_screen->chipset.is_igdng) brw_layout_cubemap_idgng( tex ); diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index ba30e63f20c..0a7151bde44 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -35,6 +35,7 @@ #include "brw_screen.h" #include "brw_winsys.h" #include "brw_debug.h" +#include "brw_resource.h" #ifdef DEBUG static const struct debug_named_value debug_names[] = { @@ -275,9 +276,9 @@ brw_is_format_supported(struct pipe_screen *screen, const enum pipe_format *list; uint i; - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) + if (tex_usage & PIPE_BIND_DEPTH_STENCIL) list = depth_supported; - else if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) + else if (tex_usage & PIPE_BIND_RENDER_TARGET) list = render_supported; else list = tex_supported; @@ -406,9 +407,8 @@ brw_create_screen(struct brw_winsys_screen *sws, uint pci_id) bscreen->base.fence_signalled = brw_fence_signalled; bscreen->base.fence_finish = brw_fence_finish; - brw_screen_tex_init(bscreen); + brw_init_screen_resource_functions(bscreen); brw_screen_tex_surface_init(bscreen); - brw_screen_buffer_init(bscreen); bscreen->no_tiling = debug_get_option("BRW_NO_TILING", FALSE) != NULL; diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h index e3a7c64d489..522a3bf8995 100644 --- a/src/gallium/drivers/i965/brw_screen.h +++ b/src/gallium/drivers/i965/brw_screen.h @@ -48,30 +48,6 @@ struct brw_screen boolean no_tiling; }; -/** - * Subclass of pipe_transfer - */ -struct brw_transfer -{ - struct pipe_transfer base; - - unsigned offset; -}; - -struct brw_buffer -{ - struct pipe_buffer base; - - /* One of either bo or user_buffer will be non-null, depending on - * whether this is a hardware or user buffer. - */ - struct brw_winsys_buffer *bo; - void *user_buffer; - - /* Mapped pointer?? - */ - void *ptr; -}; union brw_surface_id { @@ -100,31 +76,6 @@ struct brw_surface }; -#define BRW_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */ -#define BRW_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */ - - -struct brw_texture -{ - struct pipe_texture base; - struct brw_winsys_buffer *bo; - struct brw_surface_state ss; - - unsigned *image_offset[BRW_MAX_TEXTURE_2D_LEVELS]; - unsigned nr_images[BRW_MAX_TEXTURE_2D_LEVELS]; - unsigned level_offset[BRW_MAX_TEXTURE_2D_LEVELS]; - - boolean compressed; - unsigned brw_target; - unsigned pitch; - unsigned tiling; - unsigned cpp; - unsigned total_height; - - struct brw_surface views[2]; -}; - - /* * Cast wrappers @@ -135,11 +86,6 @@ brw_screen(struct pipe_screen *pscreen) return (struct brw_screen *) pscreen; } -static INLINE struct brw_transfer * -brw_transfer(struct pipe_transfer *transfer) -{ - return (struct brw_transfer *)transfer; -} static INLINE struct brw_surface * brw_surface(struct pipe_surface *surface) @@ -147,60 +93,10 @@ brw_surface(struct pipe_surface *surface) return (struct brw_surface *)surface; } -static INLINE struct brw_buffer * -brw_buffer(struct pipe_buffer *buffer) -{ - return (struct brw_buffer *)buffer; -} - -static INLINE struct brw_texture * -brw_texture(struct pipe_texture *texture) -{ - return (struct brw_texture *)texture; -} - - -/* Pipe buffer helpers - */ -static INLINE boolean -brw_buffer_is_user_buffer( const struct pipe_buffer *buf ) -{ - return ((const struct brw_buffer *)buf)->user_buffer != NULL; -} - unsigned brw_surface_pitch( const struct pipe_surface *surface ); -/*********************************************************************** - * Internal functions - */ -GLboolean brw_texture_layout(struct brw_screen *brw_screen, - struct brw_texture *tex ); - -void brw_update_texture( struct brw_screen *brw_screen, - struct brw_texture *tex ); - - -/* brw_screen_texture.h - */ -struct brw_context; -void brw_tex_init( struct brw_context *brw ); -void brw_screen_tex_init( struct brw_screen *brw_screen ); void brw_screen_tex_surface_init( struct brw_screen *brw_screen ); -void brw_screen_buffer_init(struct brw_screen *brw_screen); - - -boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen, - struct pipe_texture *texture, - unsigned face, - unsigned level, - struct brw_winsys_buffer *bo ); - -boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen, - struct pipe_buffer *buffer, - struct brw_winsys_buffer *bo ); - - #endif /* BRW_SCREEN_H */ diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c deleted file mode 100644 index 0b38885f40c..00000000000 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ /dev/null @@ -1,202 +0,0 @@ - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" - -#include "brw_screen.h" -#include "brw_winsys.h" - - - -static void * -brw_buffer_map_range( struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned offset, - unsigned length, - unsigned usage ) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_winsys_screen *sws = bscreen->sws; - struct brw_buffer *buf = brw_buffer( buffer ); - - if (buf->user_buffer) - return buf->user_buffer; - - return sws->bo_map( buf->bo, - BRW_DATA_OTHER, - offset, - length, - (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, - (usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE, - (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE); -} - -static void * -brw_buffer_map( struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned usage ) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_winsys_screen *sws = bscreen->sws; - struct brw_buffer *buf = brw_buffer( buffer ); - - if (buf->user_buffer) - return buf->user_buffer; - - return sws->bo_map( buf->bo, - BRW_DATA_OTHER, - 0, - buf->base.size, - (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, - FALSE, - FALSE); -} - - -static void -brw_buffer_flush_mapped_range( struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned offset, - unsigned length ) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_winsys_screen *sws = bscreen->sws; - struct brw_buffer *buf = brw_buffer( buffer ); - - if (buf->user_buffer) - return; - - sws->bo_flush_range( buf->bo, - offset, - length ); -} - - -static void -brw_buffer_unmap( struct pipe_screen *screen, - struct pipe_buffer *buffer ) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_winsys_screen *sws = bscreen->sws; - struct brw_buffer *buf = brw_buffer( buffer ); - - if (buf->bo) - sws->bo_unmap(buf->bo); -} - -static void -brw_buffer_destroy( struct pipe_buffer *buffer ) -{ - struct brw_buffer *buf = brw_buffer( buffer ); - - assert(!p_atomic_read(&buffer->reference.count)); - - bo_reference(&buf->bo, NULL); - FREE(buf); -} - - -static struct pipe_buffer * -brw_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct brw_screen *bscreen = brw_screen(screen); - struct brw_winsys_screen *sws = bscreen->sws; - struct brw_buffer *buf; - unsigned buffer_type; - enum pipe_error ret; - - buf = CALLOC_STRUCT(brw_buffer); - if (!buf) - return NULL; - - pipe_reference_init(&buf->base.reference, 1); - buf->base.screen = screen; - buf->base.alignment = alignment; - buf->base.usage = usage; - buf->base.size = size; - - switch (usage & (PIPE_BUFFER_USAGE_VERTEX | - PIPE_BUFFER_USAGE_INDEX | - PIPE_BUFFER_USAGE_PIXEL | - PIPE_BUFFER_USAGE_CONSTANT)) - { - case PIPE_BUFFER_USAGE_VERTEX: - case PIPE_BUFFER_USAGE_INDEX: - case (PIPE_BUFFER_USAGE_VERTEX|PIPE_BUFFER_USAGE_INDEX): - buffer_type = BRW_BUFFER_TYPE_VERTEX; - break; - - case PIPE_BUFFER_USAGE_PIXEL: - buffer_type = BRW_BUFFER_TYPE_PIXEL; - break; - - case PIPE_BUFFER_USAGE_CONSTANT: - buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS; - break; - - default: - buffer_type = BRW_BUFFER_TYPE_GENERIC; - break; - } - - ret = sws->bo_alloc( sws, buffer_type, - size, alignment, - &buf->bo ); - if (ret != PIPE_OK) - return NULL; - - return &buf->base; -} - - -static struct pipe_buffer * -brw_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct brw_buffer *buf; - - buf = CALLOC_STRUCT(brw_buffer); - if (!buf) - return NULL; - - buf->user_buffer = ptr; - - pipe_reference_init(&buf->base.reference, 1); - buf->base.screen = screen; - buf->base.alignment = 1; - buf->base.usage = 0; - buf->base.size = bytes; - - return &buf->base; -} - - -boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen, - struct pipe_buffer *buffer, - struct brw_winsys_buffer *bo ) -{ - struct brw_buffer *buf = brw_buffer(buffer); - if (buf->bo == NULL) - return FALSE; - - return brw_screen->sws->bo_references( bo, buf->bo ); -} - - -void brw_screen_buffer_init(struct brw_screen *brw_screen) -{ - brw_screen->base.buffer_create = brw_buffer_create; - brw_screen->base.user_buffer_create = brw_user_buffer_create; - brw_screen->base.buffer_map = brw_buffer_map; - brw_screen->base.buffer_map_range = brw_buffer_map_range; - brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range; - brw_screen->base.buffer_unmap = brw_buffer_unmap; - brw_screen->base.buffer_destroy = brw_buffer_destroy; -} diff --git a/src/gallium/drivers/i965/brw_screen_surface.c b/src/gallium/drivers/i965/brw_screen_surface.c index 904df813dda..f288fdbcd37 100644 --- a/src/gallium/drivers/i965/brw_screen_surface.c +++ b/src/gallium/drivers/i965/brw_screen_surface.c @@ -36,6 +36,7 @@ #include "pipe/p_screen.h" #include "brw_screen.h" #include "brw_defines.h" +#include "brw_resource.h" #include "brw_winsys.h" enum { @@ -138,9 +139,9 @@ static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen, */ assert(id.bits.zslice == 0); - surface->base.format = tex->base.format; - surface->base.width = u_minify(tex->base.width0, id.bits.level); - surface->base.height = u_minify(tex->base.height0, id.bits.level); + surface->base.format = tex->b.b.format; + surface->base.width = u_minify(tex->b.b.width0, id.bits.level); + surface->base.height = u_minify(tex->b.b.height0, id.bits.level); surface->base.offset = tex->image_offset[id.bits.level][id.bits.face]; surface->base.usage = usage; surface->base.zslice = id.bits.zslice; @@ -152,7 +153,7 @@ static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen, surface->tiling = tex->tiling; bo_reference( &surface->bo, tex->bo ); - pipe_texture_reference( &surface->base.texture, &tex->base ); + pipe_resource_reference( &surface->base.texture, &tex->b.b ); surface->ss.ss0.surface_format = tex->ss.ss0.surface_format; surface->ss.ss0.surface_type = BRW_SURFACE_2D; @@ -198,7 +199,7 @@ static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen, /* Get a surface which is view into a texture */ static struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage ) @@ -246,7 +247,7 @@ static void brw_tex_surface_destroy( struct pipe_surface *surf ) */ remove_from_list(surface); bo_reference(&surface->bo, NULL); - pipe_texture_reference( &surface->base.texture, NULL ); + pipe_resource_reference( &surface->base.texture, NULL ); FREE(surface); diff --git a/src/gallium/drivers/i965/brw_util.c b/src/gallium/drivers/i965/brw_util.c deleted file mode 100644 index 1fd2e297137..00000000000 --- a/src/gallium/drivers/i965/brw_util.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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 the rights to use, copy, modify, merge, publish, - distribute, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell <[email protected]> - */ - - - - - - diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 004e3cb4e6f..424bb0d0dfb 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -82,7 +82,7 @@ brw_update_vs_constant_surface( struct brw_context *brw, GLuint surf) { struct brw_surface_key key; - struct pipe_buffer *cb = brw->curr.vs_constants; + struct pipe_resource *cb = brw->curr.vs_constants; enum pipe_error ret; assert(surf == 0); diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 7ed2378ec04..5d66e61fbc1 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -35,6 +35,7 @@ #include "brw_wm.h" #include "brw_state.h" #include "brw_debug.h" +#include "brw_resource.h" #include "brw_pipe_rast.h" @@ -254,10 +255,10 @@ static void brw_wm_populate_key( struct brw_context *brw, for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) { const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture); - if (tex->base.format == PIPE_FORMAT_UYVY) + if (tex->b.b.format == PIPE_FORMAT_UYVY) key->yuvtex_mask |= 1 << i; - if (tex->base.format == PIPE_FORMAT_YUYV) + if (tex->b.b.format == PIPE_FORMAT_YUYV) key->yuvtex_swap_mask |= 1 << i; /* XXX: shadow texture diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c index 6434c6acf73..df5cd0398c9 100644 --- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c +++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c @@ -62,7 +62,7 @@ brw_update_wm_constant_surface( struct brw_context *brw, { struct brw_surface_key key; struct brw_fragment_shader *fp = brw->curr.fragment_shader; - struct pipe_buffer *cbuf = brw->curr.fragment_constants; + struct pipe_resource *cbuf = brw->curr.fragment_constants; int pitch = cbuf->size / (4 * sizeof(float)); enum pipe_error ret; diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 3f18062c584..8406a1a9e20 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -35,7 +35,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "brw_screen.h" +#include "brw_resource.h" /* Samplers aren't strictly wm state from the hardware's perspective, @@ -94,7 +94,7 @@ brw_wm_sampler_populate_key(struct brw_context *brw, /* Cube-maps on 965 and later must use the same wrap mode for all 3 * coordinate dimensions. Futher, only CUBE and CLAMP are valid. */ - if (tex->base.target == PIPE_TEXTURE_CUBE) { + if (tex->b.b.target == PIPE_TEXTURE_CUBE) { if (FALSE && (sampler->ss0.min_filter != BRW_MAPFILTER_NEAREST || sampler->ss0.mag_filter != BRW_MAPFILTER_NEAREST)) { @@ -106,7 +106,7 @@ brw_wm_sampler_populate_key(struct brw_context *brw, entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; } - } else if (tex->base.target == PIPE_TEXTURE_1D) { + } else if (tex->b.b.target == PIPE_TEXTURE_1D) { /* There's a bug in 1D texture sampling - it actually pays * attention to the wrap_t value, though it should not. * Override the wrap_t value here to GL_REPEAT to keep @@ -137,7 +137,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) sampler->border_color[0] }; - if (util_format_is_depth_or_stencil(tex->base.format)) { + if (util_format_is_depth_or_stencil(tex->b.b.format)) { bc = bordercolor; } else { diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index 2368ae3f808..0d80a0114af 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -34,7 +34,7 @@ #include "brw_batchbuffer.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_screen.h" +#include "brw_resource.h" diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 00a542215ad..3b7eaecc02f 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -28,6 +28,7 @@ #include "pipe/p_context.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "id_context.h" #include "id_objects.h" @@ -61,19 +62,19 @@ identity_draw_arrays(struct pipe_context *_pipe, static void identity_draw_elements(struct pipe_context *_pipe, - struct pipe_buffer *_indexBuffer, + struct pipe_resource *_indexResource, unsigned indexSize, unsigned prim, unsigned start, unsigned count) { struct identity_context *id_pipe = identity_context(_pipe); - struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct identity_resource *id_resource = identity_resource(_indexResource); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_buffer *indexBuffer = id_buffer->buffer; + struct pipe_resource *indexResource = id_resource->resource; pipe->draw_elements(pipe, - indexBuffer, + indexResource, indexSize, prim, start, @@ -82,7 +83,7 @@ identity_draw_elements(struct pipe_context *_pipe, static void identity_draw_range_elements(struct pipe_context *_pipe, - struct pipe_buffer *_indexBuffer, + struct pipe_resource *_indexResource, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -91,12 +92,12 @@ identity_draw_range_elements(struct pipe_context *_pipe, unsigned count) { struct identity_context *id_pipe = identity_context(_pipe); - struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct identity_resource *id_resource = identity_resource(_indexResource); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_buffer *indexBuffer = id_buffer->buffer; + struct pipe_resource *indexResource = id_resource->resource; pipe->draw_range_elements(pipe, - indexBuffer, + indexResource, indexSize, minIndex, maxIndex, @@ -450,23 +451,23 @@ static void identity_set_constant_buffer(struct pipe_context *_pipe, uint shader, uint index, - struct pipe_buffer *_buffer) + struct pipe_resource *_resource) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_buffer *unwrapped_buffer; - struct pipe_buffer *buffer = NULL; + struct pipe_resource *unwrapped_resource; + struct pipe_resource *resource = NULL; /* XXX hmm? unwrap the input state */ - if (_buffer) { - unwrapped_buffer = identity_buffer_unwrap(_buffer); - buffer = unwrapped_buffer; + if (_resource) { + unwrapped_resource = identity_resource_unwrap(_resource); + resource = unwrapped_resource; } pipe->set_constant_buffer(pipe, shader, index, - buffer); + resource); } static void @@ -587,7 +588,7 @@ identity_set_vertex_buffers(struct pipe_context *_pipe, if (num_buffers) { memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); for (i = 0; i < num_buffers; i++) - unwrapped_buffers[i].buffer = identity_buffer_unwrap(_buffers[i].buffer); + unwrapped_buffers[i].buffer = identity_resource_unwrap(_buffers[i].buffer); buffers = unwrapped_buffers; } @@ -678,44 +679,31 @@ identity_flush(struct pipe_context *_pipe, } static unsigned int -identity_is_texture_referenced(struct pipe_context *_pipe, - struct pipe_texture *_texture, +identity_is_resource_referenced(struct pipe_context *_pipe, + struct pipe_resource *_resource, unsigned face, unsigned level) { struct identity_context *id_pipe = identity_context(_pipe); - struct identity_texture *id_texture = identity_texture(_texture); + struct identity_resource *id_resource = identity_resource(_resource); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_texture *texture = id_texture->texture; + struct pipe_resource *texture = id_resource->resource; - return pipe->is_texture_referenced(pipe, + return pipe->is_resource_referenced(pipe, texture, face, level); } -static unsigned int -identity_is_buffer_referenced(struct pipe_context *_pipe, - struct pipe_buffer *_buffer) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_buffer *buffer = id_buffer->buffer; - - return pipe->is_buffer_referenced(pipe, - buffer); -} - static struct pipe_sampler_view * identity_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct identity_context *id_pipe = identity_context(pipe); - struct identity_texture *id_texture = identity_texture(texture); + struct identity_resource *id_resource = identity_resource(texture); struct pipe_context *pipe_unwrapped = id_pipe->pipe; - struct pipe_texture *texture_unwrapped = id_texture->texture; + struct pipe_resource *texture_unwrapped = id_resource->resource; struct identity_sampler_view *view = malloc(sizeof(struct identity_sampler_view)); view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped, @@ -725,7 +713,7 @@ identity_create_sampler_view(struct pipe_context *pipe, view->base = *templ; view->base.reference.count = 1; view->base.texture = NULL; - pipe_texture_reference(&view->base.texture, texture); + pipe_resource_reference(&view->base.texture, texture); view->base.context = pipe; return &view->base; @@ -743,47 +731,36 @@ identity_sampler_view_destroy(struct pipe_context *pipe, pipe_unwrapped->sampler_view_destroy(pipe_unwrapped, view_unwrapped); - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); free(view); } - static struct pipe_transfer * -identity_context_get_tex_transfer(struct pipe_context *_context, - struct pipe_texture *_texture, - unsigned face, - unsigned level, - unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, - unsigned y, - unsigned w, - unsigned h) +identity_context_get_transfer(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct identity_context *id_context = identity_context(_context); - struct identity_texture *id_texture = identity_texture(_texture); + struct identity_resource *id_resource = identity_resource(_resource); struct pipe_context *context = id_context->pipe; - struct pipe_texture *texture = id_texture->texture; + struct pipe_resource *texture = id_resource->resource; struct pipe_transfer *result; - result = context->get_tex_transfer(context, - texture, - face, - level, - zslice, - usage, - x, - y, - w, - h); + result = context->get_transfer(context, + texture, + sr, + usage, + box); if (result) - return identity_transfer_create(id_context, id_texture, result); + return identity_transfer_create(id_context, id_resource, result); return NULL; } static void -identity_context_tex_transfer_destroy(struct pipe_context *_pipe, +identity_context_transfer_destroy(struct pipe_context *_pipe, struct pipe_transfer *_transfer) { identity_transfer_destroy(identity_context(_pipe), @@ -803,6 +780,24 @@ identity_context_transfer_map(struct pipe_context *_context, transfer); } + + +static void +identity_context_transfer_flush_region( struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) +{ + struct identity_context *id_context = identity_context(_context); + struct identity_transfer *id_transfer = identity_transfer(_transfer); + struct pipe_context *context = id_context->pipe; + struct pipe_transfer *transfer = id_transfer->transfer; + + context->transfer_flush_region(context, + transfer, + box); +} + + static void identity_context_transfer_unmap(struct pipe_context *_context, struct pipe_transfer *_transfer) @@ -816,6 +811,33 @@ identity_context_transfer_unmap(struct pipe_context *_context, transfer); } + +static void +identity_context_transfer_inline_write( struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ + struct identity_context *id_context = identity_context(_context); + struct identity_resource *id_resource = identity_resource(_resource); + struct pipe_context *context = id_context->pipe; + struct pipe_resource *texture = id_resource->resource; + + context->transfer_inline_write(context, + texture, + sr, + usage, + box, + data, + stride, + slice_stride); +} + + struct pipe_context * identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) { @@ -878,14 +900,15 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.surface_fill = identity_surface_fill; id_pipe->base.clear = identity_clear; id_pipe->base.flush = identity_flush; - id_pipe->base.is_texture_referenced = identity_is_texture_referenced; - id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; + id_pipe->base.is_resource_referenced = identity_is_resource_referenced; id_pipe->base.create_sampler_view = identity_create_sampler_view; id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy; - id_pipe->base.get_tex_transfer = identity_context_get_tex_transfer; - id_pipe->base.tex_transfer_destroy = identity_context_tex_transfer_destroy; + id_pipe->base.get_transfer = identity_context_get_transfer; + id_pipe->base.transfer_destroy = identity_context_transfer_destroy; id_pipe->base.transfer_map = identity_context_transfer_map; id_pipe->base.transfer_unmap = identity_context_transfer_unmap; + id_pipe->base.transfer_flush_region = identity_context_transfer_flush_region; + id_pipe->base.transfer_inline_write = identity_context_transfer_inline_write; id_pipe->pipe = pipe; diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c index d37fb0042e5..d50914e7d5d 100644 --- a/src/gallium/drivers/identity/id_objects.c +++ b/src/gallium/drivers/identity/id_objects.c @@ -32,80 +32,46 @@ #include "id_objects.h" #include "id_context.h" -struct pipe_buffer * -identity_buffer_create(struct identity_screen *id_screen, - struct pipe_buffer *buffer) -{ - struct identity_buffer *id_buffer; - - if(!buffer) - goto error; - - assert(buffer->screen == id_screen->screen); - - id_buffer = CALLOC_STRUCT(identity_buffer); - if(!id_buffer) - goto error; - - memcpy(&id_buffer->base, buffer, sizeof(struct pipe_buffer)); - - pipe_reference_init(&id_buffer->base.reference, 1); - id_buffer->base.screen = &id_screen->base; - id_buffer->buffer = buffer; - - return &id_buffer->base; - -error: - pipe_buffer_reference(&buffer, NULL); - return NULL; -} - -void -identity_buffer_destroy(struct identity_buffer *id_buffer) -{ - pipe_buffer_reference(&id_buffer->buffer, NULL); - FREE(id_buffer); -} -struct pipe_texture * -identity_texture_create(struct identity_screen *id_screen, - struct pipe_texture *texture) +struct pipe_resource * +identity_resource_create(struct identity_screen *id_screen, + struct pipe_resource *resource) { - struct identity_texture *id_texture; + struct identity_resource *id_resource; - if(!texture) + if(!resource) goto error; - assert(texture->screen == id_screen->screen); + assert(resource->screen == id_screen->screen); - id_texture = CALLOC_STRUCT(identity_texture); - if(!id_texture) + id_resource = CALLOC_STRUCT(identity_resource); + if(!id_resource) goto error; - memcpy(&id_texture->base, texture, sizeof(struct pipe_texture)); + memcpy(&id_resource->base, resource, sizeof(struct pipe_resource)); - pipe_reference_init(&id_texture->base.reference, 1); - id_texture->base.screen = &id_screen->base; - id_texture->texture = texture; + pipe_reference_init(&id_resource->base.reference, 1); + id_resource->base.screen = &id_screen->base; + id_resource->resource = resource; - return &id_texture->base; + return &id_resource->base; error: - pipe_texture_reference(&texture, NULL); + pipe_resource_reference(&resource, NULL); return NULL; } void -identity_texture_destroy(struct identity_texture *id_texture) +identity_resource_destroy(struct identity_resource *id_resource) { - pipe_texture_reference(&id_texture->texture, NULL); - FREE(id_texture); + pipe_resource_reference(&id_resource->resource, NULL); + FREE(id_resource); } struct pipe_surface * -identity_surface_create(struct identity_texture *id_texture, +identity_surface_create(struct identity_resource *id_resource, struct pipe_surface *surface) { struct identity_surface *id_surface; @@ -113,7 +79,7 @@ identity_surface_create(struct identity_texture *id_texture, if(!surface) goto error; - assert(surface->texture == id_texture->texture); + assert(surface->texture == id_resource->resource); id_surface = CALLOC_STRUCT(identity_surface); if(!id_surface) @@ -123,7 +89,7 @@ identity_surface_create(struct identity_texture *id_texture, pipe_reference_init(&id_surface->base.reference, 1); id_surface->base.texture = NULL; - pipe_texture_reference(&id_surface->base.texture, &id_texture->base); + pipe_resource_reference(&id_surface->base.texture, &id_resource->base); id_surface->surface = surface; return &id_surface->base; @@ -136,7 +102,7 @@ error: void identity_surface_destroy(struct identity_surface *id_surface) { - pipe_texture_reference(&id_surface->base.texture, NULL); + pipe_resource_reference(&id_surface->base.texture, NULL); pipe_surface_reference(&id_surface->surface, NULL); FREE(id_surface); } @@ -144,7 +110,7 @@ identity_surface_destroy(struct identity_surface *id_surface) struct pipe_transfer * identity_transfer_create(struct identity_context *id_context, - struct identity_texture *id_texture, + struct identity_resource *id_resource, struct pipe_transfer *transfer) { struct identity_transfer *id_transfer; @@ -152,7 +118,7 @@ identity_transfer_create(struct identity_context *id_context, if(!transfer) goto error; - assert(transfer->texture == id_texture->texture); + assert(transfer->resource == id_resource->resource); id_transfer = CALLOC_STRUCT(identity_transfer); if(!id_transfer) @@ -160,16 +126,16 @@ identity_transfer_create(struct identity_context *id_context, memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer)); - id_transfer->base.texture = NULL; + id_transfer->base.resource = NULL; id_transfer->transfer = transfer; - pipe_texture_reference(&id_transfer->base.texture, &id_texture->base); - assert(id_transfer->base.texture == &id_texture->base); + pipe_resource_reference(&id_transfer->base.resource, &id_resource->base); + assert(id_transfer->base.resource == &id_resource->base); return &id_transfer->base; error: - id_context->pipe->tex_transfer_destroy(id_context->pipe, transfer); + id_context->pipe->transfer_destroy(id_context->pipe, transfer); return NULL; } @@ -177,47 +143,9 @@ void identity_transfer_destroy(struct identity_context *id_context, struct identity_transfer *id_transfer) { - pipe_texture_reference(&id_transfer->base.texture, NULL); - id_context->pipe->tex_transfer_destroy(id_context->pipe, - id_transfer->transfer); + pipe_resource_reference(&id_transfer->base.resource, NULL); + id_context->pipe->transfer_destroy(id_context->pipe, + id_transfer->transfer); FREE(id_transfer); } -struct pipe_video_surface * -identity_video_surface_create(struct identity_screen *id_screen, - struct pipe_video_surface *video_surface) -{ - struct identity_video_surface *id_video_surface; - - if (!video_surface) { - goto error; - } - - assert(video_surface->screen == id_screen->screen); - - id_video_surface = CALLOC_STRUCT(identity_video_surface); - if (!id_video_surface) { - goto error; - } - - memcpy(&id_video_surface->base, - video_surface, - sizeof(struct pipe_video_surface)); - - pipe_reference_init(&id_video_surface->base.reference, 1); - id_video_surface->base.screen = &id_screen->base; - id_video_surface->video_surface = video_surface; - - return &id_video_surface->base; - -error: - pipe_video_surface_reference(&video_surface, NULL); - return NULL; -} - -void -identity_video_surface_destroy(struct identity_video_surface *id_video_surface) -{ - pipe_video_surface_reference(&id_video_surface->video_surface, NULL); - FREE(id_video_surface); -} diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h index 9a07ebe8d72..058cf3009df 100644 --- a/src/gallium/drivers/identity/id_objects.h +++ b/src/gallium/drivers/identity/id_objects.h @@ -31,25 +31,17 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" -#include "pipe/p_video_state.h" #include "id_screen.h" struct identity_context; -struct identity_buffer -{ - struct pipe_buffer base; - - struct pipe_buffer *buffer; -}; - -struct identity_texture +struct identity_resource { - struct pipe_texture base; + struct pipe_resource base; - struct pipe_texture *texture; + struct pipe_resource *resource; }; @@ -78,30 +70,13 @@ struct identity_transfer }; -struct identity_video_surface -{ - struct pipe_video_surface base; - - struct pipe_video_surface *video_surface; -}; - - -static INLINE struct identity_buffer * -identity_buffer(struct pipe_buffer *_buffer) +static INLINE struct identity_resource * +identity_resource(struct pipe_resource *_resource) { - if(!_buffer) + if(!_resource) return NULL; - (void)identity_screen(_buffer->screen); - return (struct identity_buffer *)_buffer; -} - -static INLINE struct identity_texture * -identity_texture(struct pipe_texture *_texture) -{ - if(!_texture) - return NULL; - (void)identity_screen(_texture->screen); - return (struct identity_texture *)_texture; + (void)identity_screen(_resource->screen); + return (struct identity_resource *)_resource; } static INLINE struct identity_sampler_view * @@ -118,7 +93,7 @@ identity_surface(struct pipe_surface *_surface) { if(!_surface) return NULL; - (void)identity_texture(_surface->texture); + (void)identity_resource(_surface->texture); return (struct identity_surface *)_surface; } @@ -127,34 +102,16 @@ identity_transfer(struct pipe_transfer *_transfer) { if(!_transfer) return NULL; - (void)identity_texture(_transfer->texture); + (void)identity_resource(_transfer->resource); return (struct identity_transfer *)_transfer; } -static INLINE struct identity_video_surface * -identity_video_surface(struct pipe_video_surface *_video_surface) -{ - if (!_video_surface) { - return NULL; - } - (void)identity_screen(_video_surface->screen); - return (struct identity_video_surface *)_video_surface; -} - -static INLINE struct pipe_buffer * -identity_buffer_unwrap(struct pipe_buffer *_buffer) -{ - if(!_buffer) - return NULL; - return identity_buffer(_buffer)->buffer; -} - -static INLINE struct pipe_texture * -identity_texture_unwrap(struct pipe_texture *_texture) +static INLINE struct pipe_resource * +identity_resource_unwrap(struct pipe_resource *_resource) { - if(!_texture) + if(!_resource) return NULL; - return identity_texture(_texture)->texture; + return identity_resource(_resource)->resource; } static INLINE struct pipe_sampler_view * @@ -183,22 +140,15 @@ identity_transfer_unwrap(struct pipe_transfer *_transfer) } -struct pipe_buffer * -identity_buffer_create(struct identity_screen *id_screen, - struct pipe_buffer *buffer); - -void -identity_buffer_destroy(struct identity_buffer *id_buffer); - -struct pipe_texture * -identity_texture_create(struct identity_screen *id_screen, - struct pipe_texture *texture); +struct pipe_resource * +identity_resource_create(struct identity_screen *id_screen, + struct pipe_resource *resource); void -identity_texture_destroy(struct identity_texture *id_texture); +identity_resource_destroy(struct identity_resource *id_resource); struct pipe_surface * -identity_surface_create(struct identity_texture *id_texture, +identity_surface_create(struct identity_resource *id_resource, struct pipe_surface *surface); void @@ -206,19 +156,12 @@ identity_surface_destroy(struct identity_surface *id_surface); struct pipe_transfer * identity_transfer_create(struct identity_context *id_context, - struct identity_texture *id_texture, + struct identity_resource *id_resource, struct pipe_transfer *transfer); void identity_transfer_destroy(struct identity_context *id_context, struct identity_transfer *id_transfer); -struct pipe_video_surface * -identity_video_surface_create(struct identity_screen *id_screen, - struct pipe_video_surface *video_surface); - -void -identity_video_surface_destroy(struct identity_video_surface *id_video_surface); - #endif /* ID_OBJECTS_H */ diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 419b1465787..52573b211fb 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -118,75 +118,76 @@ identity_screen_context_create(struct pipe_screen *_screen, return NULL; } -static struct pipe_texture * -identity_screen_texture_create(struct pipe_screen *_screen, - const struct pipe_texture *templat) +static struct pipe_resource * +identity_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; - struct pipe_texture *result; + struct pipe_resource *result; - result = screen->texture_create(screen, + result = screen->resource_create(screen, templat); if (result) - return identity_texture_create(id_screen, result); + return identity_resource_create(id_screen, result); return NULL; } -static struct pipe_texture * -identity_screen_texture_from_handle(struct pipe_screen *_screen, - const struct pipe_texture *templ, +static struct pipe_resource * +identity_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, struct winsys_handle *handle) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; - struct pipe_texture *result; + struct pipe_resource *result; /* TODO trace call */ - result = screen->texture_from_handle(screen, templ, handle); + result = screen->resource_from_handle(screen, templ, handle); - result = identity_texture_create(identity_screen(_screen), result); + result = identity_resource_create(identity_screen(_screen), result); return result; } static boolean -identity_screen_texture_get_handle(struct pipe_screen *_screen, - struct pipe_texture *_texture, +identity_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_resource *_texture, struct winsys_handle *handle) { struct identity_screen *id_screen = identity_screen(_screen); - struct identity_texture *id_texture = identity_texture(_texture); + struct identity_resource *id_resource = identity_resource(_texture); struct pipe_screen *screen = id_screen->screen; - struct pipe_texture *texture = id_texture->texture; + struct pipe_resource *texture = id_resource->resource; /* TODO trace call */ - return screen->texture_get_handle(screen, texture, handle); + return screen->resource_get_handle(screen, texture, handle); } static void -identity_screen_texture_destroy(struct pipe_texture *_texture) +identity_screen_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *_texture) { - identity_texture_destroy(identity_texture(_texture)); + identity_resource_destroy(identity_resource(_texture)); } static struct pipe_surface * identity_screen_get_tex_surface(struct pipe_screen *_screen, - struct pipe_texture *_texture, + struct pipe_resource *_texture, unsigned face, unsigned level, unsigned zslice, unsigned usage) { struct identity_screen *id_screen = identity_screen(_screen); - struct identity_texture *id_texture = identity_texture(_texture); + struct identity_resource *id_resource = identity_resource(_texture); struct pipe_screen *screen = id_screen->screen; - struct pipe_texture *texture = id_texture->texture; + struct pipe_resource *texture = id_resource->resource; struct pipe_surface *result; result = screen->get_tex_surface(screen, @@ -197,7 +198,7 @@ identity_screen_get_tex_surface(struct pipe_screen *_screen, usage); if (result) - return identity_surface_create(id_texture, result); + return identity_surface_create(id_resource, result); return NULL; } @@ -208,141 +209,28 @@ identity_screen_tex_surface_destroy(struct pipe_surface *_surface) } -static struct pipe_buffer * -identity_screen_buffer_create(struct pipe_screen *_screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *result; - - result = screen->buffer_create(screen, - alignment, - usage, - size); - if (result) - return identity_buffer_create(id_screen, result); - return NULL; -} - -static struct pipe_buffer * +static struct pipe_resource * identity_screen_user_buffer_create(struct pipe_screen *_screen, void *ptr, - unsigned bytes) + unsigned bytes, + unsigned usage) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *result; + struct pipe_resource *result; result = screen->user_buffer_create(screen, ptr, - bytes); + bytes, + usage); if (result) - return identity_buffer_create(id_screen, result); + return identity_resource_create(id_screen, result); return NULL; } -static void * -identity_screen_buffer_map(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned usage) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *buffer = id_buffer->buffer; - - return screen->buffer_map(screen, - buffer, - usage); -} - -static void * -identity_screen_buffer_map_range(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned offset, - unsigned length, - unsigned usage) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *buffer = id_buffer->buffer; - - return screen->buffer_map_range(screen, - buffer, - offset, - length, - usage); -} - -static void -identity_screen_buffer_flush_mapped_range(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned offset, - unsigned length) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *buffer = id_buffer->buffer; - - screen->buffer_flush_mapped_range(screen, - buffer, - offset, - length); -} - -static void -identity_screen_buffer_unmap(struct pipe_screen *_screen, - struct pipe_buffer *_buffer) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *buffer = id_buffer->buffer; - - screen->buffer_unmap(screen, - buffer); -} - -static void -identity_screen_buffer_destroy(struct pipe_buffer *_buffer) -{ - identity_buffer_destroy(identity_buffer(_buffer)); -} - -static struct pipe_video_surface * -identity_screen_video_surface_create(struct pipe_screen *_screen, - enum pipe_video_chroma_format chroma_format, - unsigned width, - unsigned height) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct pipe_screen *screen = id_screen->screen; - struct pipe_video_surface *result; - - result = screen->video_surface_create(screen, - chroma_format, - width, - height); - - if (result) { - return identity_video_surface_create(id_screen, result); - } - return NULL; -} - -static void -identity_screen_video_surface_destroy(struct pipe_video_surface *_vsfc) -{ - identity_video_surface_destroy(identity_video_surface(_vsfc)); -} static void identity_screen_flush_frontbuffer(struct pipe_screen *_screen, @@ -417,29 +305,13 @@ identity_screen_create(struct pipe_screen *screen) id_screen->base.get_paramf = identity_screen_get_paramf; id_screen->base.is_format_supported = identity_screen_is_format_supported; id_screen->base.context_create = identity_screen_context_create; - id_screen->base.texture_create = identity_screen_texture_create; - id_screen->base.texture_from_handle = identity_screen_texture_from_handle; - id_screen->base.texture_get_handle = identity_screen_texture_get_handle; - id_screen->base.texture_destroy = identity_screen_texture_destroy; + id_screen->base.resource_create = identity_screen_resource_create; + id_screen->base.resource_from_handle = identity_screen_resource_from_handle; + id_screen->base.resource_get_handle = identity_screen_resource_get_handle; + id_screen->base.resource_destroy = identity_screen_resource_destroy; id_screen->base.get_tex_surface = identity_screen_get_tex_surface; id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy; - id_screen->base.buffer_create = identity_screen_buffer_create; id_screen->base.user_buffer_create = identity_screen_user_buffer_create; - if (screen->buffer_map) - id_screen->base.buffer_map = identity_screen_buffer_map; - if (screen->buffer_map_range) - id_screen->base.buffer_map_range = identity_screen_buffer_map_range; - if (screen->buffer_flush_mapped_range) - id_screen->base.buffer_flush_mapped_range = identity_screen_buffer_flush_mapped_range; - if (screen->buffer_unmap) - id_screen->base.buffer_unmap = identity_screen_buffer_unmap; - id_screen->base.buffer_destroy = identity_screen_buffer_destroy; - if (screen->video_surface_create) { - id_screen->base.video_surface_create = identity_screen_video_surface_create; - } - if (screen->video_surface_destroy) { - id_screen->base.video_surface_destroy = identity_screen_video_surface_destroy; - } id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer; id_screen->base.fence_reference = identity_screen_fence_reference; id_screen->base.fence_signalled = identity_screen_fence_signalled; diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 7bfce15c2ed..a35a24f5b06 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -6,7 +6,6 @@ LIBNAME = llvmpipe DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS C_SOURCES = \ - lp_buffer.c \ lp_clear.c \ lp_context.c \ lp_draw_arrays.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 07e6ccfce45..f5a38d05d48 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -27,7 +27,6 @@ env.Depends('lp_tile_soa.c', [ llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ - 'lp_buffer.c', 'lp_clear.c', 'lp_context.c', 'lp_draw_arrays.c', diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c deleted file mode 100644 index 6e0f37393e9..00000000000 --- a/src/gallium/drivers/llvmpipe/lp_buffer.c +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 VMWARE AND/OR ITS 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 "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "lp_screen.h" -#include "lp_buffer.h" - - -static void * -llvmpipe_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned flags) -{ - struct llvmpipe_buffer *llvmpipe_buf = llvmpipe_buffer(buf); - return llvmpipe_buf->data; -} - - -static void -llvmpipe_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ -} - - -static void -llvmpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct llvmpipe_buffer *sbuf = llvmpipe_buffer(buf); - - if (!sbuf->userBuffer) - align_free(sbuf->data); - - FREE(sbuf); -} - - -static struct pipe_buffer * -llvmpipe_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct llvmpipe_buffer *buffer = CALLOC_STRUCT(llvmpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.alignment = MAX2(alignment, 16); - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -llvmpipe_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct llvmpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(llvmpipe_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -void -llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen) -{ - screen->buffer_create = llvmpipe_buffer_create; - screen->user_buffer_create = llvmpipe_user_buffer_create; - screen->buffer_map = llvmpipe_buffer_map; - screen->buffer_unmap = llvmpipe_buffer_unmap; - screen->buffer_destroy = llvmpipe_buffer_destroy; -} diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.h b/src/gallium/drivers/llvmpipe/lp_buffer.h deleted file mode 100644 index d6b8184a0b9..00000000000 --- a/src/gallium/drivers/llvmpipe/lp_buffer.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 VMWARE AND/OR ITS 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. - * - **************************************************************************/ - -#ifndef LP_BUFFER_H -#define LP_BUFFER_H - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - - -struct llvmpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; -}; - - -/** Cast wrapper */ -static INLINE struct llvmpipe_buffer * -llvmpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct llvmpipe_buffer *)buf; -} - - -void -llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen); - - -#endif /* LP_BUFFER_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 270ae451c04..c7acb0c5455 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -77,29 +77,13 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) for (i = 0; i < Elements(llvmpipe->constants); i++) { if (llvmpipe->constants[i]) { - pipe_buffer_reference(&llvmpipe->constants[i], NULL); + pipe_resource_reference(&llvmpipe->constants[i], NULL); } } align_free( llvmpipe ); } -static unsigned int -llvmpipe_is_texture_referenced( struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - - return lp_setup_is_texture_referenced(llvmpipe->setup, texture); -} - -static unsigned int -llvmpipe_is_buffer_referenced( struct pipe_context *pipe, - struct pipe_buffer *buf) -{ - return PIPE_UNREFERENCED; -} struct pipe_context * llvmpipe_create_context( struct pipe_screen *screen, void *priv ) @@ -171,11 +155,9 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe->pipe.clear = llvmpipe_clear; llvmpipe->pipe.flush = llvmpipe_flush; - llvmpipe->pipe.is_texture_referenced = llvmpipe_is_texture_referenced; - llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced; llvmpipe_init_query_funcs( llvmpipe ); - llvmpipe_init_context_texture_funcs( &llvmpipe->pipe ); + llvmpipe_init_context_resource_funcs( &llvmpipe->pipe ); /* * Create drawing context and plug our rendering stage into it. diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 71f991049e5..4848101ffb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -65,7 +65,7 @@ struct llvmpipe_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - struct pipe_buffer *constants[PIPE_SHADER_TYPES]; + struct pipe_resource *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 3dd68d5794e..a9b8ba258b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -35,7 +35,6 @@ #include "pipe/p_context.h" #include "util/u_prim.h" -#include "lp_buffer.h" #include "lp_context.h" #include "lp_state.h" @@ -58,7 +57,7 @@ llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, */ void llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -75,13 +74,13 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { - void *buf = llvmpipe_buffer(lp->vertex_buffer[i].buffer)->data; + void *buf = llvmpipe_resource(lp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = llvmpipe_buffer(indexBuffer)->data; + void *mapped_indexes = llvmpipe_resource(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, min_index, max_index, @@ -117,7 +116,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, void llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 782669a1e77..f1533f8f70c 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -103,7 +103,7 @@ llvmpipe_flush( struct pipe_context *pipe, */ boolean llvmpipe_flush_texture(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, unsigned face, unsigned level, unsigned flush_flags, @@ -113,7 +113,7 @@ llvmpipe_flush_texture(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_texture_referenced(pipe, texture, face, level); + referenced = pipe->is_resource_referenced(pipe, texture, face, level); if ((referenced & PIPE_REFERENCED_FOR_WRITE) || ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h index e13f57ccec5..2375d22b854 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.h +++ b/src/gallium/drivers/llvmpipe/lp_flush.h @@ -38,7 +38,7 @@ void llvmpipe_flush(struct pipe_context *pipe, unsigned flags, boolean llvmpipe_flush_texture(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, unsigned face, unsigned level, unsigned flush_flags, diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index e629a3e5f1f..fccc63c28fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -67,13 +67,13 @@ lp_rast_begin( struct lp_rasterizer *rast, rast->cbuf[i].format = cbuf->texture->format; rast->cbuf[i].width = cbuf->width; rast->cbuf[i].height = cbuf->height; - rast->cbuf[i].stride = llvmpipe_texture_stride(cbuf->texture, cbuf->level); + rast->cbuf[i].stride = llvmpipe_resource_stride(cbuf->texture, cbuf->level); } if (write_zstencil) { struct pipe_surface *zsbuf = scene->fb.zsbuf; rast->zsbuf.map = scene->zsbuf_map; - rast->zsbuf.stride = llvmpipe_texture_stride(zsbuf->texture, zsbuf->level); + rast->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level); rast->zsbuf.blocksize = util_format_get_blocksize(zsbuf->texture->format); } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 0c51b52d170..245d3875785 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -181,7 +181,7 @@ lp_scene_reset(struct lp_scene *scene ) struct texture_ref *ref, *next, *ref_list = &scene->textures; for (ref = ref_list->next; ref != ref_list; ref = next) { next = next_elem(ref); - pipe_texture_reference(&ref->texture, NULL); + pipe_resource_reference(&ref->texture, NULL); FREE(ref); } make_empty_list(ref_list); @@ -248,12 +248,12 @@ lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) */ void lp_scene_texture_reference( struct lp_scene *scene, - struct pipe_texture *texture ) + struct pipe_resource *texture ) { struct texture_ref *ref = CALLOC_STRUCT(texture_ref); if (ref) { struct texture_ref *ref_list = &scene->textures; - pipe_texture_reference(&ref->texture, texture); + pipe_resource_reference(&ref->texture, texture); insert_at_tail(ref_list, ref); } } @@ -263,8 +263,8 @@ lp_scene_texture_reference( struct lp_scene *scene, * Does this scene have a reference to the given texture? */ boolean -lp_scene_is_texture_referenced( const struct lp_scene *scene, - const struct pipe_texture *texture ) +lp_scene_is_resource_referenced( const struct lp_scene *scene, + const struct pipe_resource *texture ) { const struct texture_ref *ref_list = &scene->textures; const struct texture_ref *ref; @@ -398,20 +398,25 @@ static boolean lp_scene_map_buffers( struct lp_scene *scene ) { struct pipe_surface *cbuf, *zsbuf; + unsigned usage; int i; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + /* XXX: try to improve on this: + */ + usage = PIPE_TRANSFER_READ_WRITE; /* Map all color buffers */ for (i = 0; i < scene->fb.nr_cbufs; i++) { cbuf = scene->fb.cbufs[i]; if (cbuf) { - scene->cbuf_map[i] = llvmpipe_texture_map(cbuf->texture, - cbuf->face, - cbuf->level, - cbuf->zslice); + scene->cbuf_map[i] = llvmpipe_resource_map(cbuf->texture, + usage, + cbuf->face, + cbuf->level, + cbuf->zslice); if (!scene->cbuf_map[i]) goto fail; } @@ -421,10 +426,11 @@ lp_scene_map_buffers( struct lp_scene *scene ) */ zsbuf = scene->fb.zsbuf; if (zsbuf) { - scene->zsbuf_map = llvmpipe_texture_map(zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice); + scene->zsbuf_map = llvmpipe_resource_map(zsbuf->texture, + usage, + zsbuf->face, + zsbuf->level, + zsbuf->zslice); if (!scene->zsbuf_map) goto fail; } @@ -453,7 +459,7 @@ lp_scene_unmap_buffers( struct lp_scene *scene ) for (i = 0; i < scene->fb.nr_cbufs; i++) { if (scene->cbuf_map[i]) { struct pipe_surface *cbuf = scene->fb.cbufs[i]; - llvmpipe_texture_unmap(cbuf->texture, + llvmpipe_resource_unmap(cbuf->texture, cbuf->face, cbuf->level, cbuf->zslice); @@ -463,7 +469,7 @@ lp_scene_unmap_buffers( struct lp_scene *scene ) if (scene->zsbuf_map) { struct pipe_surface *zsbuf = scene->fb.zsbuf; - llvmpipe_texture_unmap(zsbuf->texture, + llvmpipe_resource_unmap(zsbuf->texture, zsbuf->face, zsbuf->level, zsbuf->zslice); diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index b602b1e8a05..a1fb8bf541b 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -99,7 +99,7 @@ struct data_block_list { /** List of texture references */ struct texture_ref { - struct pipe_texture *texture; + struct pipe_resource *texture; struct texture_ref *prev, *next; /**< linked list w/ u_simple_list.h */ }; @@ -168,10 +168,10 @@ unsigned lp_scene_data_size( const struct lp_scene *scene ); unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); void lp_scene_texture_reference( struct lp_scene *scene, - struct pipe_texture *texture ); + struct pipe_resource *texture ); -boolean lp_scene_is_texture_referenced( const struct lp_scene *scene, - const struct pipe_texture *texture ); +boolean lp_scene_is_resource_referenced( const struct lp_scene *scene, + const struct pipe_resource *texture ); /** diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 69995995580..6d309c6b647 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -33,7 +33,6 @@ #include "pipe/p_screen.h" #include "lp_texture.h" -#include "lp_buffer.h" #include "lp_fence.h" #include "lp_jit.h" #include "lp_screen.h" @@ -192,7 +191,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, break; } - if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + if(tex_usage & PIPE_BIND_RENDER_TARGET) { if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) return FALSE; @@ -205,14 +204,14 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, return FALSE; } - if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if(tex_usage & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } - if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + if(tex_usage & PIPE_BIND_DEPTH_STENCIL) { if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) return FALSE; @@ -234,7 +233,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen, { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; - struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture); + struct llvmpipe_resource *texture = llvmpipe_resource(surface->texture); assert(texture->dt); if (texture->dt) @@ -289,8 +288,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys) util_format_s3tc_init(); - llvmpipe_init_screen_texture_funcs(&screen->base); - llvmpipe_init_screen_buffer_funcs(&screen->base); + llvmpipe_init_screen_resource_funcs(&screen->base); llvmpipe_init_screen_fence_funcs(&screen->base); lp_jit_screen_init(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 76a8b87a309..b8abdfa1146 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -39,7 +39,6 @@ #include "util/u_surface.h" #include "lp_scene.h" #include "lp_scene_queue.h" -#include "lp_buffer.h" #include "lp_texture.h" #include "lp_debug.h" #include "lp_fence.h" @@ -379,11 +378,11 @@ lp_setup_set_fs_functions( struct lp_setup_context *setup, void lp_setup_set_fs_constants(struct lp_setup_context *setup, - struct pipe_buffer *buffer) + struct pipe_resource *buffer) { LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer); - pipe_buffer_reference(&setup->constants.current, buffer); + pipe_resource_reference(&setup->constants.current, buffer); setup->dirty |= LP_SETUP_NEW_CONSTANTS; } @@ -481,8 +480,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct pipe_sampler_view *view = i < num ? views[i] : NULL; if(view) { - struct pipe_texture *tex = view->texture; - struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); + struct pipe_resource *tex = view->texture; + struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); struct lp_jit_texture *jit_tex; jit_tex = &setup->fs.current.jit_context.textures[i]; jit_tex->width = tex->width0; @@ -493,7 +492,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, /* We're referencing the texture's internal data, so save a * reference to it. */ - pipe_texture_reference(&setup->fs.current_tex[i], tex); + pipe_resource_reference(&setup->fs.current_tex[i], tex); if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ @@ -513,7 +512,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ); jit_tex->row_stride[0] = lp_tex->stride[0]; assert(jit_tex->data[0]); } @@ -530,8 +529,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, * being rendered and the current scene being built. */ unsigned -lp_setup_is_texture_referenced( const struct lp_setup_context *setup, - const struct pipe_texture *texture ) +lp_setup_is_resource_referenced( const struct lp_setup_context *setup, + const struct pipe_resource *texture ) { unsigned i; @@ -546,7 +545,7 @@ lp_setup_is_texture_referenced( const struct lp_setup_context *setup, /* check textures referenced by the scene */ for (i = 0; i < Elements(setup->scenes); i++) { - if (lp_scene_is_texture_referenced(setup->scenes[i], texture)) { + if (lp_scene_is_resource_referenced(setup->scenes[i], texture)) { return PIPE_REFERENCED_FOR_READ; } } @@ -607,11 +606,11 @@ lp_setup_update_state( struct lp_setup_context *setup ) } if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { - struct pipe_buffer *buffer = setup->constants.current; + struct pipe_resource *buffer = setup->constants.current; if(buffer) { - unsigned current_size = buffer->size; - const void *current_data = llvmpipe_buffer(buffer)->data; + unsigned current_size = buffer->width0; + const void *current_data = llvmpipe_resource(buffer)->data; /* TODO: copy only the actually used constants? */ @@ -693,10 +692,10 @@ lp_setup_destroy( struct lp_setup_context *setup ) reset_context( setup ); for (i = 0; i < Elements(setup->fs.current_tex); i++) { - pipe_texture_reference(&setup->fs.current_tex[i], NULL); + pipe_resource_reference(&setup->fs.current_tex[i], NULL); } - pipe_buffer_reference(&setup->constants.current, NULL); + pipe_resource_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ while (1) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index dbfc1bf8d4c..e10d37d8d04 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -52,9 +52,8 @@ struct lp_shader_input { unsigned src_index; /* where to find values in incoming vertices */ }; -struct pipe_texture; +struct pipe_resource; struct pipe_surface; -struct pipe_buffer; struct pipe_blend_color; struct pipe_screen; struct pipe_framebuffer_state; @@ -105,7 +104,7 @@ lp_setup_set_fs_functions( struct lp_setup_context *setup, void lp_setup_set_fs_constants(struct lp_setup_context *setup, - struct pipe_buffer *buffer); + struct pipe_resource *buffer); void @@ -130,8 +129,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct pipe_sampler_view **views); unsigned -lp_setup_is_texture_referenced( const struct lp_setup_context *setup, - const struct pipe_texture *texture ); +lp_setup_is_resource_referenced( const struct lp_setup_context *setup, + const struct pipe_resource *texture ); void lp_setup_set_flatshade_first( struct lp_setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index ca0dafab627..ed21ec0f758 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -111,12 +111,12 @@ struct lp_setup_context const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ - struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS]; + struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS]; } fs; /** fragment shader constants */ struct { - struct pipe_buffer *current; + struct pipe_resource *current; unsigned stored_size; const void *stored_data; } constants; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 74ebf90d580..d89c28a2af2 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -170,7 +170,7 @@ void llvmpipe_set_clip_state( struct pipe_context *, void llvmpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, - struct pipe_buffer *buf); + struct pipe_resource *buf); void *llvmpipe_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -204,7 +204,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *, struct pipe_sampler_view * llvmpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ); void @@ -227,12 +227,12 @@ void llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); void llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); void llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 7bbf348e0b8..c57b4a4258e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -85,7 +85,6 @@ #include "gallivm/lp_bld_swizzle.h" #include "gallivm/lp_bld_flow.h" #include "gallivm/lp_bld_debug.h" -#include "lp_buffer.h" #include "lp_context.h" #include "lp_debug.h" #include "lp_perf.h" @@ -1044,11 +1043,11 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *constants) + struct pipe_resource *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - unsigned size = constants ? constants->size : 0; - const void *data = constants ? llvmpipe_buffer(constants)->data : NULL; + unsigned size = constants ? constants->width0 : 0; + const void *data = constants ? llvmpipe_resource(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -1059,7 +1058,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, draw_flush(llvmpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&llvmpipe->constants[shader], constants); + pipe_resource_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 2645441b58c..3552ff50ce1 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -165,7 +165,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe, struct pipe_sampler_view * llvmpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -174,7 +174,7 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -186,7 +186,7 @@ void llvmpipe_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 8137f29af52..972c7ae7c30 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -37,11 +37,13 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_transfer.h" #include "lp_context.h" #include "lp_screen.h" #include "lp_flush.h" #include "lp_texture.h" +#include "lp_setup.h" #include "lp_tile_size.h" #include "state_tracker/sw_winsys.h" @@ -51,10 +53,10 @@ * Simple, maximally packed layout. */ static boolean -llvmpipe_texture_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) +llvmpipe_resource_layout(struct llvmpipe_screen *screen, + struct llvmpipe_resource *lpt) { - struct pipe_texture *pt = &lpt->base; + struct pipe_resource *pt = &lpt->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; @@ -92,7 +94,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) + struct llvmpipe_resource *lpt) { struct sw_winsys *winsys = screen->winsys; @@ -103,7 +105,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, unsigned height = align(lpt->base.height0, TILE_SIZE); lpt->dt = winsys->displaytarget_create(winsys, - lpt->base.tex_usage, + lpt->base.bind, lpt->base.format, width, height, 16, @@ -113,12 +115,12 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, } -static struct pipe_texture * -llvmpipe_texture_create(struct pipe_screen *_screen, - const struct pipe_texture *templat) +static struct pipe_resource * +llvmpipe_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); - struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource); if (!lpt) return NULL; @@ -126,17 +128,17 @@ llvmpipe_texture_create(struct pipe_screen *_screen, pipe_reference_init(&lpt->base.reference, 1); lpt->base.screen = &screen->base; - if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if (lpt->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if (!llvmpipe_displaytarget_layout(screen, lpt)) goto fail; } else { - if (!llvmpipe_texture_layout(screen, lpt)) + if (!llvmpipe_resource_layout(screen, lpt)) goto fail; } - + return &lpt->base; fail: @@ -146,17 +148,18 @@ llvmpipe_texture_create(struct pipe_screen *_screen, static void -llvmpipe_texture_destroy(struct pipe_texture *pt) +llvmpipe_resource_destroy(struct pipe_screen *pscreen, + struct pipe_resource *pt) { - struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen); - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); if (lpt->dt) { /* display target */ struct sw_winsys *winsys = screen->winsys; winsys->displaytarget_destroy(winsys, lpt->dt); } - else { + else if (!lpt->userBuffer) { /* regular texture */ align_free(lpt->data); } @@ -169,19 +172,19 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) * Map a texture. Without any synchronization. */ void * -llvmpipe_texture_map(struct pipe_texture *texture, - unsigned face, - unsigned level, - unsigned zslice) +llvmpipe_resource_map(struct pipe_resource *texture, + unsigned usage, + unsigned face, + unsigned level, + unsigned zslice) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(texture); uint8_t *map; if (lpt->dt) { /* display target */ struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen); struct sw_winsys *winsys = screen->winsys; - const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE; assert(face == 0); assert(level == 0); @@ -204,7 +207,7 @@ llvmpipe_texture_map(struct pipe_texture *texture, /* XXX shouldn't that rather be tex_height = align(u_minify(texture->height0, level), 2) - to account for alignment done in llvmpipe_texture_layout ? + to account for alignment done in llvmpipe_resource_layout ? */ if (texture->target == PIPE_TEXTURE_CUBE) { unsigned tex_height = u_minify(texture->height0, level); @@ -230,12 +233,12 @@ llvmpipe_texture_map(struct pipe_texture *texture, * Unmap a texture. Without any synchronization. */ void -llvmpipe_texture_unmap(struct pipe_texture *texture, +llvmpipe_resource_unmap(struct pipe_resource *texture, unsigned face, unsigned level, unsigned zslice) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(texture); if (lpt->dt) { /* display target */ @@ -251,13 +254,13 @@ llvmpipe_texture_unmap(struct pipe_texture *texture, } -static struct pipe_texture * -llvmpipe_texture_from_handle(struct pipe_screen *screen, - const struct pipe_texture *template, - struct winsys_handle *whandle) +static struct pipe_resource * +llvmpipe_resource_from_handle(struct pipe_screen *screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) { struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; - struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource); if (!lpt) return NULL; @@ -281,12 +284,12 @@ llvmpipe_texture_from_handle(struct pipe_screen *screen, static boolean -llvmpipe_texture_get_handle(struct pipe_screen *screen, - struct pipe_texture *pt, +llvmpipe_resource_get_handle(struct pipe_screen *screen, + struct pipe_resource *pt, struct winsys_handle *whandle) { struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); assert(lpt->dt); if (!lpt->dt) @@ -298,11 +301,10 @@ llvmpipe_texture_get_handle(struct pipe_screen *screen, static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage) { - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); struct pipe_surface *ps; assert(level <= pt->last_level); @@ -310,32 +312,12 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); ps->usage = usage; - /* Because we are llvmpipe, anything that the state tracker - * thought was going to be done with the GPU will actually get - * done with the CPU. Let's adjust the flags to take that into - * account. - */ - if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - /* GPU_WRITE means "render" and that can involve reads (blending) */ - ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; - } - - if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) - ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; - - if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. */ - lpt->timestamp++; - llvmpipe_screen(screen)->timestamp++; - } - ps->face = face; ps->level = level; ps->zslice = zslice; @@ -352,37 +334,31 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf) * where it would happen. For llvmpipe, nothing to do. */ assert(surf->texture); - pipe_texture_reference(&surf->texture, NULL); + pipe_resource_reference(&surf->texture, NULL); FREE(surf); } static struct pipe_transfer * -llvmpipe_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +llvmpipe_get_transfer(struct pipe_context *pipe, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { - struct llvmpipe_texture *lptex = llvmpipe_texture(texture); + struct llvmpipe_resource *lptex = llvmpipe_resource(resource); struct llvmpipe_transfer *lpt; - assert(texture); - assert(level <= texture->last_level); + assert(resource); + assert(sr.level <= resource->last_level); lpt = CALLOC_STRUCT(llvmpipe_transfer); if (lpt) { struct pipe_transfer *pt = &lpt->base; - pipe_texture_reference(&pt->texture, texture); - pt->x = x; - pt->y = y; - pt->width = align(w, TILE_SIZE); - pt->height = align(h, TILE_SIZE); - pt->stride = lptex->stride[level]; + pipe_resource_reference(&pt->resource, resource); + pt->box = *box; + pt->stride = lptex->stride[sr.level]; pt->usage = usage; - pt->face = face; - pt->level = level; - pt->zslice = zslice; return pt; } @@ -391,15 +367,15 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe, static void -llvmpipe_tex_transfer_destroy(struct pipe_context *pipe, +llvmpipe_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { /* Effectively do the texture_update work here - if texture images * needed post-processing to put them into hardware layout, this is * where it would happen. For llvmpipe, nothing to do. */ - assert (transfer->texture); - pipe_texture_reference(&transfer->texture, NULL); + assert (transfer->resource); + pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } @@ -410,11 +386,11 @@ llvmpipe_transfer_map( struct pipe_context *pipe, { struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); ubyte *map; - struct llvmpipe_texture *lpt; + struct llvmpipe_resource *lpt; enum pipe_format format; - assert(transfer->texture); - lpt = llvmpipe_texture(transfer->texture); + assert(transfer->resource); + lpt = llvmpipe_resource(transfer->resource); format = lpt->base.format; /* @@ -422,14 +398,19 @@ llvmpipe_transfer_map( struct pipe_context *pipe, * context if necessary. */ llvmpipe_flush_texture(pipe, - transfer->texture, transfer->face, transfer->level, + transfer->resource, + transfer->sr.face, + transfer->sr.level, 0, /* flush_flags */ !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */ TRUE, /* cpu_access */ FALSE); /* do_not_flush */ - map = llvmpipe_texture_map(transfer->texture, - transfer->face, transfer->level, transfer->zslice); + map = llvmpipe_resource_map(transfer->resource, + transfer->usage, + transfer->sr.face, + transfer->sr.level, + transfer->box.z); /* May want to different things here depending on read/write nature * of the map: @@ -441,8 +422,8 @@ llvmpipe_transfer_map( struct pipe_context *pipe, } map += - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); return map; } @@ -452,20 +433,68 @@ static void llvmpipe_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - assert(transfer->texture); + assert(transfer->resource); + + llvmpipe_resource_unmap(transfer->resource, + transfer->sr.face, + transfer->sr.level, + transfer->box.z); +} + +static unsigned int +llvmpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *presource, + unsigned face, unsigned level) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + + if (presource->target == PIPE_BUFFER) + return PIPE_UNREFERENCED; + + return lp_setup_is_resource_referenced(llvmpipe->setup, presource); +} + + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_resource * +llvmpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags) +{ + struct llvmpipe_resource *buffer; + + buffer = CALLOC_STRUCT(llvmpipe_resource); + if(!buffer) + return NULL; - llvmpipe_texture_unmap(transfer->texture, - transfer->face, transfer->level, transfer->zslice); + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buffer->base.bind = bind_flags; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.flags = 0; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; } void -llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) +llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) { - screen->texture_create = llvmpipe_texture_create; - screen->texture_destroy = llvmpipe_texture_destroy; - screen->texture_from_handle = llvmpipe_texture_from_handle; - screen->texture_get_handle = llvmpipe_texture_get_handle; + screen->resource_create = llvmpipe_resource_create; + screen->resource_destroy = llvmpipe_resource_destroy; + screen->resource_from_handle = llvmpipe_resource_from_handle; + screen->resource_get_handle = llvmpipe_resource_get_handle; + screen->user_buffer_create = llvmpipe_user_buffer_create; screen->get_tex_surface = llvmpipe_get_tex_surface; screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; @@ -473,10 +502,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) void -llvmpipe_init_context_texture_funcs(struct pipe_context *pipe) +llvmpipe_init_context_resource_funcs(struct pipe_context *pipe) { - pipe->get_tex_transfer = llvmpipe_get_tex_transfer; - pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy; + pipe->get_transfer = llvmpipe_get_transfer; + pipe->transfer_destroy = llvmpipe_transfer_destroy; pipe->transfer_map = llvmpipe_transfer_map; pipe->transfer_unmap = llvmpipe_transfer_unmap; + pipe->is_resource_referenced = llvmpipe_is_resource_referenced; + + pipe->transfer_flush_region = u_default_transfer_flush_region; + pipe->transfer_inline_write = u_default_transfer_inline_write; } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index 6b78750f1ae..02268678409 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -44,15 +44,15 @@ struct llvmpipe_context; struct sw_displaytarget; -struct llvmpipe_texture +struct llvmpipe_resource { - struct pipe_texture base; + struct pipe_resource base; unsigned long level_offset[LP_MAX_TEXTURE_2D_LEVELS]; unsigned stride[LP_MAX_TEXTURE_2D_LEVELS]; /** - * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * Display target, for textures with the PIPE_BIND_DISPLAY_TARGET * usage. */ struct sw_displaytarget *dt; @@ -62,6 +62,7 @@ struct llvmpipe_texture */ void *data; + boolean userBuffer; /** Is this a user-space buffer? */ unsigned timestamp; }; @@ -75,17 +76,17 @@ struct llvmpipe_transfer /** cast wrappers */ -static INLINE struct llvmpipe_texture * -llvmpipe_texture(struct pipe_texture *pt) +static INLINE struct llvmpipe_resource * +llvmpipe_resource(struct pipe_resource *pt) { - return (struct llvmpipe_texture *) pt; + return (struct llvmpipe_resource *) pt; } -static INLINE const struct llvmpipe_texture * -llvmpipe_texture_const(const struct pipe_texture *pt) +static INLINE const struct llvmpipe_resource * +llvmpipe_resource_const(const struct pipe_resource *pt) { - return (const struct llvmpipe_texture *) pt; + return (const struct llvmpipe_resource *) pt; } @@ -96,32 +97,31 @@ llvmpipe_transfer(struct pipe_transfer *pt) } +void llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen); +void llvmpipe_init_context_resource_funcs(struct pipe_context *pipe); + static INLINE unsigned -llvmpipe_texture_stride(struct pipe_texture *texture, +llvmpipe_resource_stride(struct pipe_resource *texture, unsigned level) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(texture); assert(level < LP_MAX_TEXTURE_2D_LEVELS); return lpt->stride[level]; } void * -llvmpipe_texture_map(struct pipe_texture *texture, - unsigned face, - unsigned level, - unsigned zslice); +llvmpipe_resource_map(struct pipe_resource *texture, + unsigned usage, + unsigned face, + unsigned level, + unsigned zslice); void -llvmpipe_texture_unmap(struct pipe_texture *texture, +llvmpipe_resource_unmap(struct pipe_resource *texture, unsigned face, unsigned level, unsigned zslice); -extern void -llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); - -extern void -llvmpipe_init_context_texture_funcs(struct pipe_context *pipe); #endif /* LP_TEXTURE_H */ diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index 0cb66041d50..db591b756c4 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -3,7 +3,9 @@ include $(TOP)/configs/current LIBNAME = nouveau -C_SOURCES = nouveau_screen.c \ - nouveau_context.c +LIBRARY_INCLUDES = \ + -I$(TOP)/src/gallium/drivers/nouveau/include + +C_SOURCES = nouveau_screen.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_context.c b/src/gallium/drivers/nouveau/nouveau_context.c deleted file mode 100644 index 15174983e7f..00000000000 --- a/src/gallium/drivers/nouveau/nouveau_context.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "pipe/p_defines.h" -#include "pipe/p_context.h" - -#include "nouveau/nouveau_screen.h" -#include "nouveau/nouveau_context.h" - -#include "nouveau/nouveau_bo.h" - -static unsigned int -nouveau_reference_flags(struct nouveau_bo *bo) -{ - uint32_t bo_flags; - int flags = 0; - - bo_flags = nouveau_bo_pending(bo); - if (bo_flags & NOUVEAU_BO_RD) - flags |= PIPE_REFERENCED_FOR_READ; - if (bo_flags & NOUVEAU_BO_WR) - flags |= PIPE_REFERENCED_FOR_WRITE; - - return flags; -} - -unsigned int -nouveau_is_texture_referenced(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level) -{ - struct nouveau_miptree *mt = nouveau_miptree(pt); - - return nouveau_reference_flags(mt->bo); -} - -unsigned int -nouveau_is_buffer_referenced(struct pipe_context *pipe, struct pipe_buffer *pb) -{ - struct nouveau_bo *bo = nouveau_bo(pb); - - return nouveau_reference_flags(bo); -} - diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h deleted file mode 100644 index 6a28d40da7b..00000000000 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_H__ -#define __NOUVEAU_CONTEXT_H__ - -unsigned int -nouveau_is_texture_referenced(struct pipe_context *, struct pipe_texture *, - unsigned face, unsigned level); - -unsigned int -nouveau_is_buffer_referenced(struct pipe_context *, struct pipe_buffer *); - -#endif diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index b1ad686022a..a0bbc3e38d7 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -15,6 +15,7 @@ /* XXX this should go away */ #include "state_tracker/drm_api.h" +#include "util/u_simple_screen.h" static const char * nouveau_screen_get_name(struct pipe_screen *pscreen) @@ -32,56 +33,42 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen) return "nouveau"; } -static struct pipe_buffer * -nouveau_screen_bo_skel(struct pipe_screen *pscreen, struct nouveau_bo *bo, - unsigned alignment, unsigned usage, unsigned size) -{ - struct pipe_buffer *pb; - - pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *)); - if (!pb) { - nouveau_bo_ref(NULL, &bo); - return NULL; - } - pipe_reference_init(&pb->reference, 1); - pb->screen = pscreen; - pb->alignment = alignment; - pb->usage = usage; - pb->size = size; - *(struct nouveau_bo **)(pb + 1) = bo; - return pb; -} -static struct pipe_buffer * +struct nouveau_bo * nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, - unsigned usage, unsigned size) + unsigned usage, unsigned bind, unsigned size) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nouveau_bo *bo = NULL; uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0; int ret; - if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER) - flags |= NOUVEAU_BO_GART; - else - if (usage & PIPE_BUFFER_USAGE_VERTEX) { + if (bind & PIPE_BIND_VERTEX_BUFFER) { if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF)) flags |= NOUVEAU_BO_GART; } else - if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (usage & PIPE_BIND_INDEX_BUFFER) { if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF)) flags |= NOUVEAU_BO_GART; } - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + if (bind & (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DEPTH_STENCIL | + PIPE_BIND_BLIT_SOURCE | + PIPE_BIND_BLIT_DESTINATION | + PIPE_BIND_SCANOUT | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SAMPLER_VIEW)) + { + /* TODO: this may be incorrect or suboptimal */ + if (!(bind & PIPE_BIND_SCANOUT)) flags |= NOUVEAU_BO_GART; - if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE)) + if (usage != PIPE_USAGE_DYNAMIC) flags |= NOUVEAU_BO_VRAM; if (dev->chipset == 0x50 || dev->chipset >= 0x80) { - if (usage & NOUVEAU_BUFFER_USAGE_ZETA) + if (bind & PIPE_BIND_DEPTH_STENCIL) tile_flags = 0x2800; else tile_flags = 0x7000; @@ -93,10 +80,10 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, if (ret) return NULL; - return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size); + return bo; } -static struct pipe_buffer * +struct nouveau_bo * nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; @@ -107,47 +94,17 @@ nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes) if (ret) return NULL; - return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes); + return bo; } -static inline uint32_t -nouveau_screen_map_flags(unsigned pipe) +void * +nouveau_screen_bo_map(struct pipe_screen *pscreen, + struct nouveau_bo *bo, + unsigned map_flags) { - uint32_t flags = 0; - - if (pipe & PIPE_BUFFER_USAGE_CPU_READ) - flags |= NOUVEAU_BO_RD; - if (pipe & PIPE_BUFFER_USAGE_CPU_WRITE) - flags |= NOUVEAU_BO_WR; - if (pipe & PIPE_BUFFER_USAGE_DISCARD) - flags |= NOUVEAU_BO_INVAL; - if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK) - flags |= NOUVEAU_BO_NOWAIT; - else - if (pipe & PIPE_BUFFER_USAGE_UNSYNCHRONIZED) - flags |= NOUVEAU_BO_NOSYNC; - - return flags; -} - -static void * -nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb, - unsigned usage) -{ - struct nouveau_bo *bo = nouveau_bo(pb); - struct nouveau_screen *nscreen = nouveau_screen(pscreen); int ret; - if (nscreen->pre_pipebuffer_map_callback) { - ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage); - if (ret) { - debug_printf("pre_pipebuffer_map_callback failed %d\n", - ret); - return NULL; - } - } - - ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage)); + ret = nouveau_bo_map(bo, map_flags); if (ret) { debug_printf("map failed: %d\n", ret); return NULL; @@ -156,24 +113,12 @@ nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb, return bo->map; } -static void * -nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb, - unsigned offset, unsigned length, unsigned usage) +void * +nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, + unsigned offset, unsigned length, unsigned flags) { - struct nouveau_bo *bo = nouveau_bo(pb); - struct nouveau_screen *nscreen = nouveau_screen(pscreen); - uint32_t flags = nouveau_screen_map_flags(usage); int ret; - if (nscreen->pre_pipebuffer_map_callback) { - ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage); - if (ret) { - debug_printf("pre_pipebuffer_map_callback failed %d\n", - ret); - return NULL; - } - } - ret = nouveau_bo_map_range(bo, offset, length, flags); if (ret) { nouveau_bo_unmap(bo); @@ -185,30 +130,23 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb, return (char *)bo->map - offset; /* why gallium? why? */ } -static void -nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb, - unsigned offset, unsigned length) +void +nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, + unsigned offset, unsigned length) { - struct nouveau_bo *bo = nouveau_bo(pb); - nouveau_bo_map_flush(bo, offset, length); } -static void -nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb) +void +nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo) { - struct nouveau_bo *bo = nouveau_bo(pb); - nouveau_bo_unmap(bo); } -static void -nouveau_screen_bo_del(struct pipe_buffer *pb) +void +nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo) { - struct nouveau_bo *bo = nouveau_bo(pb); - nouveau_bo_ref(NULL, &bo); - FREE(pb); } static void @@ -236,71 +174,65 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, } -/* - * Both texture_{from|get}_handle use drm api defines directly which they - * shouldn't do. The problem is that from|get are pipe functions and as - * such they should be defined in the pipe level. If nouveau had a propper - * winsys interface we would have added from|get to that interface using - * the winsys_handle struct as done with other drivers. However this code - * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So - * we need to translate the handle into something they understand. - */ -static struct pipe_texture * -nouveau_screen_texture_from_handle(struct pipe_screen *pscreen, - const struct pipe_texture *templ, - struct winsys_handle *whandle) +struct nouveau_bo * +nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, + struct winsys_handle *whandle, + unsigned *out_stride) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; - struct pipe_texture *pt; - struct pipe_buffer *pb; + struct nouveau_bo *bo = 0; int ret; - - pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*)); - if (!pb) - return NULL; - - ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1)); + + ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo); if (ret) { debug_printf("%s: ref name 0x%08x failed with %d\n", __func__, whandle->handle, ret); - FREE(pb); return NULL; } - pipe_reference_init(&pb->reference, 1); - pb->screen = pscreen; - pb->alignment = 0; - pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE | - PIPE_BUFFER_USAGE_CPU_READ_WRITE; - pb->size = nouveau_bo(pb)->size; - pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ, - &whandle->stride, pb); - pipe_buffer_reference(&pb, NULL); - return pt; + *out_stride = whandle->stride; + return bo; } -static boolean -nouveau_screen_texture_get_handle(struct pipe_screen *pscreen, - struct pipe_texture *pt, - struct winsys_handle *whandle) -{ - struct nouveau_miptree *mt = nouveau_miptree(pt); - - if (!mt || !mt->bo) - return false; - whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0); +boolean +nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, + struct nouveau_bo *bo, + unsigned stride, + struct winsys_handle *whandle) +{ + whandle->stride = stride; if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { - return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0; + return nouveau_bo_handle_get(bo, &whandle->handle) == 0; } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { - whandle->handle = mt->bo->handle; + whandle->handle = bo->handle; return TRUE; } else { return FALSE; } } + +unsigned int +nouveau_reference_flags(struct nouveau_bo *bo) +{ + uint32_t bo_flags; + int flags = 0; + + bo_flags = nouveau_bo_pending(bo); + if (bo_flags & NOUVEAU_BO_RD) + flags |= PIPE_REFERENCED_FOR_READ; + if (bo_flags & NOUVEAU_BO_WR) + flags |= PIPE_REFERENCED_FOR_WRITE; + + return flags; +} + + + + + int nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) { @@ -316,21 +248,10 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) pscreen->get_name = nouveau_screen_get_name; pscreen->get_vendor = nouveau_screen_get_vendor; - pscreen->buffer_create = nouveau_screen_bo_new; - pscreen->user_buffer_create = nouveau_screen_bo_user; - pscreen->buffer_map = nouveau_screen_bo_map; - pscreen->buffer_map_range = nouveau_screen_bo_map_range; - pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush; - pscreen->buffer_unmap = nouveau_screen_bo_unmap; - pscreen->buffer_destroy = nouveau_screen_bo_del; - pscreen->fence_reference = nouveau_screen_fence_ref; pscreen->fence_signalled = nouveau_screen_fence_signalled; pscreen->fence_finish = nouveau_screen_fence_finish; - pscreen->texture_from_handle = nouveau_screen_texture_from_handle; - pscreen->texture_get_handle = nouveau_screen_texture_get_handle; - return 0; } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index f4a7a2bc234..c0ec6e48952 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -5,21 +5,6 @@ struct nouveau_screen { struct pipe_screen base; struct nouveau_device *device; struct nouveau_channel *channel; - - /** - * Create a new texture object, using the given template info, but on top of - * existing memory. - * - * It is assumed that the buffer data is layed out according to the expected - * by the hardware. NULL will be returned if any inconsistency is found. - */ - struct pipe_texture * (*texture_blanket)(struct pipe_screen *, - const struct pipe_texture *templat, - const unsigned *stride, - struct pipe_buffer *buffer); - - int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen, - struct pipe_buffer *pb, unsigned usage); }; static inline struct nouveau_screen * @@ -28,24 +13,51 @@ nouveau_screen(struct pipe_screen *pscreen) return (struct nouveau_screen *)pscreen; } -static inline struct nouveau_bo * -nouveau_bo(struct pipe_buffer *pb) -{ - return pb ? *(struct nouveau_bo **)(pb + 1) : NULL; -} + + +/* Not really sure if this is needed, or whether the individual + * drivers are happy to talk to the bo functions themselves. In a way + * this is what we'd expect from a regular winsys interface. + */ +struct nouveau_bo * +nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, + unsigned usage, unsigned bind, unsigned size); +struct nouveau_bo * +nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes); +void * +nouveau_screen_bo_map(struct pipe_screen *pscreen, + struct nouveau_bo *pb, + unsigned usage); +void * +nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, + unsigned offset, unsigned length, unsigned usage); +void +nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, + unsigned offset, unsigned length); +void +nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo); +void +nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo); + +boolean +nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, + struct nouveau_bo *bo, + unsigned stride, + struct winsys_handle *whandle); +struct nouveau_bo * +nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, + struct winsys_handle *whandle, + unsigned *out_stride); + +unsigned int +nouveau_reference_flags(struct nouveau_bo *bo); + + int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *); void nouveau_screen_fini(struct nouveau_screen *); -struct nouveau_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; -}; -static inline struct nouveau_miptree * -nouveau_miptree(struct pipe_texture *pt) -{ - return (struct nouveau_miptree *)pt; -} + #endif diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h index ab7761a31da..ed6e643785d 100644 --- a/src/gallium/drivers/nouveau/nouveau_util.h +++ b/src/gallium/drivers/nouveau/nouveau_util.h @@ -98,9 +98,9 @@ struct u_split_prim { unsigned p_start; unsigned p_end; - int repeat_first:1; - int close_first:1; - int edgeflag_off:1; + uint repeat_first:1; + uint close_first:1; + uint edgeflag_off:1; }; static inline void diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index bed014b9ce0..b144bef5e61 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -2,7 +2,6 @@ #define NOUVEAU_WINSYS_H #include <stdint.h> -#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "nouveau/nouveau_bo.h" @@ -17,14 +16,25 @@ #define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000) #define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) -#define NOUVEAU_TEXTURE_USAGE_LINEAR (1 << 16) - -#define NOUVEAU_BUFFER_USAGE_TEXTURE (1 << 16) -#define NOUVEAU_BUFFER_USAGE_ZETA (1 << 17) -#define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18) - -/* use along with GPU_WRITE for 2D-only writes */ -#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19) +static inline uint32_t +nouveau_screen_transfer_flags(unsigned pipe) +{ + uint32_t flags = 0; + + if (pipe & PIPE_TRANSFER_READ) + flags |= NOUVEAU_BO_RD; + if (pipe & PIPE_TRANSFER_WRITE) + flags |= NOUVEAU_BO_WR; + if (pipe & PIPE_TRANSFER_DISCARD) + flags |= NOUVEAU_BO_INVAL; + if (pipe & PIPE_TRANSFER_DONTBLOCK) + flags |= NOUVEAU_BO_NOWAIT; + else + if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED) + flags |= NOUVEAU_BO_NOSYNC; + + return flags; +} extern struct pipe_screen * nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *); diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index 5d622e1c13c..e31e6f8662a 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -4,12 +4,14 @@ include $(TOP)/configs/current LIBNAME = nv50 C_SOURCES = \ + nv50_buffer.c \ nv50_clear.c \ nv50_context.c \ nv50_draw.c \ nv50_miptree.c \ nv50_query.c \ nv50_program.c \ + nv50_resource.c \ nv50_screen.c \ nv50_state.c \ nv50_state_validate.c \ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c new file mode 100644 index 00000000000..094e05e9bbf --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_buffer.c @@ -0,0 +1,150 @@ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_winsys.h" +#include "nv50_resource.h" + + + +static void nv50_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct nv50_resource *buffer = nv50_resource(presource); + + nouveau_screen_bo_release(pscreen, buffer->bo); + FREE(buffer); +} + + + + +/* Utility functions for transfer create/destroy are hooked in and + * just record the arguments to those functions. + */ +static void * +nv50_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct nv50_resource *buffer = nv50_resource(transfer->resource); + uint8_t *map; + + map = nouveau_screen_bo_map_range( pipe->screen, + buffer->bo, + transfer->box.x, + transfer->box.width, + nouveau_screen_transfer_flags(transfer->usage) ); + if (map == NULL) + return NULL; + + return map + transfer->box.x; +} + + + +static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct nv50_resource *buffer = nv50_resource(transfer->resource); + + nouveau_screen_bo_map_flush_range(pipe->screen, + buffer->bo, + transfer->box.x + box->x, + box->width); +} + +static void nv50_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct nv50_resource *buffer = nv50_resource(transfer->resource); + + nouveau_screen_bo_unmap(pipe->screen, buffer->bo); +} + + + + +struct u_resource_vtbl nv50_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + nv50_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + nv50_buffer_transfer_map, /* transfer_map */ + nv50_buffer_transfer_flush_region, /* transfer_flush_region */ + nv50_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + + +struct pipe_resource * +nv50_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *template) +{ + struct nv50_resource *buffer; + + buffer = CALLOC_STRUCT(nv50_resource); + if (!buffer) + return NULL; + + buffer->base = *template; + buffer->vtbl = &nv50_buffer_vtbl; + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = pscreen; + + buffer->bo = nouveau_screen_bo_new(pscreen, + 16, + buffer->base._usage, + buffer->base.bind, + buffer->base.width0); + + if (buffer->bo == NULL) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + + +struct pipe_resource * +nv50_user_buffer_create(struct pipe_screen *pscreen, + void *ptr, + unsigned bytes, + unsigned bind) +{ + struct nv50_resource *buffer; + + buffer = CALLOC_STRUCT(nv50_resource); + if (!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->vtbl = &nv50_buffer_vtbl; + buffer->base.screen = pscreen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.bind = bind; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + + buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes); + if (!buffer->bo) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index aa14e17872d..f543b3c504d 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -25,6 +25,7 @@ #include "nv50_context.h" #include "nv50_screen.h" +#include "nv50_resource.h" static void nv50_flush(struct pipe_context *pipe, unsigned flags, @@ -89,15 +90,12 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50->pipe.flush = nv50_flush; - nv50->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - screen->base.channel->user_private = nv50; nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_query_functions(nv50); - nv50_init_transfer_functions(nv50); + nv50_init_resource_functions(&nv50->pipe); nv50->draw = draw_create(); assert(nv50->draw); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index bc7831d9aca..8bf465378e3 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -16,7 +16,6 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" #include "nouveau/nouveau_stateobj.h" -#include "nouveau/nouveau_context.h" #include "nv50_screen.h" #include "nv50_program.h" @@ -101,27 +100,6 @@ get_tile_depth(uint32_t tile_mode) return 1 << (tile_mode >> 4); } -struct nv50_miptree_level { - int *image_offset; - unsigned pitch; - unsigned tile_mode; -}; - -#define NV50_MAX_TEXTURE_LEVELS 16 - -struct nv50_miptree { - struct nouveau_miptree base; - - struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; - int image_nr; - int total_size; -}; - -static INLINE struct nv50_miptree * -nv50_miptree(struct pipe_texture *pt) -{ - return (struct nv50_miptree *)pt; -} struct nv50_surface { struct pipe_surface base; @@ -165,7 +143,7 @@ struct nv50_context { struct nv50_program *vertprog; struct nv50_program *fragprog; struct nv50_program *geomprog; - struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; struct nv50_vtxelt_stateobj *vtxelt; @@ -206,12 +184,12 @@ extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode, unsigned startInstance, unsigned instanceCount); extern void nv50_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); extern void nv50_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count, @@ -222,7 +200,7 @@ extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50); /* nv50_push.c */ extern void -nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *, +nv50_push_elements_instanced(struct pipe_context *, struct pipe_resource *, unsigned idxsize, unsigned mode, unsigned start, unsigned count, unsigned i_start, unsigned i_count); @@ -258,13 +236,6 @@ extern boolean nv50_tex_construct(struct nv50_sampler_view *view); extern void nv50_tex_relocs(struct nv50_context *); extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *); -/* nv50_transfer.c */ -extern void -nv50_upload_sifc(struct nv50_context *nv50, - struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc, - unsigned dst_format, int dst_w, int dst_h, int dst_pitch, - void *src, unsigned src_format, int src_pitch, - int x, int y, int w, int h, int cpp); /* nv50_context.c */ struct pipe_context * diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 85b0aef20cc..6484f924d0b 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -26,6 +26,8 @@ #include "util/u_format.h" #include "nv50_context.h" +#include "nv50_resource.h" +#include "nv50_transfer.h" /* The restrictions in tile mode selection probably aren't necessary. */ static INLINE uint32_t @@ -70,12 +72,66 @@ get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h) return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d; } -static struct pipe_texture * -nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) + + + +static void +nv50_miptree_destroy(struct pipe_screen *pscreen, + struct pipe_resource *pt) +{ + struct nv50_miptree *mt = nv50_miptree(pt); + unsigned l; + + for (l = 0; l <= pt->last_level; ++l) + FREE(mt->level[l].image_offset); + + nouveau_screen_bo_release(pscreen, mt->base.bo); + FREE(mt); +} + +static boolean +nv50_miptree_get_handle(struct pipe_screen *pscreen, + struct pipe_resource *pt, + struct winsys_handle *whandle) +{ + struct nv50_miptree *mt = nv50_miptree(pt); + unsigned stride; + + + if (!mt || !mt->base.bo) + return FALSE; + + stride = util_format_get_stride(mt->base.base.format, + mt->base.base.width0); + + return nouveau_screen_bo_get_handle(pscreen, + mt->base.bo, + stride, + whandle); +} + + +struct u_resource_vtbl nv50_miptree_vtbl = +{ + nv50_miptree_get_handle, /* get_handle */ + nv50_miptree_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nv50_miptree_transfer_new, /* get_transfer */ + nv50_miptree_transfer_del, /* transfer_destroy */ + nv50_miptree_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + nv50_miptree_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + +struct pipe_resource * +nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *tmp) { struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); - struct pipe_texture *pt = &mt->base.base; + struct pipe_resource *pt = &mt->base.base; unsigned width = tmp->width0, height = tmp->height0; unsigned depth = tmp->depth0, image_alignment; uint32_t tile_flags; @@ -104,7 +160,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) tile_flags = 0x7400; break; default: - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) && + if ((pt->bind & PIPE_BIND_SCANOUT) && util_format_get_blocksizebits(pt->format) == 32) tile_flags = 0x7a00; else @@ -165,49 +221,53 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) return pt; } -static struct pipe_texture * -nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) + +struct pipe_resource * +nv50_miptree_from_handle(struct pipe_screen *pscreen, + const struct pipe_resource *template, + struct winsys_handle *whandle) { - struct nouveau_bo *bo = nouveau_bo(pb); struct nv50_miptree *mt; + unsigned stride; /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) + if (template->target != PIPE_TEXTURE_2D || + template->last_level != 0 || + template->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv50_miptree); if (!mt) return NULL; - mt->base.base = *pt; + mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); + if (mt->base.bo == NULL) { + FREE(mt); + return NULL; + } + + + mt->base.base = *template; pipe_reference_init(&mt->base.base.reference, 1); mt->base.base.screen = pscreen; mt->image_nr = 1; - mt->level[0].pitch = *stride; + mt->level[0].pitch = stride; mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - mt->level[0].tile_mode = bo->tile_mode; + mt->level[0].tile_mode = mt->base.bo->tile_mode; - nouveau_bo_ref(bo, &mt->base.bo); + /* XXX: Need to adjust bo refcount?? + */ + /* nouveau_bo_ref(bo, &mt->base.bo); */ return &mt->base.base; } -static void -nv50_miptree_destroy(struct pipe_texture *pt) -{ - struct nv50_miptree *mt = nv50_miptree(pt); - unsigned l; - for (l = 0; l <= pt->last_level; ++l) - FREE(mt->level[l].image_offset); - nouveau_bo_ref(NULL, &mt->base.bo); - FREE(mt); -} +/* Surface functions + */ -static struct pipe_surface * -nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, +struct pipe_surface * +nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { @@ -222,7 +282,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); @@ -242,23 +302,11 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return ps; } -static void +void nv50_miptree_surface_del(struct pipe_surface *ps) { struct nv50_surface *s = nv50_surface(ps); - pipe_texture_reference(&ps->texture, NULL); + pipe_resource_reference(&ps->texture, NULL); FREE(s); } - -void -nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv50_miptree_create; - pscreen->texture_destroy = nv50_miptree_destroy; - pscreen->get_tex_surface = nv50_miptree_surface_new; - pscreen->tex_surface_destroy = nv50_miptree_surface_del; - - nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket; -} - diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2f61888ed99..11ca2a21178 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -30,6 +30,7 @@ #include "tgsi/tgsi_util.h" #include "nv50_context.h" +#include "nv50_transfer.h" #define NV50_SU_MAX_TEMP 127 #define NV50_SU_MAX_ADDR 4 @@ -4157,7 +4158,8 @@ nv50_program_upload_data(struct nv50_context *nv50, uint32_t *map, static void nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) { - struct pipe_screen *pscreen = nv50->pipe.screen; + struct pipe_context *pipe = &nv50->pipe; + struct pipe_transfer *transfer; if (!p->data[0] && p->immd_nr) { struct nouveau_resource *heap = nv50->screen->immd_heap[0]; @@ -4182,9 +4184,10 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) if (p->param_nr) { unsigned cb; - uint32_t *map = pipe_buffer_map(pscreen, + uint32_t *map = pipe_buffer_map(pipe, nv50->constbuf[p->type], - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &transfer); switch (p->type) { case PIPE_SHADER_GEOMETRY: cb = NV50_CB_PGP; break; case PIPE_SHADER_FRAGMENT: cb = NV50_CB_PFP; break; @@ -4195,7 +4198,8 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) } nv50_program_upload_data(nv50, map, 0, p->param_nr, cb); - pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]); + pipe_buffer_unmap(pipe, nv50->constbuf[p->type], + transfer); } } diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 96a1f32d304..6981e5b919b 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -5,6 +5,7 @@ #include "nouveau/nouveau_util.h" #include "nv50_context.h" +#include "nv50_resource.h" struct push_context { struct nv50_context *nv50; @@ -171,7 +172,7 @@ emit_verts(void *priv, unsigned start, unsigned count) void nv50_push_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *idxbuf, unsigned idxsize, + struct pipe_resource *idxbuf, unsigned idxsize, unsigned mode, unsigned start, unsigned count, unsigned i_start, unsigned i_count) { @@ -199,7 +200,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, for (i = 0; i < nv50->vtxelt->num_elements; i++) { struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo *bo = nouveau_bo(vb->buffer); + struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; unsigned size, nr_components, n; if (!(nv50->vbo_fifo & (1 << i))) @@ -260,7 +261,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, /* map index buffer, if present */ if (idxbuf) { - struct nouveau_bo *bo = nouveau_bo(idxbuf); + struct nouveau_bo *bo = nv50_resource(idxbuf)->bo; if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) { assert(bo->map); diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c new file mode 100644 index 00000000000..cfdb60418b5 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_resource.c @@ -0,0 +1,67 @@ + +#include "pipe/p_context.h" +#include "nv50_resource.h" +#include "nouveau/nouveau_screen.h" + + +/* This doesn't look quite right - this query is supposed to ask + * whether the particular context has references to the resource in + * any unflushed rendering command buffer, and hence requires a + * pipe->flush() for serializing some modification to that resource. + * + * This seems to be answering the question of whether the resource is + * currently on hardware. + */ +static unsigned int +nv50_resource_is_referenced(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned face, unsigned level) +{ + return nouveau_reference_flags(nv50_resource(resource)->bo); +} + +static struct pipe_resource * +nv50_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return nv50_buffer_create(screen, template); + else + return nv50_miptree_create(screen, template); +} + +static struct pipe_resource * +nv50_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return nv50_miptree_from_handle(screen, template, whandle); +} + +void +nv50_init_resource_functions(struct pipe_context *pcontext) +{ + pcontext->get_transfer = u_get_transfer_vtbl; + pcontext->transfer_map = u_transfer_map_vtbl; + pcontext->transfer_flush_region = u_transfer_flush_region_vtbl; + pcontext->transfer_unmap = u_transfer_unmap_vtbl; + pcontext->transfer_destroy = u_transfer_destroy_vtbl; + pcontext->transfer_inline_write = u_transfer_inline_write_vtbl; + pcontext->is_resource_referenced = nv50_resource_is_referenced; +} + +void +nv50_screen_init_resource_functions(struct pipe_screen *pscreen) +{ + pscreen->resource_create = nv50_resource_create; + pscreen->resource_from_handle = nv50_resource_from_handle; + pscreen->resource_get_handle = u_resource_get_handle_vtbl; + pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->user_buffer_create = nv50_user_buffer_create; + + pscreen->get_tex_surface = nv50_miptree_surface_new; + pscreen->tex_surface_destroy = nv50_miptree_surface_del; +} diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h new file mode 100644 index 00000000000..963a1100ce8 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -0,0 +1,90 @@ + +#ifndef NV50_RESOURCE_H +#define NV50_RESOURCE_H + +#include "util/u_transfer.h" + +struct pipe_resource; +struct nouveau_bo; + + +/* This gets further specialized into either buffer or texture + * structures. In the future we'll want to remove much of that + * distinction, but for now try to keep as close to the existing code + * as possible and use the vtbl struct to choose between the two + * underlying implementations. + */ +struct nv50_resource { + struct pipe_resource base; + struct u_resource_vtbl *vtbl; + struct nouveau_bo *bo; +}; + +struct nv50_miptree_level { + int *image_offset; + unsigned pitch; + unsigned tile_mode; +}; + +#define NV50_MAX_TEXTURE_LEVELS 16 + +struct nv50_miptree { + struct nv50_resource base; + + struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; + int image_nr; + int total_size; +}; + +static INLINE struct nv50_miptree * +nv50_miptree(struct pipe_resource *pt) +{ + return (struct nv50_miptree *)pt; +} + + +static INLINE +struct nv50_resource *nv50_resource(struct pipe_resource *resource) +{ + return (struct nv50_resource *)resource; +} + + +void +nv50_init_resource_functions(struct pipe_context *pcontext); + +void +nv50_screen_init_resource_functions(struct pipe_screen *pscreen); + +/* Internal functions + */ +struct pipe_resource * +nv50_miptree_create(struct pipe_screen *pscreen, + const struct pipe_resource *tmp); + +struct pipe_resource * +nv50_miptree_from_handle(struct pipe_screen *pscreen, + const struct pipe_resource *template, + struct winsys_handle *whandle); + +struct pipe_resource * +nv50_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *template); + +struct pipe_resource * +nv50_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + + +struct pipe_surface * +nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags); + +void +nv50_miptree_surface_del(struct pipe_surface *ps); + + +#endif diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 551e8935693..a0fe4c59132 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -24,6 +24,7 @@ #include "nv50_context.h" #include "nv50_screen.h" +#include "nv50_resource.h" #include "nouveau/nouveau_stateobj.h" @@ -33,7 +34,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_texture_target target, unsigned tex_usage, unsigned geom_flags) { - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: @@ -48,7 +49,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, break; } } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { switch (format) { case PIPE_FORMAT_Z32_FLOAT: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: @@ -280,7 +281,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->is_format_supported = nv50_screen_is_format_supported; pscreen->context_create = nv50_create; - nv50_screen_init_miptree_functions(pscreen); + nv50_screen_init_resource_functions(pscreen); /* DMA engine object */ ret = nouveau_grobj_alloc(chan, 0xbeef5039, diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 15bd4eed399..092333a3b10 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -22,7 +22,7 @@ struct nv50_screen { struct nouveau_resource *immd_heap[1]; struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES]; - struct pipe_buffer *strm_vbuf[16]; + struct pipe_resource *strm_vbuf[16]; struct nouveau_bo *tic; struct nouveau_bo *tsc; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index c1628089285..e885a2b7196 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -310,13 +310,13 @@ static void nv50_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(nv50_sampler_view(view)); } static struct pipe_sampler_view * nv50_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view); @@ -324,7 +324,7 @@ nv50_create_sampler_view(struct pipe_context *pipe, view->pipe = *templ; view->pipe.reference.count = 1; view->pipe.texture = NULL; - pipe_texture_reference(&view->pipe.texture, texture); + pipe_resource_reference(&view->pipe.texture, texture); view->pipe.context = pipe; if (!nv50_tex_construct(view)) { @@ -690,7 +690,7 @@ nv50_set_clip_state(struct pipe_context *pipe, static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf ) + struct pipe_resource *buf ) { struct nv50_context *nv50 = nv50_context(pipe); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 402045416c6..a4deb56ffc8 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -23,6 +23,7 @@ #include "util/u_format.h" #include "nv50_context.h" +#include "nv50_resource.h" #include "nouveau/nouveau_stateobj.h" static struct nouveau_stateobj * @@ -43,7 +44,7 @@ validate_fb(struct nv50_context *nv50) (4 << 16) | (5 << 19) | (6 << 22) | (7 << 25)); for (i = 0; i < fb->nr_cbufs; i++) { - struct pipe_texture *pt = fb->cbufs[i]->texture; + struct pipe_resource *pt = fb->cbufs[i]->texture; struct nouveau_bo *bo = nv50_miptree(pt)->base.bo; if (!gw) { @@ -104,7 +105,7 @@ validate_fb(struct nv50_context *nv50) } if (fb->zsbuf) { - struct pipe_texture *pt = fb->zsbuf->texture; + struct pipe_resource *pt = fb->zsbuf->texture; struct nouveau_bo *bo = nv50_miptree(pt)->base.bo; if (!gw) { diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 7a9dada531b..c2d9e835260 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -24,6 +24,7 @@ #include <stdint.h> #include "nouveau/nouveau_pushbuf.h" #include "nv50_context.h" +#include "nv50_resource.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index d094b490edb..2c628db97da 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -22,6 +22,7 @@ #include "nv50_context.h" #include "nv50_texture.h" +#include "nv50_resource.h" #include "nouveau/nouveau_stateobj.h" #include "nouveau/nouveau_reloc.h" diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 6d16c1354bb..9fefed4fef9 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -5,6 +5,8 @@ #include "util/u_math.h" #include "nv50_context.h" +#include "nv50_transfer.h" +#include "nv50_resource.h" struct nv50_transfer { struct pipe_transfer base; @@ -121,44 +123,51 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, } } -static struct pipe_transfer * -nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +struct pipe_transfer * +nv50_miptree_transfer_new(struct pipe_context *pcontext, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct pipe_screen *pscreen = pcontext->screen; struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nv50_miptree *mt = nv50_miptree(pt); - struct nv50_miptree_level *lvl = &mt->level[level]; + struct nv50_miptree_level *lvl = &mt->level[sr.level]; struct nv50_transfer *tx; unsigned nx, ny, image = 0; int ret; if (pt->target == PIPE_TEXTURE_CUBE) - image = face; + image = sr.face; tx = CALLOC_STRUCT(nv50_transfer); if (!tx) return NULL; - pipe_texture_reference(&tx->base.texture, pt); - tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level)); - tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)); - tx->base.width = w; - tx->base.height = h; + /* Don't handle 3D transfers yet. + */ + assert(box->depth == 1); + + + pipe_resource_reference(&tx->base.resource, pt); + tx->base.sr = sr; + tx->base.usage = usage; + tx->base.box = *box; + tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, sr.level)); + tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, sr.level)); tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format); tx->base.usage = usage; tx->level_pitch = lvl->pitch; - tx->level_width = u_minify(mt->base.base.width0, level); - tx->level_height = u_minify(mt->base.base.height0, level); - tx->level_depth = u_minify(mt->base.base.depth0, level); + tx->level_width = u_minify(mt->base.base.width0, sr.level); + tx->level_height = u_minify(mt->base.base.height0, sr.level); + tx->level_depth = u_minify(mt->base.base.depth0, sr.level); tx->level_offset = lvl->image_offset[image]; tx->level_tiling = lvl->tile_mode; - tx->level_z = zslice; - tx->level_x = util_format_get_nblocksx(pt->format, x); - tx->level_y = util_format_get_nblocksy(pt->format, y); + tx->level_z = box->z; + tx->level_x = util_format_get_nblocksx(pt->format, box->x); + tx->level_y = util_format_get_nblocksy(pt->format, box->y); ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, tx->nblocksy * tx->base.stride, &tx->bo); if (ret) { @@ -167,12 +176,12 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt, } if (usage & PIPE_TRANSFER_READ) { - nx = util_format_get_nblocksx(pt->format, tx->base.width); - ny = util_format_get_nblocksy(pt->format, tx->base.height); + nx = util_format_get_nblocksx(pt->format, box->width); + ny = util_format_get_nblocksy(pt->format, box->height); nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset, tx->level_pitch, tx->level_tiling, - x, y, zslice, + box->x, box->y, box->z, tx->nblocksx, tx->nblocksy, tx->level_depth, tx->bo, 0, @@ -187,15 +196,16 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt, return &tx->base; } -static void -nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx) +void +nv50_miptree_transfer_del(struct pipe_context *pcontext, + struct pipe_transfer *ptx) { struct nv50_transfer *tx = (struct nv50_transfer *)ptx; - struct nv50_miptree *mt = nv50_miptree(ptx->texture); - struct pipe_texture *pt = ptx->texture; + struct nv50_miptree *mt = nv50_miptree(ptx->resource); + struct pipe_resource *pt = ptx->resource; - unsigned nx = util_format_get_nblocksx(pt->format, tx->base.width); - unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height); + unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width); + unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height); if (ptx->usage & PIPE_TRANSFER_WRITE) { struct pipe_screen *pscreen = pcontext->screen; @@ -215,12 +225,13 @@ nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx) } nouveau_bo_ref(NULL, &tx->bo); - pipe_texture_reference(&ptx->texture, NULL); + pipe_resource_reference(&ptx->resource, NULL); FREE(ptx); } -static void * -nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx) +void * +nv50_miptree_transfer_map(struct pipe_context *pcontext, + struct pipe_transfer *ptx) { struct nv50_transfer *tx = (struct nv50_transfer *)ptx; unsigned flags = 0; @@ -242,8 +253,9 @@ nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx) return tx->bo->map; } -static void -nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx) +void +nv50_miptree_transfer_unmap(struct pipe_context *pcontext, + struct pipe_transfer *ptx) { struct nv50_transfer *tx = (struct nv50_transfer *)ptx; @@ -252,14 +264,6 @@ nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx) nouveau_bo_unmap(tx->bo); } -void -nv50_init_transfer_functions(struct nv50_context *nv50) -{ - nv50->pipe.get_tex_transfer = nv50_transfer_new; - nv50->pipe.tex_transfer_destroy = nv50_transfer_del; - nv50->pipe.transfer_map = nv50_transfer_map; - nv50->pipe.transfer_unmap = nv50_transfer_unmap; -} void nv50_upload_sifc(struct nv50_context *nv50, diff --git a/src/gallium/drivers/nv50/nv50_transfer.h b/src/gallium/drivers/nv50/nv50_transfer.h new file mode 100644 index 00000000000..663503547cb --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_transfer.h @@ -0,0 +1,31 @@ + +#ifndef NV50_TRANSFER_H +#define NV50_TRANSFER_H + +#include "pipe/p_state.h" + + +struct pipe_transfer * +nv50_miptree_transfer_new(struct pipe_context *pcontext, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box); +void +nv50_miptree_transfer_del(struct pipe_context *pcontext, + struct pipe_transfer *ptx); +void * +nv50_miptree_transfer_map(struct pipe_context *pcontext, + struct pipe_transfer *ptx); +void +nv50_miptree_transfer_unmap(struct pipe_context *pcontext, + struct pipe_transfer *ptx); + +extern void +nv50_upload_sifc(struct nv50_context *nv50, + struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc, + unsigned dst_format, int dst_w, int dst_h, int dst_pitch, + void *src, unsigned src_format, int src_pitch, + int x, int y, int w, int h, int cpp); + +#endif diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 50472868063..609145db88a 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -27,6 +27,7 @@ #include "nouveau/nouveau_util.h" #include "nv50_context.h" +#include "nv50_resource.h" static INLINE uint32_t nv50_vbo_type_to_hw(enum pipe_format format) @@ -139,7 +140,7 @@ instance_init(struct nv50_context *nv50, struct instance *a, unsigned first) if (a[i].divisor) { vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - a[i].bo = nouveau_bo(vb->buffer); + a[i].bo = nv50_resource(vb->buffer)->bo; a[i].stride = vb->stride; a[i].step = first % a[i].divisor; a[i].delta = vb->buffer_offset + ve->src_offset + @@ -307,14 +308,14 @@ inline_edgeflag(void *priv, boolean enabled) static void nv50_draw_elements_inline(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, unsigned indexSize, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count, unsigned startInstance, unsigned instanceCount) { - struct pipe_screen *pscreen = pipe->screen; struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->tesla->channel; struct nouveau_grobj *tesla = nv50->screen->tesla; + struct pipe_transfer *transfer; struct instance a[16]; struct inline_ctx ctx; struct u_split_prim s; @@ -337,7 +338,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, s.edge = inline_edgeflag; ctx.nv50 = nv50; - ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); + ctx.map = pipe_buffer_map(pipe, indexBuffer, PIPE_TRANSFER_READ, &transfer); assert(ctx.map); if (!ctx.map) return; @@ -380,12 +381,12 @@ nv50_draw_elements_inline(struct pipe_context *pipe, nzi = TRUE; } - pipe_buffer_unmap(pscreen, indexBuffer); + pipe_buffer_unmap(pipe, indexBuffer, transfer); } void nv50_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count, unsigned startInstance, unsigned instanceCount) @@ -406,7 +407,7 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, instanceCount); return; } else - if (!(indexBuffer->usage & PIPE_BUFFER_USAGE_INDEX) || indexSize == 1) { + if (!(indexBuffer->bind & PIPE_BIND_INDEX_BUFFER) || indexSize == 1) { nv50_draw_elements_inline(pipe, indexBuffer, indexSize, mode, start, count, startInstance, instanceCount); @@ -431,7 +432,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, if (indexSize == 4) { BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0); OUT_RING (chan, count); - nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer), + nouveau_pushbuf_submit(chan, + nv50_resource(indexBuffer)->bo, start << 2, count << 2); } else if (indexSize == 2) { @@ -443,7 +445,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, OUT_RING (chan, ((start & 1) << 31) | count); BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0); OUT_RING (chan, dwords); - nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer), + nouveau_pushbuf_submit(chan, + nv50_resource(indexBuffer)->bo, vb_start << 1, dwords << 2); BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1); OUT_RING (chan, 0); @@ -457,7 +460,7 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, void nv50_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, unsigned indexSize, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { nv50_draw_elements_instanced(pipe, indexBuffer, indexSize, @@ -473,7 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, { struct nouveau_stateobj *so; struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_bo *bo = nouveau_bo(vb->buffer); + struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; float v[4]; int ret; unsigned nr_components = util_format_get_nr_components(ve->src_format); @@ -556,7 +559,7 @@ nv50_vbo_validate(struct nv50_context *nv50) for (i = 0; i < nv50->vtxbuf_nr; i++) { if (nv50->vtxbuf[i].stride && - !(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)) + !(nv50->vtxbuf[i].buffer->bind & PIPE_BIND_VERTEX_BUFFER)) nv50->vbo_fifo = 0xffff; } @@ -571,7 +574,7 @@ nv50_vbo_validate(struct nv50_context *nv50) struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo *bo = nouveau_bo(vb->buffer); + struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; uint32_t hw = nv50->vtxelt->hw[i]; if (!vb->stride && @@ -608,10 +611,10 @@ nv50_vbo_validate(struct nv50_context *nv50) /* vertex array limits */ so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2); - so_reloc (vtxbuf, bo, vb->buffer->size - 1, + so_reloc (vtxbuf, bo, vb->buffer->width0 - 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (vtxbuf, bo, vb->buffer->size - 1, + so_reloc (vtxbuf, bo, vb->buffer->width0 - 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); } diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile index dfe97e6ed5f..c1d57ca3969 100644 --- a/src/gallium/drivers/nvfx/Makefile +++ b/src/gallium/drivers/nvfx/Makefile @@ -5,6 +5,7 @@ LIBNAME = nvfx C_SOURCES = \ nv04_surface_2d.c \ + nvfx_buffer.c \ nvfx_context.c \ nvfx_clear.c \ nvfx_draw.c \ @@ -14,6 +15,7 @@ C_SOURCES = \ nv40_fragtex.c \ nvfx_miptree.c \ nvfx_query.c \ + nvfx_resource.c \ nvfx_screen.c \ nvfx_state.c \ nvfx_state_blend.c \ @@ -29,4 +31,7 @@ C_SOURCES = \ nvfx_vbo.c \ nvfx_vertprog.c +LIBRARY_INCLUDES = \ + -I$(TOP)/src/gallium/drivers/nouveau/include + include ../../Makefile.template diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.c b/src/gallium/drivers/nvfx/nv04_surface_2d.c index 6784170c00e..005d72b30c7 100644 --- a/src/gallium/drivers/nvfx/nv04_surface_2d.c +++ b/src/gallium/drivers/nvfx/nv04_surface_2d.c @@ -125,8 +125,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, struct nouveau_channel *chan = ctx->swzsurf->channel; struct nouveau_grobj *swzsurf = ctx->swzsurf; struct nouveau_grobj *sifm = ctx->sifm; - struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src)); - struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); + struct nouveau_bo *src_bo = ctx->buf(src); + struct nouveau_bo *dst_bo = ctx->buf(dst); const unsigned src_pitch = ((struct nv04_surface *)src)->pitch; /* Max width & height may not be the same on all HW, but must be POT */ const unsigned max_w = 1024; @@ -205,8 +205,8 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx, { struct nouveau_channel *chan = ctx->m2mf->channel; struct nouveau_grobj *m2mf = ctx->m2mf; - struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src)); - struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); + struct nouveau_bo *src_bo = ctx->buf(src); + struct nouveau_bo *dst_bo = ctx->buf(dst); unsigned src_pitch = ((struct nv04_surface *)src)->pitch; unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; unsigned dst_offset = dst->offset + dy * dst_pitch + @@ -252,8 +252,8 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst, struct nouveau_channel *chan = ctx->surf2d->channel; struct nouveau_grobj *surf2d = ctx->surf2d; struct nouveau_grobj *blit = ctx->blit; - struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src)); - struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); + struct nouveau_bo *src_bo = ctx->buf(src); + struct nouveau_bo *dst_bo = ctx->buf(dst); unsigned src_pitch = ((struct nv04_surface *)src)->pitch; unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; int format; @@ -287,8 +287,8 @@ nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst, { unsigned src_pitch = ((struct nv04_surface *)src)->pitch; unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; - int src_linear = src->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR; - int dst_linear = dst->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR; + int src_linear = src->texture->flags & NVFX_RESOURCE_FLAG_LINEAR; + int dst_linear = dst->texture->flags & NVFX_RESOURCE_FLAG_LINEAR; assert(src->format == dst->format); @@ -317,7 +317,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst, struct nouveau_channel *chan = ctx->surf2d->channel; struct nouveau_grobj *surf2d = ctx->surf2d; struct nouveau_grobj *rect = ctx->rect; - struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst)); + struct nouveau_bo *dst_bo = ctx->buf(dst); unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; int cs2d_format, gdirect_format; @@ -501,26 +501,19 @@ nv04_surface_2d_init(struct nouveau_screen *screen) } struct nv04_surface* -nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns) +nv04_surface_wrap_for_render(struct pipe_screen *pscreen, + struct nv04_surface_2d* eng2d, struct nv04_surface* ns) { int temp_flags; - // printf("creating temp, flags is %i!\n", flags); + temp_flags = (ns->base.usage | + PIPE_BIND_BLIT_SOURCE | + PIPE_BIND_BLIT_DESTINATION); - if(ns->base.usage & PIPE_BUFFER_USAGE_DISCARD) - { - temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ; - ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_DISCARD; - } - else - { - temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; - ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ; - } - - ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; + ns->base.usage = (PIPE_BIND_BLIT_SOURCE | + PIPE_BIND_BLIT_DESTINATION); - struct pipe_texture templ; + struct pipe_resource templ; memset(&templ, 0, sizeof(templ)); templ.format = ns->base.texture->format; templ.target = PIPE_TEXTURE_2D; @@ -532,14 +525,16 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d // TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented templ.nr_samples = ns->base.texture->nr_samples; - templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET; + templ.bind = ns->base.texture->bind | PIPE_BIND_RENDER_TARGET; - struct pipe_texture* temp_tex = pscreen->texture_create(pscreen, &templ); + struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ); struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags); temp_ns->backing = ns; - if(ns->base.usage & PIPE_BUFFER_USAGE_GPU_READ) - eng2d->copy(eng2d, &temp_ns->backing->base, 0, 0, &ns->base, 0, 0, ns->base.width, ns->base.height); + if(ns->base.usage & PIPE_BIND_BLIT_SOURCE) + eng2d->copy(eng2d, &temp_ns->backing->base, + 0, 0, &ns->base, + 0, 0, ns->base.width, ns->base.height); return temp_ns; } diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.h b/src/gallium/drivers/nvfx/nv04_surface_2d.h index ce696a11a39..b2b237b9dfa 100644 --- a/src/gallium/drivers/nvfx/nv04_surface_2d.h +++ b/src/gallium/drivers/nvfx/nv04_surface_2d.h @@ -16,7 +16,7 @@ struct nv04_surface_2d { struct nouveau_grobj *blit; struct nouveau_grobj *sifm; - struct pipe_buffer *(*buf)(struct pipe_surface *); + struct nouveau_bo *(*buf)(struct pipe_surface *); void (*copy)(struct nv04_surface_2d *, struct pipe_surface *dst, int dx, int dy, struct pipe_surface *src, int sx, int sy, @@ -34,4 +34,6 @@ nv04_surface_2d_takedown(struct nv04_surface_2d **); struct nv04_surface* nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns); +#define NVFX_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) + #endif diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c index d3f3edb3278..e0356783ea0 100644 --- a/src/gallium/drivers/nvfx/nv30_fragtex.c +++ b/src/gallium/drivers/nvfx/nv30_fragtex.c @@ -3,6 +3,7 @@ #include "nvfx_context.h" #include "nouveau/nouveau_util.h" #include "nvfx_tex.h" +#include "nvfx_resource.h" void nv30_sampler_state_init(struct pipe_context *pipe, @@ -92,8 +93,8 @@ nv30_fragtex_build(struct nvfx_context *nvfx, int unit) { struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit]; struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture; - struct pipe_texture *pt = &nv30mt->base; - struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer); + struct pipe_resource *pt = &nv30mt->base.base; + struct nouveau_bo *bo = nv30mt->base.bo; struct nv30_texture_format *tf; struct nouveau_stateobj *so; uint32_t txf, txs; diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c index fe87cebbb68..bffdf0893c3 100644 --- a/src/gallium/drivers/nvfx/nv40_fragtex.c +++ b/src/gallium/drivers/nvfx/nv40_fragtex.c @@ -1,6 +1,7 @@ #include "util/u_format.h" #include "nvfx_context.h" #include "nvfx_tex.h" +#include "nvfx_resource.h" void nv40_sampler_state_init(struct pipe_context *pipe, @@ -110,8 +111,8 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit) { struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit]; struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture; - struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer); - struct pipe_texture *pt = &nv40mt->base; + struct nouveau_bo *bo = nv40mt->base.bo; + struct pipe_resource *pt = &nv40mt->base.base; struct nv40_texture_format *tf; struct nouveau_stateobj *so; uint32_t txf, txs, txp; @@ -146,7 +147,7 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit) return NULL; } - if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) { txp = 0; } else { txp = nv40mt->level[0].pitch; diff --git a/src/gallium/drivers/nvfx/nvfx_buffer.c b/src/gallium/drivers/nvfx/nvfx_buffer.c new file mode 100644 index 00000000000..24e0a0c7f65 --- /dev/null +++ b/src/gallium/drivers/nvfx/nvfx_buffer.c @@ -0,0 +1,153 @@ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_winsys.h" +#include "nvfx_resource.h" + + +/* Currently using separate implementations for buffers and textures, + * even though gallium has a unified abstraction of these objects. + * Eventually these should be combined, and mechanisms like transfers + * be adapted to work for both buffer and texture uploads. + */ +static void nvfx_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct nvfx_resource *buffer = nvfx_resource(presource); + + nouveau_screen_bo_release(pscreen, buffer->bo); + FREE(buffer); +} + + + + +/* Utility functions for transfer create/destroy are hooked in and + * just record the arguments to those functions. + */ +static void * +nvfx_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct nvfx_resource *buffer = nvfx_resource(transfer->resource); + uint8_t *map; + + map = nouveau_screen_bo_map_range( pipe->screen, + buffer->bo, + transfer->box.x, + transfer->box.width, + nouveau_screen_transfer_flags(transfer->usage) ); + if (map == NULL) + return NULL; + + return map + transfer->box.x; +} + + + +static void nvfx_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct nvfx_resource *buffer = nvfx_resource(transfer->resource); + + nouveau_screen_bo_map_flush_range(pipe->screen, + buffer->bo, + transfer->box.x + box->x, + box->width); +} + +static void nvfx_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct nvfx_resource *buffer = nvfx_resource(transfer->resource); + + nouveau_screen_bo_unmap(pipe->screen, buffer->bo); +} + + + + +struct u_resource_vtbl nvfx_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + nvfx_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + nvfx_buffer_transfer_map, /* transfer_map */ + nvfx_buffer_transfer_flush_region, /* transfer_flush_region */ + nvfx_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + +struct pipe_resource * +nvfx_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *template) +{ + struct nvfx_resource *buffer; + + buffer = CALLOC_STRUCT(nvfx_resource); + if (!buffer) + return NULL; + + buffer->base = *template; + buffer->vtbl = &nvfx_buffer_vtbl; + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = pscreen; + + buffer->bo = nouveau_screen_bo_new(pscreen, + 16, + buffer->base._usage, + buffer->base.bind, + buffer->base.width0); + + if (buffer->bo == NULL) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + + +struct pipe_resource * +nvfx_user_buffer_create(struct pipe_screen *pscreen, + void *ptr, + unsigned bytes, + unsigned usage) +{ + struct nvfx_resource *buffer; + + buffer = CALLOC_STRUCT(nvfx_resource); + if (!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->vtbl = &nvfx_buffer_vtbl; + buffer->base.screen = pscreen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.bind = usage; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + + buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes); + if (!buffer->bo) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index fc3cbdb558f..61f55907e0d 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -3,6 +3,7 @@ #include "nvfx_context.h" #include "nvfx_screen.h" +#include "nvfx_resource.h" static void nvfx_flush(struct pipe_context *pipe, unsigned flags, @@ -65,9 +66,6 @@ nvfx_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.clear = nvfx_clear; nvfx->pipe.flush = nvfx_flush; - nvfx->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - screen->base.channel->user_private = nvfx; screen->base.channel->flush_notify = nvfx_state_flush_notify; @@ -76,7 +74,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv) nvfx_init_query_functions(nvfx); nvfx_init_surface_functions(nvfx); nvfx_init_state_functions(nvfx); - nvfx_init_transfer_functions(nvfx); + nvfx_init_resource_functions(&nvfx->pipe); /* Create, configure, and install fallback swtnl path */ nvfx->draw = draw_create(); diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index ab7225cf6c3..9d988b015c2 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -16,7 +16,6 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.h" #include "nouveau/nouveau_stateobj.h" #include "nvfx_state.h" @@ -146,7 +145,7 @@ struct nvfx_context { struct pipe_clip_state clip; struct nvfx_vertex_program *vertprog; struct nvfx_fragment_program *fragprog; - struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nvfx_rasterizer_state *rasterizer; struct nvfx_zsa_state *zsa; @@ -155,7 +154,7 @@ struct nvfx_context { struct pipe_stencil_ref stencil_ref; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; - struct pipe_buffer *idxbuf; + struct pipe_resource *idxbuf; unsigned idxbuf_format; struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; @@ -210,7 +209,7 @@ extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers, /* nvfx_draw.c */ extern struct draw_stage *nvfx_draw_render_stage(struct nvfx_context *nvfx); extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe, - struct pipe_buffer *idxbuf, + struct pipe_resource *idxbuf, unsigned ib_size, unsigned mode, unsigned start, unsigned count); @@ -252,7 +251,7 @@ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode, unsigned start, unsigned count); extern void nvfx_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c index 68e50a36479..fc6f8d02721 100644 --- a/src/gallium/drivers/nvfx/nvfx_draw.c +++ b/src/gallium/drivers/nvfx/nvfx_draw.c @@ -234,11 +234,13 @@ nvfx_draw_render_stage(struct nvfx_context *nvfx) void nvfx_draw_elements_swtnl(struct pipe_context *pipe, - struct pipe_buffer *idxbuf, unsigned idxbuf_size, + struct pipe_resource *idxbuf, unsigned idxbuf_size, unsigned mode, unsigned start, unsigned count) { struct nvfx_context *nvfx = nvfx_context(pipe); - struct pipe_screen *pscreen = pipe->screen; + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *ib_transfer; + struct pipe_transfer *cb_transfer; unsigned i; void *map; @@ -248,14 +250,16 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe, nvfx_state_emit(nvfx); for (i = 0; i < nvfx->vtxbuf_nr; i++) { - map = pipe_buffer_map(pscreen, nvfx->vtxbuf[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, nvfx->vtxbuf[i].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[i]); draw_set_mapped_vertex_buffer(nvfx->draw, i, map); } if (idxbuf) { - map = pipe_buffer_map(pscreen, idxbuf, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, idxbuf, + PIPE_TRANSFER_READ, + &ib_transfer); draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map); } else { draw_set_mapped_element_buffer(nvfx->draw, 0, NULL); @@ -264,9 +268,10 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe, if (nvfx->constbuf[PIPE_SHADER_VERTEX]) { const unsigned nr = nvfx->constbuf_nr[PIPE_SHADER_VERTEX]; - map = pipe_buffer_map(pscreen, + map = pipe_buffer_map(pipe, nvfx->constbuf[PIPE_SHADER_VERTEX], - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &cb_transfer); draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0, map, nr); } @@ -274,13 +279,14 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe, draw_arrays(nvfx->draw, mode, start, count); for (i = 0; i < nvfx->vtxbuf_nr; i++) - pipe_buffer_unmap(pscreen, nvfx->vtxbuf[i].buffer); + pipe_buffer_unmap(pipe, nvfx->vtxbuf[i].buffer, vb_transfer[i]); if (idxbuf) - pipe_buffer_unmap(pscreen, idxbuf); + pipe_buffer_unmap(pipe, idxbuf, ib_transfer); if (nvfx->constbuf[PIPE_SHADER_VERTEX]) - pipe_buffer_unmap(pscreen, nvfx->constbuf[PIPE_SHADER_VERTEX]); + pipe_buffer_unmap(pipe, nvfx->constbuf[PIPE_SHADER_VERTEX], + cb_transfer); draw_flush(nvfx->draw); pipe->flush(pipe, 0, NULL); diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c index b9c91cec8ce..c600f284446 100644 --- a/src/gallium/drivers/nvfx/nvfx_fragprog.c +++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c @@ -9,6 +9,7 @@ #include "nvfx_context.h" #include "nvfx_shader.h" +#include "nvfx_resource.h" #define MAX_CONSTS 128 #define MAX_IMM 32 @@ -826,12 +827,8 @@ static void nvfx_fragprog_upload(struct nvfx_context *nvfx, struct nvfx_fragment_program *fp) { - struct pipe_screen *pscreen = nvfx->pipe.screen; + struct pipe_context *pipe = &nvfx->pipe; const uint32_t le = 1; - uint32_t *map; - int i; - - map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); #if 0 for (i = 0; i < fp->insn_len; i++) { @@ -842,25 +839,37 @@ nvfx_fragprog_upload(struct nvfx_context *nvfx, #endif if ((*(const uint8_t *)&le)) { - for (i = 0; i < fp->insn_len; i++) { - map[i] = fp->insn[i]; - } + /* Can do this with an inline transfer */ + pipe_buffer_write(pipe, + fp->buffer, + 0, + fp->insn_len * sizeof fp->insn[0], + fp->insn); } else { + struct pipe_transfer *transfer; + uint32_t *map; + int i; + + map = pipe_buffer_map(pipe, fp->buffer, + PIPE_TRANSFER_WRITE, + &transfer); + /* Weird swapping for big-endian chips */ for (i = 0; i < fp->insn_len; i++) { map[i] = ((fp->insn[i] & 0xffff) << 16) | ((fp->insn[i] >> 16) & 0xffff); } - } - pipe_buffer_unmap(pscreen, fp->buffer); + pipe_buffer_unmap(pipe, fp->buffer, transfer); + } } static boolean nvfx_fragprog_validate(struct nvfx_context *nvfx) { + struct pipe_context *pipe = &nvfx->pipe; struct nvfx_fragment_program *fp = nvfx->fragprog; - struct pipe_buffer *constbuf = + struct pipe_resource *constbuf = nvfx->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_screen *pscreen = nvfx->pipe.screen; struct nouveau_stateobj *so; @@ -877,12 +886,16 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) return FALSE; } - fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4); + fp->buffer = pipe_buffer_create(pscreen, + /* XXX: no alignment, maybe use a priv bind flag + * 0x100, + */ + 0, fp->insn_len * 4); nvfx_fragprog_upload(nvfx, fp); so = so_new(4, 4, 1); so_method(so, nvfx->screen->eng3d, NV34TCL_FP_ACTIVE_PROGRAM, 1); - so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM | + so_reloc (so, nvfx_resource(fp->buffer)->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0, NV34TCL_FP_ACTIVE_PROGRAM_DMA1); @@ -900,10 +913,18 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) update_constants: if (fp->nr_consts) { + struct pipe_transfer *transfer; float *map; - map = pipe_buffer_map(pscreen, constbuf, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, constbuf, + PIPE_TRANSFER_READ, + &transfer); + + /* XXX: probably a bad idea to be reading back data + * from a buffer the gpu has been using. Not really + * sure what this code is doing though, or how to + * avoid it - kw. + */ for (i = 0; i < fp->nr_consts; i++) { struct nvfx_fragment_program_data *fpd = &fp->consts[i]; uint32_t *p = &fp->insn[fpd->offset]; @@ -914,7 +935,7 @@ update_constants: memcpy(p, cb, 4 * sizeof(float)); new_consts = TRUE; } - pipe_buffer_unmap(pscreen, constbuf); + pipe_buffer_unmap(pipe, constbuf, transfer); if (new_consts) nvfx_fragprog_upload(nvfx, fp); @@ -933,7 +954,7 @@ nvfx_fragprog_destroy(struct nvfx_context *nvfx, struct nvfx_fragment_program *fp) { if (fp->buffer) - pipe_buffer_reference(&fp->buffer, NULL); + pipe_resource_reference(&fp->buffer, NULL); if (fp->so) so_ref(NULL, &fp->so); diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c index 9de25175e78..a5965ca4a31 100644 --- a/src/gallium/drivers/nvfx/nvfx_miptree.c +++ b/src/gallium/drivers/nvfx/nvfx_miptree.c @@ -5,22 +5,30 @@ #include "util/u_math.h" #include "nvfx_context.h" +#include "nvfx_resource.h" +#include "nvfx_transfer.h" #include "nv04_surface_2d.h" +#include "nouveau/nouveau_util.h" +/* Currently using separate implementations for buffers and textures, + * even though gallium has a unified abstraction of these objects. + * Eventually these should be combined, and mechanisms like transfers + * be adapted to work for both buffer and texture uploads. + */ static void nvfx_miptree_layout(struct nvfx_miptree *mt) { - struct pipe_texture *pt = &mt->base; + struct pipe_resource *pt = &mt->base.base; uint width = pt->width0; uint offset = 0; int nr_faces, l, f; - uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT); + uint wide_pitch = pt->bind & (PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DEPTH_STENCIL | + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT); if (pt->target == PIPE_TEXTURE_CUBE) { nr_faces = 6; @@ -32,7 +40,7 @@ nvfx_miptree_layout(struct nvfx_miptree *mt) } for (l = 0; l <= pt->last_level; l++) { - if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) + if (wide_pitch && (pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64); else mt->level[l].pitch = util_format_get_stride(pt->format, width); @@ -47,7 +55,7 @@ nvfx_miptree_layout(struct nvfx_miptree *mt) for (l = 0; l < pt->last_level; l++) { mt->level[l].image_offset[f] = offset; - if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && + if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR) && u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64); else @@ -61,35 +69,86 @@ nvfx_miptree_layout(struct nvfx_miptree *mt) mt->total_size = offset; } -static struct pipe_texture * -nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) +static boolean +nvfx_miptree_get_handle(struct pipe_screen *pscreen, + struct pipe_resource *ptexture, + struct winsys_handle *whandle) +{ + struct nvfx_miptree* mt = (struct nvfx_miptree*)ptexture; + + if (!mt || !mt->base.bo) + return FALSE; + + return nouveau_screen_bo_get_handle(pscreen, + mt->base.bo, + mt->level[0].pitch, + whandle); +} + + +static void +nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt) +{ + struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; + int l; + + nouveau_screen_bo_release(screen, mt->base.bo); + + for (l = 0; l <= pt->last_level; l++) { + if (mt->level[l].image_offset) + FREE(mt->level[l].image_offset); + } + + FREE(mt); +} + + + + +struct u_resource_vtbl nvfx_miptree_vtbl = +{ + nvfx_miptree_get_handle, /* get_handle */ + nvfx_miptree_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nvfx_miptree_transfer_new, /* get_transfer */ + nvfx_miptree_transfer_del, /* transfer_destroy */ + nvfx_miptree_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + nvfx_miptree_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + +struct pipe_resource * +nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt) { struct nvfx_miptree *mt; - unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE; static int no_swizzle = -1; if(no_swizzle < 0) no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE); - mt = MALLOC(sizeof(struct nvfx_miptree)); + mt = CALLOC_STRUCT(nvfx_miptree); if (!mt) return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; + + mt->base.base = *pt; + mt->base.vtbl = &nvfx_miptree_vtbl; + pipe_reference_init(&mt->base.base.reference, 1); + mt->base.base.screen = pscreen; /* Swizzled textures must be POT */ if (pt->width0 & (pt->width0 - 1) || pt->height0 & (pt->height0 - 1)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; else - if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + if (pt->bind & (PIPE_BIND_SCANOUT | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_DEPTH_STENCIL)) + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; else - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + if (pt->_usage == PIPE_USAGE_DYNAMIC) + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; else { switch (pt->format) { case PIPE_FORMAT_B5G6R5_UNORM: @@ -101,7 +160,7 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) are just preserving the pre-unification behavior. The whole 2D code is going to be rewritten anyway. */ if(nvfx_screen(pscreen)->is_nv4x) { - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; break; } /* TODO: Figure out which formats can be swizzled */ @@ -110,80 +169,82 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) case PIPE_FORMAT_R16_SNORM: { if (no_swizzle) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; break; } default: - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; } } - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear. * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy. * This also happens for small mipmaps of large textures. */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + if (pt->bind & PIPE_BIND_RENDER_TARGET && + util_format_get_stride(pt->format, pt->width0) < 64) + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; nvfx_miptree_layout(mt); - mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage, mt->total_size); - if (!mt->buffer) { + mt->base.bo = nouveau_screen_bo_new(pscreen, 256, + pt->_usage, pt->bind, mt->total_size); + if (!mt->base.bo) { FREE(mt); return NULL; } - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; + return &mt->base.base; } -static struct pipe_texture * -nvfx_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) + + + +struct pipe_resource * +nvfx_miptree_from_handle(struct pipe_screen *pscreen, + const struct pipe_resource *template, + struct winsys_handle *whandle) { struct nvfx_miptree *mt; + unsigned stride; /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) + if (template->target != PIPE_TEXTURE_2D || + template->last_level != 0 || + template->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nvfx_miptree); if (!mt) return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; + mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); + if (mt->base.bo == NULL) { + FREE(mt); + return NULL; + } + + mt->base.base = *template; + pipe_reference_init(&mt->base.base.reference, 1); + mt->base.base.screen = pscreen; + mt->level[0].pitch = stride; mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); /* Assume whoever created this buffer expects it to be linear for now */ - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; + /* XXX: Need to adjust bo refcount?? + */ + /* nouveau_bo_ref(bo, &mt->base.bo); */ + return &mt->base.base; } -static void -nvfx_miptree_destroy(struct pipe_texture *pt) -{ - struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; - int l; - pipe_buffer_reference(&mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (mt->level[l].image_offset) - FREE(mt->level[l].image_offset); - } - FREE(mt); -} -static struct pipe_surface * -nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + +/* Surface helpers, not strictly required to implement the resource vtbl: + */ +struct pipe_surface * +nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { @@ -193,7 +254,7 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns = CALLOC_STRUCT(nv04_surface); if (!ns) return NULL; - pipe_texture_reference(&ns->base.texture, pt); + pipe_resource_reference(&ns->base.texture, pt); ns->base.format = pt->format; ns->base.width = u_minify(pt->width0, level); ns->base.height = u_minify(pt->height0, level); @@ -213,38 +274,38 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.offset = mt->level[level].image_offset[0]; } - /* create a linear temporary that we can render into if necessary. - * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so - * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/ - if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE) - return &nv04_surface_wrap_for_render(pscreen, ((struct nvfx_screen*)pscreen)->eng2d, ns)->base; + /* create a linear temporary that we can render into if + * necessary. + * + * Note that ns->pitch is always a multiple of 64 for linear + * surfaces and swizzled surfaces are POT, so ns->pitch & 63 + * is equivalent to (ns->pitch < 64 && swizzled) + */ + + if ((ns->pitch & 63) && + (ns->base.usage & PIPE_BIND_RENDER_TARGET)) + { + struct nv04_surface_2d* eng2d = + ((struct nvfx_screen*)pscreen)->eng2d; + + ns = nv04_surface_wrap_for_render(pscreen, eng2d, ns); + } return &ns->base; } -static void +void nvfx_miptree_surface_del(struct pipe_surface *ps) { struct nv04_surface* ns = (struct nv04_surface*)ps; if(ns->backing) { struct nvfx_screen* screen = (struct nvfx_screen*)ps->texture->screen; - if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE) + if(ns->backing->base.usage & PIPE_BIND_RENDER_TARGET) screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); nvfx_miptree_surface_del(&ns->backing->base); } - pipe_texture_reference(&ps->texture, NULL); + pipe_resource_reference(&ps->texture, NULL); FREE(ps); } - -void -nvfx_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nvfx_miptree_create; - pscreen->texture_destroy = nvfx_miptree_destroy; - pscreen->get_tex_surface = nvfx_miptree_surface_new; - pscreen->tex_surface_destroy = nvfx_miptree_surface_del; - - nouveau_screen(pscreen)->texture_blanket = nvfx_miptree_blanket; -} diff --git a/src/gallium/drivers/nvfx/nvfx_resource.c b/src/gallium/drivers/nvfx/nvfx_resource.c new file mode 100644 index 00000000000..10cdeed2a37 --- /dev/null +++ b/src/gallium/drivers/nvfx/nvfx_resource.c @@ -0,0 +1,67 @@ + +#include "pipe/p_context.h" +#include "nvfx_resource.h" +#include "nouveau/nouveau_screen.h" + + +/* This doesn't look quite right - this query is supposed to ask + * whether the particular context has references to the resource in + * any unflushed rendering command buffer, and hence requires a + * pipe->flush() for serializing some modification to that resource. + * + * This seems to be answering the question of whether the resource is + * currently on hardware. + */ +static unsigned int +nvfx_resource_is_referenced(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned face, unsigned level) +{ + return nouveau_reference_flags(nvfx_resource(resource)->bo); +} + +static struct pipe_resource * +nvfx_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return nvfx_buffer_create(screen, template); + else + return nvfx_miptree_create(screen, template); +} + +static struct pipe_resource * +nvfx_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return nvfx_miptree_from_handle(screen, template, whandle); +} + +void +nvfx_init_resource_functions(struct pipe_context *pipe) +{ + pipe->get_transfer = u_get_transfer_vtbl; + pipe->transfer_map = u_transfer_map_vtbl; + pipe->transfer_flush_region = u_transfer_flush_region_vtbl; + pipe->transfer_unmap = u_transfer_unmap_vtbl; + pipe->transfer_destroy = u_transfer_destroy_vtbl; + pipe->transfer_inline_write = u_transfer_inline_write_vtbl; + pipe->is_resource_referenced = nvfx_resource_is_referenced; +} + +void +nvfx_screen_init_resource_functions(struct pipe_screen *pscreen) +{ + pscreen->resource_create = nvfx_resource_create; + pscreen->resource_from_handle = nvfx_resource_from_handle; + pscreen->resource_get_handle = u_resource_get_handle_vtbl; + pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->user_buffer_create = nvfx_user_buffer_create; + + pscreen->get_tex_surface = nvfx_miptree_surface_new; + pscreen->tex_surface_destroy = nvfx_miptree_surface_del; +} diff --git a/src/gallium/drivers/nvfx/nvfx_resource.h b/src/gallium/drivers/nvfx/nvfx_resource.h new file mode 100644 index 00000000000..a68c14cf3fb --- /dev/null +++ b/src/gallium/drivers/nvfx/nvfx_resource.h @@ -0,0 +1,91 @@ + +#ifndef NVFX_RESOURCE_H +#define NVFX_RESOURCE_H + +#include "util/u_transfer.h" + +struct pipe_resource; +struct nouveau_bo; + + +/* This gets further specialized into either buffer or texture + * structures. In the future we'll want to remove much of that + * distinction, but for now try to keep as close to the existing code + * as possible and use the vtbl struct to choose between the two + * underlying implementations. + */ +struct nvfx_resource { + struct pipe_resource base; + struct u_resource_vtbl *vtbl; + struct nouveau_bo *bo; +}; + +#define NVFX_MAX_TEXTURE_LEVELS 16 + +struct nvfx_miptree { + struct nvfx_resource base; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[NVFX_MAX_TEXTURE_LEVELS]; + + unsigned image_nr; +}; + +static INLINE +struct nvfx_resource *nvfx_resource(struct pipe_resource *resource) +{ + return (struct nvfx_resource *)resource; +} + +static INLINE struct nouveau_bo * +nvfx_surface_buffer(struct pipe_surface *surf) +{ + struct nvfx_resource *mt = nvfx_resource(surf->texture); + + return mt->bo; +} + + +void +nvfx_init_resource_functions(struct pipe_context *pipe); + +void +nvfx_screen_init_resource_functions(struct pipe_screen *pscreen); + + +/* Internal: + */ + +struct pipe_resource * +nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt); + +struct pipe_resource * +nvfx_miptree_from_handle(struct pipe_screen *pscreen, + const struct pipe_resource *template, + struct winsys_handle *whandle); + +struct pipe_resource * +nvfx_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *template); + +struct pipe_resource * +nvfx_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + + + +void +nvfx_miptree_surface_del(struct pipe_surface *ps); + +struct pipe_surface * +nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags); + + +#endif diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 1a103520a3c..1f6e6e34973 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -1,10 +1,12 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" +#include "util/u_simple_screen.h" #include "nouveau/nouveau_screen.h" #include "nvfx_context.h" #include "nvfx_screen.h" +#include "nvfx_resource.h" #define NV30TCL_CHIPSET_3X_MASK 0x00000003 #define NV34TCL_CHIPSET_3X_MASK 0x00000010 @@ -122,7 +124,7 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, struct nvfx_screen *screen = nvfx_screen(pscreen); struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front; - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B5G6R5_UNORM: @@ -131,7 +133,7 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, break; } } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { switch (format) { case PIPE_FORMAT_S8_USCALED_Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: @@ -172,13 +174,6 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, return FALSE; } -static struct pipe_buffer * -nvfx_surface_buffer(struct pipe_surface *surf) -{ - struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture; - - return mt->buffer; -} static void nvfx_screen_destroy(struct pipe_screen *pscreen) @@ -380,8 +375,8 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } + nvfx_screen_init_resource_functions(pscreen); nvfx_screen_init_buffer_functions(screen); - nvfx_screen_init_miptree_functions(pscreen); ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d); if (ret) { diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h index baa848c47aa..3302e1aa586 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.h +++ b/src/gallium/drivers/nvfx/nvfx_screen.h @@ -3,6 +3,7 @@ #include "nouveau/nouveau_screen.h" #include "nv04_surface_2d.h" +#include "nvfx_context.h" struct nvfx_screen { struct nouveau_screen base; diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index ecaa0dcb16a..e11ab46c425 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -163,7 +163,7 @@ nvfx_set_fragment_sampler_views(struct pipe_context *pipe, static struct pipe_sampler_view * nvfx_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -172,7 +172,7 @@ nvfx_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -184,7 +184,7 @@ static void nvfx_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } @@ -499,12 +499,12 @@ nvfx_set_clip_state(struct pipe_context *pipe, static void nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf ) + struct pipe_resource *buf ) { struct nvfx_context *nvfx = nvfx_context(pipe); nvfx->constbuf[shader] = buf; - nvfx->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + nvfx->constbuf_nr[shader] = buf->width0 / (4 * sizeof(float)); if (shader == PIPE_SHADER_VERTEX) { nvfx->dirty |= NVFX_NEW_VERTPROG; diff --git a/src/gallium/drivers/nvfx/nvfx_state.h b/src/gallium/drivers/nvfx/nvfx_state.h index e585246879b..1f612ea95f5 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.h +++ b/src/gallium/drivers/nvfx/nvfx_state.h @@ -58,26 +58,14 @@ struct nvfx_fragment_program { struct nvfx_fragment_program_data *consts; unsigned nr_consts; - - struct pipe_buffer *buffer; + + /* XXX: just use a nouveau_bo for this? + */ + struct pipe_resource *buffer; uint32_t fp_control; struct nouveau_stateobj *so; }; -#define NVFX_MAX_TEXTURE_LEVELS 16 - -struct nvfx_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; - - struct pipe_buffer *buffer; - uint total_size; - - struct { - uint pitch; - uint *image_offset; - } level[NVFX_MAX_TEXTURE_LEVELS]; -}; #endif diff --git a/src/gallium/drivers/nvfx/nvfx_state_fb.c b/src/gallium/drivers/nvfx/nvfx_state_fb.c index 1923184163b..c64ba27eaaa 100644 --- a/src/gallium/drivers/nvfx/nvfx_state_fb.c +++ b/src/gallium/drivers/nvfx/nvfx_state_fb.c @@ -1,14 +1,8 @@ #include "nvfx_context.h" +#include "nvfx_resource.h" #include "nouveau/nouveau_util.h" -static struct pipe_buffer * -nvfx_do_surface_buffer(struct pipe_surface *surface) -{ - struct nvfx_miptree *mt = (struct nvfx_miptree *)surface->texture; - return mt->buffer; -} -#define nvfx_surface_buffer(ps) nouveau_bo(nvfx_do_surface_buffer(ps)) static boolean nvfx_state_framebuffer_validate(struct nvfx_context *nvfx) @@ -53,10 +47,10 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx) if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) { /* Render to at least a colour buffer */ - if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + if (!(rt[0]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) { assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); for (i = 1; i < fb->nr_cbufs; i++) - assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)); + assert(!(rt[i]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)); rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | (log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) | @@ -68,7 +62,7 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx) depth_only = 1; /* Render to depth buffer only */ - if (!(zeta->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + if (!(zeta->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) { assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c index 1c250e9fe44..59ab14826c3 100644 --- a/src/gallium/drivers/nvfx/nvfx_transfer.c +++ b/src/gallium/drivers/nvfx/nvfx_transfer.c @@ -8,6 +8,8 @@ #include "nvfx_context.h" #include "nvfx_screen.h" #include "nvfx_state.h" +#include "nvfx_resource.h" +#include "nvfx_transfer.h" struct nvfx_transfer { struct pipe_transfer base; @@ -16,10 +18,11 @@ struct nvfx_transfer { }; static void -nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) +nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height, + unsigned bind, + struct pipe_resource *template) { - memset(template, 0, sizeof(struct pipe_texture)); + memset(template, 0, sizeof(struct pipe_resource)); template->target = pt->target; template->format = pt->format; template->width0 = width; @@ -27,56 +30,77 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h template->depth0 = 1; template->last_level = 0; template->nr_samples = pt->nr_samples; + template->bind = bind; + template->_usage = PIPE_USAGE_DYNAMIC; + template->flags = NVFX_RESOURCE_FLAG_LINEAR; +} + + +static unsigned nvfx_transfer_bind_flags( unsigned transfer_usage ) +{ + unsigned bind = 0; + + if (transfer_usage & PIPE_TRANSFER_WRITE) + bind |= PIPE_BIND_BLIT_DESTINATION; - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; + if (transfer_usage & PIPE_TRANSFER_READ) + bind |= PIPE_BIND_BLIT_SOURCE; + + return bind; } -static struct pipe_transfer * -nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +struct pipe_transfer * +nvfx_miptree_transfer_new(struct pipe_context *pipe, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct pipe_screen *pscreen = pipe->screen; struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; struct nvfx_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; + struct pipe_resource tx_tex_template, *tx_tex; static int no_transfer = -1; + unsigned bind = nvfx_transfer_bind_flags(usage); if(no_transfer < 0) no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/); + tx = CALLOC_STRUCT(nvfx_transfer); if (!tx) return NULL; - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; + /* Don't handle 3D transfers yet. + */ + assert(box->depth == 1); + + pipe_resource_reference(&tx->base.resource, pt); + tx->base.sr = sr; tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; + tx->base.box = *box; + tx->base.stride = mt->level[sr.level].pitch; /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) + if ((pt->_usage == PIPE_USAGE_DYNAMIC || + no_transfer) && + pt->flags & NVFX_RESOURCE_FLAG_LINEAR) { tx->direct = true; + + /* XXX: just call the internal nvfx function. + */ tx->surface = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); + sr.face, sr.level, + box->z, + bind); return &tx->base; } tx->direct = false; - nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template); + nvfx_compatible_transfer_tex(pt, box->width, box->height, bind, &tx_tex_template); - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); + tx_tex = pscreen->resource_create(pscreen, &tx_tex_template); if (!tx_tex) { FREE(tx); @@ -87,9 +111,9 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); + bind); - pipe_texture_reference(&tx_tex, NULL); + pipe_resource_reference(&tx_tex, NULL); if (!tx->surface) { @@ -103,15 +127,16 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt, struct pipe_surface *src; src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); + sr.face, sr.level, box->z, + PIPE_BIND_BLIT_SOURCE); /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ /* TODO: Check if SIFM can un-swizzle */ nvscreen->eng2d->copy(nvscreen->eng2d, tx->surface, 0, 0, - src, x, y, - w, h); + src, + box->x, box->y, + box->width, box->height); pipe_surface_reference(&src, NULL); } @@ -119,9 +144,9 @@ nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt, return &tx->base; } -static void -nvfx_transfer_del(struct pipe_context *pipe, - struct pipe_transfer *ptx) +void +nvfx_miptree_transfer_del(struct pipe_context *pipe, + struct pipe_transfer *ptx) { struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; @@ -130,55 +155,51 @@ nvfx_transfer_del(struct pipe_context *pipe, struct nvfx_screen *nvscreen = nvfx_screen(pscreen); struct pipe_surface *dst; - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER); + dst = pscreen->get_tex_surface(pscreen, + ptx->resource, + ptx->sr.face, + ptx->sr.level, + ptx->box.z, + PIPE_BIND_BLIT_DESTINATION); /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, + dst, ptx->box.x, ptx->box.y, tx->surface, 0, 0, - tx->base.width, tx->base.height); + ptx->box.width, ptx->box.height); pipe_surface_reference(&dst, NULL); } pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); + pipe_resource_reference(&ptx->resource, NULL); FREE(ptx); } -static void * -nvfx_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx) +void * +nvfx_miptree_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx) { struct pipe_screen *pscreen = pipe->screen; struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); + uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo, + nouveau_screen_transfer_flags(ptx->usage)); if(!tx->direct) return map + ns->base.offset; else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); + return (map + ns->base.offset + + ptx->box.y * ns->pitch + + ptx->box.x * util_format_get_blocksize(ptx->resource->format)); } -static void -nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx) +void +nvfx_miptree_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx) { struct pipe_screen *pscreen = pipe->screen; struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nvfx_init_transfer_functions(struct nvfx_context *nvfx) -{ - nvfx->pipe.get_tex_transfer = nvfx_transfer_new; - nvfx->pipe.tex_transfer_destroy = nvfx_transfer_del; - nvfx->pipe.transfer_map = nvfx_transfer_map; - nvfx->pipe.transfer_unmap = nvfx_transfer_unmap; + nouveau_screen_bo_unmap(pscreen, mt->base.bo); } diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.h b/src/gallium/drivers/nvfx/nvfx_transfer.h new file mode 100644 index 00000000000..3e3317b2c7b --- /dev/null +++ b/src/gallium/drivers/nvfx/nvfx_transfer.h @@ -0,0 +1,26 @@ + +#ifndef NVFX_TRANSFER_H +#define NVFX_TRANSFER_H + +#include "util/u_transfer.h" +#include "pipe/p_state.h" + + +struct pipe_transfer * +nvfx_miptree_transfer_new(struct pipe_context *pcontext, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box); +void +nvfx_miptree_transfer_del(struct pipe_context *pcontext, + struct pipe_transfer *ptx); +void * +nvfx_miptree_transfer_map(struct pipe_context *pcontext, + struct pipe_transfer *ptx); +void +nvfx_miptree_transfer_unmap(struct pipe_context *pcontext, + struct pipe_transfer *ptx); + + +#endif diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c index c26536b0e77..b9566f9ee27 100644 --- a/src/gallium/drivers/nvfx/nvfx_vbo.c +++ b/src/gallium/drivers/nvfx/nvfx_vbo.c @@ -5,6 +5,7 @@ #include "nvfx_context.h" #include "nvfx_state.h" +#include "nvfx_resource.h" #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" @@ -76,7 +77,7 @@ nvfx_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) } static boolean -nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib, +nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib, unsigned ib_size) { struct pipe_screen *pscreen = &nvfx->screen->base.base; @@ -117,21 +118,22 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so, int attrib, struct pipe_vertex_element *ve, struct pipe_vertex_buffer *vb) { - struct pipe_screen *pscreen = nvfx->pipe.screen; + struct pipe_context *pipe = &nvfx->pipe; struct nouveau_grobj *eng3d = nvfx->screen->eng3d; + struct pipe_transfer *transfer; unsigned type, ncomp; - void *map; + uint8_t *map; if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp)) return FALSE; - map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, vb->buffer, PIPE_TRANSFER_READ, &transfer); map += vb->buffer_offset + ve->src_offset; switch (type) { case NV34TCL_VTXFMT_TYPE_FLOAT: { - float *v = map; + float *v = (float *)map; switch (ncomp) { case 4: @@ -157,17 +159,17 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so, so_data (so, fui(v[0])); break; default: - pipe_buffer_unmap(pscreen, vb->buffer); + pipe_buffer_unmap(pipe, vb->buffer, transfer); return FALSE; } } break; default: - pipe_buffer_unmap(pscreen, vb->buffer); + pipe_buffer_unmap(pipe, vb->buffer, transfer); return FALSE; } - pipe_buffer_unmap(pscreen, vb->buffer); + pipe_buffer_unmap(pipe, vb->buffer, transfer); return TRUE; } @@ -379,14 +381,14 @@ nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib, static void nvfx_draw_elements_inline(struct pipe_context *pipe, - struct pipe_buffer *ib, unsigned ib_size, + struct pipe_resource *ib, unsigned ib_size, unsigned mode, unsigned start, unsigned count) { struct nvfx_context *nvfx = nvfx_context(pipe); - struct pipe_screen *pscreen = pipe->screen; + struct pipe_transfer *transfer; void *map; - map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, ib, PIPE_TRANSFER_READ, &transfer); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); return; @@ -407,7 +409,7 @@ nvfx_draw_elements_inline(struct pipe_context *pipe, break; } - pipe_buffer_unmap(pscreen, ib); + pipe_buffer_unmap(pipe, ib, transfer); } static void @@ -465,7 +467,7 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe, void nvfx_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, unsigned indexSize, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { struct nvfx_context *nvfx = nvfx_context(pipe); @@ -493,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx) { struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL; struct nouveau_grobj *eng3d = nvfx->screen->eng3d; - struct pipe_buffer *ib = nvfx->idxbuf; + struct pipe_resource *ib = nvfx->idxbuf; unsigned ib_format = nvfx->idxbuf_format; unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD; int hw; @@ -529,7 +531,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx) return FALSE; } - so_reloc(vtxbuf, nouveau_bo(vb->buffer), + so_reloc(vtxbuf, nvfx_resource(vb->buffer)->bo, vb->buffer_offset + ve->src_offset, vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, 0, NV34TCL_VTXBUF_ADDRESS_DMA1); @@ -538,7 +540,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx) } if (ib) { - struct nouveau_bo *bo = nouveau_bo(ib); + struct nouveau_bo *bo = nvfx_resource(ib)->bo; so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2); so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c index 2d243be16a3..3547cad6aeb 100644 --- a/src/gallium/drivers/nvfx/nvfx_vertprog.c +++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c @@ -833,12 +833,13 @@ out_err: static boolean nvfx_vertprog_validate(struct nvfx_context *nvfx) { - struct pipe_screen *pscreen = nvfx->pipe.screen; + struct pipe_context *pipe = &nvfx->pipe; struct nvfx_screen *screen = nvfx->screen; struct nouveau_channel *chan = screen->base.channel; struct nouveau_grobj *eng3d = screen->eng3d; struct nvfx_vertex_program *vp; - struct pipe_buffer *constbuf; + struct pipe_resource *constbuf; + struct pipe_transfer *transfer; boolean upload_code = FALSE, upload_data = FALSE; int i; @@ -962,8 +963,9 @@ check_gpu_resources: float *map = NULL; if (constbuf) { - map = pipe_buffer_map(pscreen, constbuf, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe, constbuf, + PIPE_TRANSFER_READ, + &transfer); } for (i = 0; i < vp->nr_consts; i++) { @@ -984,7 +986,7 @@ check_gpu_resources: } if (constbuf) - pipe_buffer_unmap(pscreen, constbuf); + pipe_buffer_unmap(pipe, constbuf, transfer); } /* Upload vtxprog */ diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index a6529b20604..5a8e00f15a2 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -13,6 +13,7 @@ C_SOURCES = \ r300_fs.c \ r300_query.c \ r300_render.c \ + r300_resource.c \ r300_screen.c \ r300_screen_buffer.c \ r300_state.c \ diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index bcdf950df9c..b99879afdd3 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -137,8 +137,8 @@ void r300_surface_copy(struct pipe_context* pipe, if (!pipe->screen->is_format_supported(pipe->screen, old_format, src->texture->target, - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_SAMPLER, 0)) { + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW, 0)) { switch (util_format_get_blocksize(old_format)) { case 1: new_format = PIPE_FORMAT_I8_UNORM; diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 55850e09c3b..490f77341fc 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -47,7 +47,7 @@ static void r300_destroy_context(struct pipe_context* context) draw_destroy(r300->draw); /* Free the OQ BO. */ - context->screen->buffer_destroy(r300->oqbo); + context->screen->resource_destroy(context->screen, r300->oqbo); /* If there are any queries pending or not destroyed, remove them now. */ foreach_s(query, temp, &r300->query_list) { @@ -70,25 +70,6 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300); } -static unsigned int -r300_is_texture_referenced(struct pipe_context *context, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - struct r300_context* r300 = r300_context(context); - struct r300_texture* tex = r300_texture(texture); - - return r300->rws->is_buffer_referenced(r300->rws, tex->buffer); -} - -static unsigned int -r300_is_buffer_referenced(struct pipe_context *context, - struct pipe_buffer *buf) -{ - struct r300_context* r300 = r300_context(context); - - return r300_buffer_is_referenced(r300, buf); -} static void r300_flush_cb(void *data) { @@ -201,23 +182,17 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, draw_set_viewport_state(r300->draw, &r300_viewport_identity); } - r300->context.is_texture_referenced = r300_is_texture_referenced; - r300->context.is_buffer_referenced = r300_is_buffer_referenced; - r300_setup_atoms(r300); /* Open up the OQ BO. */ - r300->oqbo = screen->buffer_create(screen, 4096, - PIPE_BUFFER_USAGE_PIXEL, 4096); + r300->oqbo = pipe_buffer_create(screen, + R300_BIND_OQBO, 4096); make_empty_list(&r300->query_list); r300_init_flush_functions(r300); - r300_init_query_functions(r300); - - r300_init_transfer_functions(r300); - r300_init_state_functions(r300); + r300_init_resource_functions(r300); r300->invariant_state.dirty = TRUE; @@ -226,16 +201,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->blitter = util_blitter_create(&r300->context); - r300->upload_ib = u_upload_create(screen, + r300->upload_ib = u_upload_create(&r300->context, 32 * 1024, 16, - PIPE_BUFFER_USAGE_INDEX); + PIPE_BIND_INDEX_BUFFER); if (r300->upload_ib == NULL) goto no_upload_ib; - r300->upload_vb = u_upload_create(screen, + r300->upload_vb = u_upload_create(&r300->context, 128 * 1024, 16, - PIPE_BUFFER_USAGE_VERTEX); + PIPE_BIND_VERTEX_BUFFER); if (r300->upload_vb == NULL) goto no_upload_vb; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index be01db5b448..8d770853a46 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -29,6 +29,7 @@ #include "pipe/p_context.h" #include "util/u_inlines.h" +#include "util/u_transfer.h" #include "r300_defines.h" #include "r300_screen.h" @@ -228,7 +229,7 @@ struct r300_query { struct r300_texture { /* Parent class */ - struct pipe_texture tex; + struct u_resource b; /* Offsets into the buffer. */ unsigned offset[R300_MAX_TEXTURE_LEVELS]; @@ -305,7 +306,7 @@ struct r300_context { unsigned mode, unsigned count); void (*emit_draw_elements)( - struct r300_context *r300, struct pipe_buffer* indexBuffer, + struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, unsigned mode, unsigned start, unsigned count); @@ -320,12 +321,12 @@ struct r300_context { struct blitter_context* blitter; /* Vertex buffer for rendering. */ - struct pipe_buffer* vbo; + struct pipe_resource* vbo; /* Offset into the VBO. */ size_t vbo_offset; /* Occlusion query buffer. */ - struct pipe_buffer* oqbo; + struct pipe_resource* oqbo; /* Query list. */ struct r300_query *query_current; struct r300_query query_list; @@ -411,7 +412,7 @@ struct r300_context { }; /* Convenience cast wrapper. */ -static INLINE struct r300_texture* r300_texture(struct pipe_texture* tex) +static INLINE struct r300_texture* r300_texture(struct pipe_resource* tex) { return (struct r300_texture*)tex; } @@ -428,8 +429,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, /* Context initialization. */ struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_state_functions(struct r300_context* r300); -void r300_init_surface_functions(struct r300_context* r300); -void r300_init_tex_functions( struct pipe_context *pipe ); +void r300_init_resource_functions(struct r300_context* r300); static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags) { diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h index 2e04876de92..1cc8a8674fd 100644 --- a/src/gallium/drivers/r300/r300_defines.h +++ b/src/gallium/drivers/r300/r300_defines.h @@ -28,7 +28,7 @@ #define R300_MAX_TEXTURE_LEVELS 13 #define R300_MAX_DRAW_VBO_SIZE (1024 * 1024) -#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM +#define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV /* Non-atom dirty state flags. */ #define R300_NEW_FRAGMENT_SHADER 0x00000020 diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 79988a0caa6..350c538ebc5 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -145,7 +145,7 @@ static const float * get_shader_constant( struct r300_viewport_state* viewport = r300->viewport_state.state; struct r300_textures_state* texstate = r300->textures_state.state; static float vec[4] = { 0.0, 0.0, 0.0, 1.0 }; - struct pipe_texture *tex; + struct pipe_resource *tex; switch(constant->Type) { case RC_CONSTANT_EXTERNAL: @@ -973,7 +973,7 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi void r300_emit_buffer_validate(struct r300_context *r300, boolean do_validate_vertex_buffers, - struct pipe_buffer *index_buffer) + struct pipe_resource *index_buffer) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; @@ -982,7 +982,7 @@ void r300_emit_buffer_validate(struct r300_context *r300, struct r300_texture* tex; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->velems->velem; - struct pipe_buffer *pbuf; + struct pipe_resource *pbuf; unsigned i; boolean invalid = FALSE; diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 7db2fc6a1a1..27251a60abd 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -102,6 +102,6 @@ void r300_emit_dirty_state(struct r300_context* r300); void r300_emit_buffer_validate(struct r300_context *r300, boolean do_validate_vertex_buffers, - struct pipe_buffer *index_buffer); + struct pipe_resource *index_buffer); #endif /* R300_EMIT_H */ diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index bc40fcfb5ba..3348a0ada61 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -78,17 +78,17 @@ static void r300_destroy_query(struct pipe_context* pipe, static void r300_begin_query(struct pipe_context* pipe, struct pipe_query* query) { - uint32_t* map; + uint32_t value = ~0U; struct r300_context* r300 = r300_context(pipe); struct r300_query* q = (struct r300_query*)query; assert(r300->query_current == NULL); - map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, - PIPE_BUFFER_USAGE_CPU_WRITE); - map += q->offset / 4; - *map = ~0U; - pipe->screen->buffer_unmap(pipe->screen, r300->oqbo); + pipe_buffer_write(pipe, + r300->oqbo, + q->offset, + sizeof value, + &value); q->flushed = FALSE; r300->query_current = q; @@ -114,7 +114,8 @@ static boolean r300_get_query_result(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); struct r300_screen* r300screen = r300->screen; struct r300_query *q = (struct r300_query*)query; - unsigned flags = PIPE_BUFFER_USAGE_CPU_READ; + struct pipe_transfer *transfer; + unsigned flags = PIPE_TRANSFER_READ; uint32_t* map; uint32_t temp = 0; unsigned i, num_results; @@ -122,10 +123,10 @@ static boolean r300_get_query_result(struct pipe_context* pipe, if (q->flushed == FALSE) pipe->flush(pipe, 0, NULL); if (!wait) { - flags |= PIPE_BUFFER_USAGE_DONTBLOCK; + flags |= PIPE_TRANSFER_DONTBLOCK; } - map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, flags); + map = pipe_buffer_map(pipe, r300->oqbo, flags, &transfer); if (!map) return FALSE; map += q->offset / 4; @@ -148,7 +149,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe, temp += *map; map++; } - pipe->screen->buffer_unmap(pipe->screen, r300->oqbo); + pipe_buffer_unmap(pipe, r300->oqbo, transfer); if (temp == ~0U) { /* Our results haven't been written yet... */ diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 09355569fb8..44da7aa3777 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -152,7 +152,9 @@ static boolean immd_is_good_idea(struct r300_context *r300, if (!checked[vbi]) { vbuf = &r300->vertex_buffer[vbi]; - if (r300_buffer_is_referenced(r300, vbuf->buffer)) { + if (r300->context.is_resource_referenced(&r300->context, + vbuf->buffer, + 0, 0)) { /* It's a very bad idea to map it... */ return FALSE; } @@ -192,6 +194,7 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300, /* Mapped vertex buffers. */ uint32_t* map[PIPE_MAX_ATTRIBS] = {0}; + struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {NULL}; CS_LOCALS(r300); @@ -206,9 +209,10 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300, /* Map the buffer. */ if (!map[vbi]) { vbuf = &r300->vertex_buffer[vbi]; - map[vbi] = (uint32_t*)pipe_buffer_map(r300->context.screen, + map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context, vbuf->buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &transfer[vbi]); map[vbi] += vbuf->buffer_offset / 4; stride[vbi] = vbuf->stride / 4; } @@ -251,7 +255,7 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300, if (map[vbi]) { vbuf = &r300->vertex_buffer[vbi]; - pipe_buffer_unmap(r300->context.screen, vbuf->buffer); + pipe_buffer_unmap(&r300->context, vbuf->buffer, transfer[vbi]); map[vbi] = NULL; } } @@ -288,7 +292,7 @@ void r500_emit_draw_arrays(struct r300_context *r300, } void r500_emit_draw_elements(struct r300_context *r300, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -428,7 +432,7 @@ void r300_emit_draw_arrays(struct r300_context *r300, } void r300_emit_draw_elements(struct r300_context *r300, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -451,24 +455,24 @@ void r300_emit_draw_elements(struct r300_context *r300, } static void r300_shorten_ubyte_elts(struct r300_context* r300, - struct pipe_buffer** elts, + struct pipe_resource** elts, unsigned start, unsigned count) { + struct pipe_context* context = &r300->context; struct pipe_screen* screen = r300->context.screen; - struct pipe_buffer* new_elts; + struct pipe_resource* new_elts; unsigned char *in_map; unsigned short *out_map; + struct pipe_transfer *src_transfer, *dst_transfer; unsigned i; - new_elts = screen->buffer_create(screen, 32, - PIPE_BUFFER_USAGE_INDEX | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ, - 2 * count); + new_elts = pipe_buffer_create(screen, + PIPE_BIND_INDEX_BUFFER, + 2 * count); - in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); - out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); + in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer); + out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); in_map += start; @@ -478,41 +482,43 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300, out_map++; } - pipe_buffer_unmap(screen, *elts); - pipe_buffer_unmap(screen, new_elts); + pipe_buffer_unmap(context, *elts, src_transfer); + pipe_buffer_unmap(context, new_elts, dst_transfer); *elts = new_elts; } static void r300_align_ushort_elts(struct r300_context *r300, - struct pipe_buffer **elts, + struct pipe_resource **elts, unsigned start, unsigned count) { - struct pipe_screen* screen = r300->context.screen; - struct pipe_buffer* new_elts; + struct pipe_context* context = &r300->context; + struct pipe_transfer *in_transfer = NULL; + struct pipe_transfer *out_transfer = NULL; + struct pipe_resource* new_elts; unsigned short *in_map; unsigned short *out_map; - new_elts = screen->buffer_create(screen, 32, - PIPE_BUFFER_USAGE_INDEX | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ, - 2 * count); + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + 2 * count); - in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); - out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); + in_map = pipe_buffer_map(context, *elts, + PIPE_TRANSFER_READ, &in_transfer); + out_map = pipe_buffer_map(context, new_elts, + PIPE_TRANSFER_WRITE, &out_transfer); memcpy(out_map, in_map+start, 2 * count); - pipe_buffer_unmap(screen, *elts); - pipe_buffer_unmap(screen, new_elts); + pipe_buffer_unmap(context, *elts, in_transfer); + pipe_buffer_unmap(context, new_elts, out_transfer); *elts = new_elts; } /* This is the fast-path drawing & emission for HW TCL. */ void r300_draw_range_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -521,7 +527,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, unsigned count) { struct r300_context* r300 = r300_context(pipe); - struct pipe_buffer* orgIndexBuffer = indexBuffer; + struct pipe_resource* orgIndexBuffer = indexBuffer; #if defined(ENABLE_ALT_NUM_VERTS) boolean alt_num_verts = r300->screen->caps.is_r500 && count > 65536; @@ -581,13 +587,13 @@ void r300_draw_range_elements(struct pipe_context* pipe, } if (indexBuffer != orgIndexBuffer) { - pipe_buffer_reference( &indexBuffer, NULL ); + pipe_resource_reference( &indexBuffer, NULL ); } } /* Simple helpers for context setup. Should probably be moved to util. */ void r300_draw_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { @@ -665,6 +671,7 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, unsigned count) { struct r300_context* r300 = r300_context(pipe); + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; int i; if (r300->skip_rendering) { @@ -676,9 +683,10 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, } for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe->screen, + void* buf = pipe_buffer_map(pipe, r300->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, buf); } @@ -687,14 +695,15 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, draw_arrays(r300->draw, mode, start, count); for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer); + pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, + vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, NULL); } } /* SW TCL elements, using Draw. */ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -703,6 +712,8 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, unsigned count) { struct r300_context* r300 = r300_context(pipe); + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *ib_transfer; int i; void* indices; @@ -715,25 +726,28 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, } for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe->screen, + void* buf = pipe_buffer_map(pipe, r300->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, buf); } - indices = pipe_buffer_map(pipe->screen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + indices = pipe_buffer_map(pipe, indexBuffer, + PIPE_TRANSFER_READ, &ib_transfer); draw_set_mapped_element_buffer_range(r300->draw, indexSize, minIndex, maxIndex, indices); draw_arrays(r300->draw, mode, start, count); for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer); + pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, + vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, NULL); } - pipe_buffer_unmap(pipe->screen, indexBuffer); + pipe_buffer_unmap(pipe, indexBuffer, + ib_transfer); draw_set_mapped_element_buffer_range(r300->draw, 0, start, start + count - 1, NULL); } @@ -752,11 +766,13 @@ struct r300_render { unsigned hwprim; /* VBO */ - struct pipe_buffer* vbo; + struct pipe_resource* vbo; size_t vbo_size; size_t vbo_offset; size_t vbo_max_used; void * vbo_ptr; + + struct pipe_transfer *vbo_transfer; }; static INLINE struct r300_render* @@ -787,10 +803,9 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, if (size + r300render->vbo_offset > r300render->vbo_size) { - pipe_buffer_reference(&r300->vbo, NULL); + pipe_resource_reference(&r300->vbo, NULL); r300render->vbo = pipe_buffer_create(screen, - 64, - PIPE_BUFFER_USAGE_VERTEX, + PIPE_BIND_VERTEX_BUFFER, R300_MAX_DRAW_VBO_SIZE); r300render->vbo_offset = 0; r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE; @@ -806,10 +821,11 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, static void* r300_render_map_vertices(struct vbuf_render* render) { struct r300_render* r300render = r300_render(render); - struct pipe_screen* screen = r300render->r300->context.screen; - r300render->vbo_ptr = pipe_buffer_map(screen, r300render->vbo, - PIPE_BUFFER_USAGE_CPU_WRITE); + r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context, + r300render->vbo, + PIPE_TRANSFER_WRITE, + &r300render->vbo_transfer); return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); } @@ -819,7 +835,7 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, ushort max) { struct r300_render* r300render = r300_render(render); - struct pipe_screen* screen = r300render->r300->context.screen; + struct pipe_context* context = &r300render->r300->context; CS_LOCALS(r300render->r300); BEGIN_CS(2); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max); @@ -827,7 +843,7 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, r300render->vbo_max_used = MAX2(r300render->vbo_max_used, r300render->vertex_size * (max + 1)); - pipe_buffer_unmap(screen, r300render->vbo); + pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer); } static void r300_render_release_vertices(struct vbuf_render* render) diff --git a/src/gallium/drivers/r300/r300_render.h b/src/gallium/drivers/r300/r300_render.h index 870e1fb53d1..b8307c84d3d 100644 --- a/src/gallium/drivers/r300/r300_render.h +++ b/src/gallium/drivers/r300/r300_render.h @@ -35,7 +35,7 @@ void r500_emit_draw_arrays(struct r300_context *r300, unsigned count); void r500_emit_draw_elements(struct r300_context *r300, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -53,7 +53,7 @@ void r300_emit_draw_arrays(struct r300_context *r300, unsigned count); void r300_emit_draw_elements(struct r300_context *r300, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -62,7 +62,7 @@ void r300_emit_draw_elements(struct r300_context *r300, unsigned count); void r300_draw_range_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -71,7 +71,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, unsigned count); void r300_draw_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); @@ -84,7 +84,7 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, unsigned count); void r300_swtcl_draw_range_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, + struct pipe_resource* indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c new file mode 100644 index 00000000000..84e3fdd1379 --- /dev/null +++ b/src/gallium/drivers/r300/r300_resource.c @@ -0,0 +1,92 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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. + * + * Authors: Dave Airlie + */ +#include <stdio.h> + +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" +#include "util/u_upload_mgr.h" +#include "util/u_math.h" + +#include "r300_context.h" +#include "r300_texture.h" +#include "r300_transfer.h" +#include "r300_screen.h" +#include "r300_state_inlines.h" +#include "r300_screen_buffer.h" + +#include "r300_winsys.h" + + + + +static struct pipe_resource * +r300_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return r300_buffer_create(screen, template); + else + return r300_texture_create(screen, template); + +} + +static struct pipe_resource * +r300_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return r300_texture_from_handle(screen, template, whandle); +} + + + +void +r300_init_resource_functions(struct r300_context *r300) +{ + r300->context.get_transfer = u_get_transfer_vtbl; + r300->context.transfer_map = u_transfer_map_vtbl; + r300->context.transfer_flush_region = u_transfer_flush_region_vtbl; + r300->context.transfer_unmap = u_transfer_unmap_vtbl; + r300->context.transfer_destroy = u_transfer_destroy_vtbl; + r300->context.transfer_inline_write = u_transfer_inline_write_vtbl; + r300->context.is_resource_referenced = u_is_resource_referenced_vtbl; +} + +void +r300_init_screen_resource_functions(struct r300_screen *r300screen) +{ + r300screen->screen.resource_create = r300_resource_create; + r300screen->screen.resource_from_handle = r300_resource_from_handle; + r300screen->screen.resource_get_handle = u_resource_get_handle_vtbl; + r300screen->screen.resource_destroy = u_resource_destroy_vtbl; + r300screen->screen.user_buffer_create = r300_user_buffer_create; + + r300screen->screen.get_tex_surface = r300_get_tex_surface; + r300screen->screen.tex_surface_destroy = r300_tex_surface_destroy; +} diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 00c16b86623..2eae5756e32 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -218,7 +218,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, } /* Check sampler format support. */ - if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) && + if ((usage & PIPE_BIND_SAMPLER_VIEW) && /* Z24 cannot be sampled from on non-r5xx. */ (is_r500 || !is_z24) && /* ATI1N is r5xx-only. */ @@ -226,28 +226,28 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* ATI2N is supported on r4xx-r5xx. */ (is_r400 || is_r500 || !is_ati2n) && r300_is_sampler_format_supported(format)) { - retval |= PIPE_TEXTURE_USAGE_SAMPLER; + retval |= PIPE_BIND_SAMPLER_VIEW; } /* Check colorbuffer format support. */ - if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) && + if ((usage & (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) && /* 2101010 cannot be rendered to on non-r5xx. */ (is_r500 || !is_color2101010) && r300_is_colorbuffer_format_supported(format)) { retval |= usage & - (PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED); + (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED); } /* Check depth-stencil format support. */ - if (usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL && + if (usage & PIPE_BIND_DEPTH_STENCIL && r300_is_zs_format_supported(format)) { - retval |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + retval |= PIPE_BIND_DEPTH_STENCIL; } return retval == usage; @@ -314,9 +314,8 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) r300screen->screen.fence_signalled = r300_fence_signalled; r300screen->screen.fence_finish = r300_fence_finish; - r300_init_screen_texture_functions(&r300screen->screen); + r300_init_screen_resource_functions(r300screen); - r300_screen_init_buffer_functions(r300screen); return &r300screen->screen; } diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 159805840d9..2f951c7097c 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -89,5 +89,7 @@ static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags, void r300_init_debug(struct r300_screen* ctx); +void r300_init_screen_resource_functions(struct r300_screen *r300screen); + #endif /* R300_SCREEN_H */ diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index a1cd48ee730..cb47ba16882 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -34,23 +34,31 @@ #include "r300_winsys.h" -boolean r300_buffer_is_referenced(struct r300_context *r300, - struct pipe_buffer *buf) +static unsigned r300_buffer_is_referenced(struct pipe_context *context, + struct pipe_resource *buf, + unsigned face, unsigned level) { + struct r300_context *r300 = r300_context(context); struct r300_buffer *rbuf = r300_buffer(buf); + if (r300_buffer_is_user_buffer(buf)) - return FALSE; + return PIPE_UNREFERENCED; + + if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf)) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; - return r300->rws->is_buffer_referenced(r300->rws, rbuf->buf); - + return PIPE_UNREFERENCED; } + +/* External helper, not required to implent u_resource_vtbl: + */ int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, + struct pipe_resource **index_buffer, unsigned index_size, unsigned start, unsigned count) { - struct pipe_buffer *upload_buffer = NULL; + struct pipe_resource *upload_buffer = NULL; unsigned index_offset = start * index_size; int ret = 0; @@ -68,10 +76,12 @@ int r300_upload_index_buffer(struct r300_context *r300, } done: // if (upload_buffer) - // pipe_buffer_reference(&upload_buffer, NULL); + // pipe_resource_reference(&upload_buffer, NULL); return ret; } +/* External helper, not required to implent u_resource_vtbl: + */ int r300_upload_user_buffers(struct r300_context *r300) { enum pipe_error ret = PIPE_OK; @@ -82,9 +92,9 @@ int r300_upload_user_buffers(struct r300_context *r300) for (i = 0; i < nr; i++) { if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { - struct pipe_buffer *upload_buffer = NULL; + struct pipe_resource *upload_buffer = NULL; unsigned offset = 0; /*r300->vertex_buffer[i].buffer_offset * 4;*/ - unsigned size = r300->vertex_buffer[i].buffer->size; + unsigned size = r300->vertex_buffer[i].buffer->width0; unsigned upload_offset; ret = u_upload_buffer(r300->upload_vb, offset, size, @@ -93,7 +103,7 @@ int r300_upload_user_buffers(struct r300_context *r300) if (ret) return ret; - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); + pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL); r300->vertex_buffer[i].buffer = upload_buffer; r300->vertex_buffer[i].buffer_offset = upload_offset; } @@ -125,70 +135,11 @@ static void r300_winsys_buffer_destroy(struct r300_screen *r300screen, } } -static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto error1; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = alignment; - rbuf->base.usage = usage; - rbuf->base.size = size; - rbuf->buf = r300_winsys_buffer_create(r300screen, - alignment, - usage, - size); - - if (!rbuf->buf) - goto error2; - - return &rbuf->base; -error2: - FREE(rbuf); -error1: - return NULL; -} - - -static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) +static void r300_buffer_destroy(struct pipe_screen *screen, + struct pipe_resource *buf) { - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto no_rbuf; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = 1; - rbuf->base.usage = 0; - rbuf->base.size = bytes; - - rbuf->user_buffer = ptr; - return &rbuf->base; - -no_rbuf: - return NULL; -} - -static void r300_buffer_destroy(struct pipe_buffer *buf) -{ - struct r300_screen *r300screen = r300_screen(buf->screen); + struct r300_screen *r300screen = r300_screen(screen); struct r300_buffer *rbuf = r300_buffer(buf); r300_winsys_buffer_destroy(r300screen, rbuf); @@ -197,7 +148,7 @@ static void r300_buffer_destroy(struct pipe_buffer *buf) static void * r300_buffer_map_range(struct pipe_screen *screen, - struct pipe_buffer *buf, + struct pipe_resource *buf, unsigned offset, unsigned length, unsigned usage ) { @@ -211,11 +162,12 @@ r300_buffer_map_range(struct pipe_screen *screen, if (rbuf->user_buffer) return rbuf->user_buffer; - if (rbuf->base.usage & PIPE_BUFFER_USAGE_CONSTANT) + if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { goto just_map; + } /* check if the mapping is to a range we already flushed */ - if (usage & PIPE_BUFFER_USAGE_DISCARD) { + if (usage & PIPE_TRANSFER_DISCARD) { for (i = 0; i < rbuf->num_ranges; i++) { if ((offset >= rbuf->ranges[i].start) && @@ -229,9 +181,9 @@ r300_buffer_map_range(struct pipe_screen *screen, rbuf->num_ranges = 0; rbuf->map = NULL; rbuf->buf = r300_winsys_buffer_create(r300screen, - rbuf->base.alignment, - rbuf->base.usage, - rbuf->base.size); + 16, + rbuf->b.b.bind, /* XXX */ + rbuf->b.b.width0); break; } } @@ -244,7 +196,7 @@ just_map: static void r300_buffer_flush_mapped_range( struct pipe_screen *screen, - struct pipe_buffer *buf, + struct pipe_resource *buf, unsigned offset, unsigned length ) { @@ -254,7 +206,7 @@ r300_buffer_flush_mapped_range( struct pipe_screen *screen, if (rbuf->user_buffer) return; - if (rbuf->base.usage & PIPE_BUFFER_USAGE_CONSTANT) + if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) return; /* mark the range as used */ @@ -271,44 +223,152 @@ r300_buffer_flush_mapped_range( struct pipe_screen *screen, rbuf->num_ranges++; } -static void * -r300_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned usage) + +static void +r300_buffer_unmap(struct pipe_screen *screen, + struct pipe_resource *buf) { struct r300_screen *r300screen = r300_screen(screen); struct r300_winsys_screen *rws = r300screen->rws; struct r300_buffer *rbuf = r300_buffer(buf); - void *map; - if (rbuf->user_buffer) - return rbuf->user_buffer; + if (rbuf->buf) { + rws->buffer_unmap(rws, rbuf->buf); + } +} - map = rws->buffer_map(rws, rbuf->buf, usage); - return map; + + +/* As a first step, keep the original code intact, implement buffer + * transfers in terms of the old map/unmap functions. + * + * Utility functions for transfer create/destroy are hooked in and + * just record the arguments to those functions. + */ +static void * +r300_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + uint8_t *map = r300_buffer_map_range( pipe->screen, + transfer->resource, + transfer->box.x, + transfer->box.width, + transfer->usage ); + if (map == NULL) + return NULL; + + /* map_buffer() returned a pointer to the beginning of the buffer, + * but transfers are expected to return a pointer to just the + * region specified in the box. + */ + return map + transfer->box.x; } -static void -r300_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) + + +static void r300_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + assert(box->x + box->width <= transfer->box.width); + + r300_buffer_flush_mapped_range(pipe->screen, + transfer->resource, + transfer->box.x + box->x, + box->width); +} + +static void r300_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + r300_buffer_unmap(pipe->screen, + transfer->resource); +} + + + + +struct u_resource_vtbl r300_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + r300_buffer_destroy, /* resource_destroy */ + r300_buffer_is_referenced, /* is_buffer_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + r300_buffer_transfer_map, /* transfer_map */ + r300_buffer_transfer_flush_region, /* transfer_flush_region */ + r300_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + + +struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template) { struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); + struct r300_buffer *rbuf; + unsigned alignment = 16; - if (rbuf->buf) { - rws->buffer_unmap(rws, rbuf->buf); - } + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto error1; + + rbuf->magic = R300_BUFFER_MAGIC; + + rbuf->b.b = *template; + rbuf->b.vtbl = &r300_buffer_vtbl; + pipe_reference_init(&rbuf->b.b.reference, 1); + rbuf->b.b.screen = screen; + + if (rbuf->b.b.bind & R300_BIND_OQBO) + alignment = 4096; + + rbuf->buf = r300_winsys_buffer_create(r300screen, + alignment, + rbuf->b.b.bind, + rbuf->b.b.width0); + + if (!rbuf->buf) + goto error2; + + return &rbuf->b.b; +error2: + FREE(rbuf); +error1: + return NULL; } -void r300_screen_init_buffer_functions(struct r300_screen *r300screen) + +struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind) { - r300screen->screen.buffer_create = r300_buffer_create; - r300screen->screen.user_buffer_create = r300_user_buffer_create; - r300screen->screen.buffer_map = r300_buffer_map; - r300screen->screen.buffer_map_range = r300_buffer_map_range; - r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range; - r300screen->screen.buffer_unmap = r300_buffer_unmap; - r300screen->screen.buffer_destroy = r300_buffer_destroy; + struct r300_buffer *rbuf; + + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto no_rbuf; + + rbuf->magic = R300_BUFFER_MAGIC; + + pipe_reference_init(&rbuf->b.b.reference, 1); + rbuf->b.vtbl = &r300_buffer_vtbl; + rbuf->b.b.screen = screen; + rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; + rbuf->b.b._usage = PIPE_USAGE_IMMUTABLE; + rbuf->b.b.bind = bind; + rbuf->b.b.width0 = bytes; + rbuf->b.b.height0 = 1; + rbuf->b.b.depth0 = 1; + + rbuf->user_buffer = ptr; + return &rbuf->b.b; + +no_rbuf: + return NULL; } + diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h index 0cf349c25cd..93009ea02fd 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -3,6 +3,7 @@ #include <stdio.h> #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "util/u_transfer.h" #include "r300_screen.h" #include "r300_winsys.h" @@ -18,7 +19,7 @@ struct r300_buffer_range { struct r300_buffer { - struct pipe_buffer base; + struct u_resource b; uint32_t magic; @@ -32,7 +33,7 @@ struct r300_buffer }; static INLINE struct r300_buffer * -r300_buffer(struct pipe_buffer *buffer) +r300_buffer(struct pipe_resource *buffer) { if (buffer) { assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); @@ -42,13 +43,13 @@ r300_buffer(struct pipe_buffer *buffer) } static INLINE boolean -r300_buffer_is_user_buffer(struct pipe_buffer *buffer) +r300_buffer_is_user_buffer(struct pipe_resource *buffer) { return r300_buffer(buffer)->user_buffer ? true : false; } static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws, - struct pipe_buffer *buffer, + struct pipe_resource *buffer, int rd, int wr) { struct r300_buffer *buf = r300_buffer(buffer); @@ -67,7 +68,6 @@ static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws, return rws->add_buffer(rws, tex->buffer, rd, wr); } -void r300_screen_init_buffer_functions(struct r300_screen *r300screen); static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws, struct r300_buffer *buf, @@ -89,11 +89,18 @@ static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws, int r300_upload_user_buffers(struct r300_context *r300); int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, + struct pipe_resource **index_buffer, unsigned index_size, unsigned start, unsigned count); -boolean r300_buffer_is_referenced(struct r300_context *r300, - struct pipe_buffer *buf); + +struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template); + +struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + #endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 65498339833..52b89104b99 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1019,7 +1019,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, static struct pipe_sampler_view * r300_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -1028,7 +1028,7 @@ r300_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -1039,7 +1039,7 @@ static void r300_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } @@ -1133,7 +1133,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, vbo = (struct pipe_vertex_buffer*)&buffers[i]; /* Reference our buffer. */ - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer); + pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer); /* Skip NULL buffers */ if (!buffers[i].buffer) { @@ -1147,7 +1147,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, if (vbo->max_index == ~0) { /* Bogus value from broken state tracker; hax it. */ vbo->max_index = - (vbo->buffer->size - vbo->buffer_offset) / vbo->stride; + (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; } max_index = MIN2(vbo->max_index, max_index); @@ -1155,7 +1155,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, for (; i < r300->vertex_buffer_count; i++) { /* Dereference any old buffers. */ - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); + pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL); } memcpy(r300->vertex_buffer, buffers, @@ -1344,20 +1344,21 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) static void r300_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_resource *buf) { struct r300_context* r300 = r300_context(pipe); + struct pipe_transfer *tr; void *mapped; int max_size = 0; - if (buf == NULL || buf->size == 0 || - (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) + if (buf == NULL || buf->width0 == 0 || + (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL) { r300->shader_constants[shader].count = 0; return; } - assert((buf->size % 4 * sizeof(float)) == 0); + assert((buf->width0 % 4 * sizeof(float)) == 0); /* Check the size of the constant buffer. */ switch (shader) { @@ -1379,15 +1380,15 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, } /* XXX Subtract immediates and RC_STATE_* variables. */ - if (buf->size > (sizeof(float) * 4 * max_size)) { + if (buf->width0 > (sizeof(float) * 4 * max_size)) { fprintf(stderr, "r300: Max size of the constant buffer is " "%i*4 floats.\n", max_size); abort(); } - memcpy(r300->shader_constants[shader].constants, mapped, buf->size); - r300->shader_constants[shader].count = buf->size / (4 * sizeof(float)); - pipe_buffer_unmap(pipe->screen, buf); + memcpy(r300->shader_constants[shader].constants, mapped, buf->width0); + r300->shader_constants[shader].count = buf->width0 / (4 * sizeof(float)); + pipe_buffer_unmap(pipe, buf, tr); if (shader == PIPE_SHADER_VERTEX) { if (r300->screen->caps.has_tcl) { @@ -1396,7 +1397,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, } else if (r300->draw) { draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, - buf->size); + buf->width0); } } else if (shader == PIPE_SHADER_FRAGMENT) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index b9d3718f1c9..ae54d06372f 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -473,7 +473,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) tex = r300_texture(view->texture); sampler = state->sampler_states[i]; - assert(view->format == tex->tex.format); + assert(view->format == tex->b.b.format); texstate = &state->regs[i]; memcpy(texstate->format, &tex->state, sizeof(uint32_t)*3); @@ -484,7 +484,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) R300_TXO_MICRO_TILE(tex->microtile); /* to emulate 1D textures through 2D ones correctly */ - if (tex->tex.target == PIPE_TEXTURE_1D) { + if (tex->b.b.target == PIPE_TEXTURE_1D) { texstate->filter[0] &= ~R300_TX_WRAP_T_MASK; texstate->filter[0] |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } @@ -497,7 +497,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) /* determine min/max levels */ /* the MAX_MIP level is the largest (finest) one */ max_level = MIN3(sampler->max_lod + view->first_level, - tex->tex.last_level, view->last_level); + tex->b.b.last_level, view->last_level); min_level = MIN2(sampler->min_lod + view->first_level, max_level); texstate->format[0] |= R300_TX_NUM_LEVELS(max_level); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 8e5afc5082e..60ea763dfae 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -29,6 +29,7 @@ #include "r300_context.h" #include "r300_texture.h" +#include "r300_transfer.h" #include "r300_screen.h" #include "r300_winsys.h" @@ -513,7 +514,7 @@ boolean r300_is_sampler_format_supported(enum pipe_format format) static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_format_state* state = &tex->state; - struct pipe_texture *pt = &tex->tex; + struct pipe_resource *pt = &tex->b.b; unsigned i; boolean is_r500 = screen->caps.is_r500; @@ -554,28 +555,28 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex pt->width0, pt->height0, pt->last_level); /* Set framebuffer state. */ - if (util_format_is_depth_or_stencil(tex->tex.format)) { - for (i = 0; i <= tex->tex.last_level; i++) { + if (util_format_is_depth_or_stencil(tex->b.b.format)) { + for (i = 0; i <= tex->b.b.last_level; i++) { tex->fb_state.depthpitch[i] = tex->pitch[i] | R300_DEPTHMACROTILE(tex->mip_macrotile[i]) | R300_DEPTHMICROTILE(tex->microtile); } - tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format); + tex->fb_state.zb_format = r300_translate_zsformat(tex->b.b.format); } else { - for (i = 0; i <= tex->tex.last_level; i++) { + for (i = 0; i <= tex->b.b.last_level; i++) { tex->fb_state.colorpitch[i] = tex->pitch[i] | - r300_translate_colorformat(tex->tex.format) | + r300_translate_colorformat(tex->b.b.format) | R300_COLOR_TILE(tex->mip_macrotile[i]) | R300_COLOR_MICROTILE(tex->microtile); } - tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format); + tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->b.b.format); } } void r300_texture_reinterpret_format(struct pipe_screen *screen, - struct pipe_texture *tex, + struct pipe_resource *tex, enum pipe_format new_format) { struct r300_screen *r300screen = r300_screen(screen); @@ -593,7 +594,7 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, { unsigned offset = tex->offset[level]; - switch (tex->tex.target) { + switch (tex->b.b.target) { case PIPE_TEXTURE_3D: assert(face == 0); return offset + zslice * tex->layer_size[level]; @@ -617,7 +618,7 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex, { unsigned pixsize, tile_size; - pixsize = util_format_get_blocksize(tex->tex.format); + pixsize = util_format_get_blocksize(tex->b.b.format); tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim]; if (macrotile) { @@ -638,9 +639,9 @@ static boolean r300_texture_macro_switch(struct r300_texture *tex, tile = r300_texture_get_tile_size(tex, dim, TRUE); if (dim == TILE_WIDTH) { - texdim = u_minify(tex->tex.width0, level); + texdim = u_minify(tex->b.b.width0, level); } else { - texdim = u_minify(tex->tex.height0, level); + texdim = u_minify(tex->b.b.height0, level); } /* See TX_FILTER1_n.MACRO_SWITCH. */ @@ -664,22 +665,22 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, return tex->stride_override; /* Check the level. */ - if (level > tex->tex.last_level) { + if (level > tex->b.b.last_level) { SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", - __FUNCTION__, level, tex->tex.last_level); + __FUNCTION__, level, tex->b.b.last_level); return 0; } - width = u_minify(tex->tex.width0, level); + width = u_minify(tex->b.b.width0, level); - if (r300_format_is_plain(tex->tex.format)) { + if (r300_format_is_plain(tex->b.b.format)) { tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, tex->mip_macrotile[level]); width = align(width, tile_width); - return util_format_get_stride(tex->tex.format, width); + return util_format_get_stride(tex->b.b.format, width); } else { - return align(util_format_get_stride(tex->tex.format, width), 32); + return align(util_format_get_stride(tex->b.b.format, width), 32); } } @@ -688,9 +689,9 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, { unsigned height, tile_height; - height = u_minify(tex->tex.height0, level); + height = u_minify(tex->b.b.height0, level); - if (r300_format_is_plain(tex->tex.format)) { + if (r300_format_is_plain(tex->b.b.format)) { tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT, tex->mip_macrotile[level]); height = align(height, tile_height); @@ -699,13 +700,13 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, height = util_next_power_of_two(height); } - return util_format_get_nblocksy(tex->tex.format, height); + return util_format_get_nblocksy(tex->b.b.format, height); } static void r300_setup_miptree(struct r300_screen* screen, struct r300_texture* tex) { - struct pipe_texture* base = &tex->tex; + struct pipe_resource* base = &tex->b.b; unsigned stride, size, layer_size, nblocksy, i; boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_RV350; @@ -744,8 +745,8 @@ static void r300_setup_miptree(struct r300_screen* screen, static void r300_setup_flags(struct r300_texture* tex) { - tex->uses_pitch = !util_is_power_of_two(tex->tex.width0) || - !util_is_power_of_two(tex->tex.height0) || + tex->uses_pitch = !util_is_power_of_two(tex->b.b.width0) || + !util_is_power_of_two(tex->b.b.height0) || tex->stride_override; } @@ -753,15 +754,15 @@ static void r300_setup_tiling(struct pipe_screen *screen, struct r300_texture *tex) { struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - enum pipe_format format = tex->tex.format; + enum pipe_format format = tex->b.b.format; boolean rv350_mode = r300_screen(screen)->caps.family >= CHIP_FAMILY_RV350; if (!r300_format_is_plain(format)) { return; } - if (tex->tex.width0 == 1 || - tex->tex.height0 == 1) { + if (tex->b.b.width0 == 1 || + tex->b.b.height0 == 1) { return; } @@ -787,9 +788,73 @@ static void r300_setup_tiling(struct pipe_screen *screen, } } + +static unsigned r300_texture_is_referenced(struct pipe_context *context, + struct pipe_resource *texture, + unsigned face, unsigned level) +{ + struct r300_context *r300 = r300_context(context); + struct r300_texture *rtex = (struct r300_texture *)texture; + + if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer)) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + + return PIPE_UNREFERENCED; +} + +static void r300_texture_destroy(struct pipe_screen *screen, + struct pipe_resource* texture) +{ + struct r300_texture* tex = (struct r300_texture*)texture; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; + + rws->buffer_reference(rws, &tex->buffer, NULL); + FREE(tex); +} + + + + +static boolean + r300_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) +{ + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; + struct r300_texture* tex = (struct r300_texture*)texture; + unsigned stride; + + if (!tex) { + return FALSE; + } + + stride = r300_texture_get_stride(r300_screen(screen), tex, 0); + + rws->buffer_get_handle(rws, tex->buffer, stride, whandle); + + return TRUE; +} + + + +struct u_resource_vtbl r300_texture_vtbl = +{ + r300_texture_get_handle, /* get_handle */ + r300_texture_destroy, /* resource_destroy */ + r300_texture_is_referenced, /* is_resource_referenced */ + r300_texture_get_transfer, /* get_transfer */ + r300_texture_transfer_destroy, /* transfer_destroy */ + r300_texture_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + r300_texture_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + /* Create a new texture. */ -static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, - const struct pipe_texture* base) +struct pipe_resource* r300_texture_create(struct pipe_screen* screen, + const struct pipe_resource* base) { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); @@ -799,20 +864,21 @@ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, return NULL; } - tex->tex = *base; - pipe_reference_init(&tex->tex.reference, 1); - tex->tex.screen = screen; + tex->b.b = *base; + tex->b.vtbl = &r300_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; r300_setup_flags(tex); - if (!(base->tex_usage & R300_TEXTURE_USAGE_TRANSFER) && - !(base->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)) { + if (!(base->flags & R300_RESOURCE_FLAG_TRANSFER) && + !(base->bind & PIPE_BIND_SCANOUT)) { r300_setup_tiling(screen, tex); } r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); tex->buffer = rws->buffer_create(rws, 2048, - PIPE_BUFFER_USAGE_PIXEL, + PIPE_BIND_SAMPLER_VIEW, /* XXX */ tex->size); rws->buffer_set_tiling(rws, tex->buffer, tex->pitch[0], @@ -824,24 +890,19 @@ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, return NULL; } - return (struct pipe_texture*)tex; + return (struct pipe_resource*)tex; } -static void r300_texture_destroy(struct pipe_texture* texture) -{ - struct r300_texture* tex = r300_texture(texture); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; - rws->buffer_reference(rws, &tex->buffer, NULL); - FREE(tex); -} -static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, - struct pipe_texture* texture, - unsigned face, - unsigned level, - unsigned zslice, - unsigned flags) +/* Not required to implement u_resource_vtbl, consider moving to another file: + */ +struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, + struct pipe_resource* texture, + unsigned face, + unsigned level, + unsigned zslice, + unsigned flags) { struct r300_texture* tex = r300_texture(texture); struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface); @@ -851,7 +912,7 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, if (surface) { pipe_reference_init(&surface->reference, 1); - pipe_texture_reference(&surface->texture, texture); + pipe_resource_reference(&surface->texture, texture); surface->format = texture->format; surface->width = u_minify(texture->width0, level); surface->height = u_minify(texture->height0, level); @@ -866,17 +927,18 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, return surface; } -static void r300_tex_surface_destroy(struct pipe_surface* s) +/* Not required to implement u_resource_vtbl, consider moving to another file: + */ +void r300_tex_surface_destroy(struct pipe_surface* s) { - pipe_texture_reference(&s->texture, NULL); + pipe_resource_reference(&s->texture, NULL); FREE(s); } - -static struct pipe_texture* - r300_texture_from_handle(struct pipe_screen* screen, - const struct pipe_texture* base, - struct winsys_handle *whandle) +struct pipe_resource* +r300_texture_from_handle(struct pipe_screen* screen, + const struct pipe_resource* base, + struct winsys_handle *whandle) { struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys; struct r300_screen* rscreen = r300_screen(screen); @@ -902,9 +964,10 @@ static struct pipe_texture* return NULL; } - tex->tex = *base; - pipe_reference_init(&tex->tex.reference, 1); - tex->tex.screen = screen; + tex->b.b = *base; + tex->b.vtbl = &r300_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; tex->stride_override = stride; @@ -945,109 +1008,6 @@ static struct pipe_texture* tex->microtile, tex->macrotile); } - return (struct pipe_texture*)tex; -} - -static boolean - r300_texture_get_handle(struct pipe_screen* screen, - struct pipe_texture *texture, - struct winsys_handle *whandle) -{ - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - struct r300_texture* tex = r300_texture(texture); - unsigned stride; - - if (!tex) { - return FALSE; - } - - stride = r300_texture_get_stride(r300_screen(screen), tex, 0); - - rws->buffer_get_handle(rws, tex->buffer, stride, whandle); - - return TRUE; + return (struct pipe_resource*)tex; } -static struct pipe_video_surface * -r300_video_surface_create(struct pipe_screen *screen, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) -{ - struct r300_video_surface *r300_vsfc; - struct pipe_texture base; - - assert(screen); - assert(width && height); - - r300_vsfc = CALLOC_STRUCT(r300_video_surface); - if (!r300_vsfc) - return NULL; - - pipe_reference_init(&r300_vsfc->base.reference, 1); - r300_vsfc->base.screen = screen; - r300_vsfc->base.chroma_format = chroma_format; - r300_vsfc->base.width = width; - r300_vsfc->base.height = height; - - memset(&base, 0, sizeof(struct pipe_texture)); - base.target = PIPE_TEXTURE_2D; - base.format = PIPE_FORMAT_B8G8R8X8_UNORM; - base.last_level = 0; - base.width0 = util_next_power_of_two(width); - base.height0 = util_next_power_of_two(height); - base.depth0 = 1; - base.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | - PIPE_TEXTURE_USAGE_RENDER_TARGET; - - r300_vsfc->tex = screen->texture_create(screen, &base); - if (!r300_vsfc->tex) - { - FREE(r300_vsfc); - return NULL; - } - - return &r300_vsfc->base; -} - -static void r300_video_surface_destroy(struct pipe_video_surface *vsfc) -{ - struct r300_video_surface *r300_vsfc = r300_video_surface(vsfc); - pipe_texture_reference(&r300_vsfc->tex, NULL); - FREE(r300_vsfc); -} - -void r300_init_screen_texture_functions(struct pipe_screen* screen) -{ - screen->texture_create = r300_texture_create; - screen->texture_from_handle = r300_texture_from_handle; - screen->texture_get_handle = r300_texture_get_handle; - screen->texture_destroy = r300_texture_destroy; - screen->get_tex_surface = r300_get_tex_surface; - screen->tex_surface_destroy = r300_tex_surface_destroy; - - screen->video_surface_create = r300_video_surface_create; - screen->video_surface_destroy= r300_video_surface_destroy; -} - -boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, - unsigned* stride) -{ - struct r300_texture* tex = r300_texture(texture); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - struct r300_winsys_buffer *buf; - - if (!tex) { - return FALSE; - } - - rws->buffer_reference(rws, &buf, tex->buffer); - - if (stride) { - *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); - } - - *buffer = buf; - return TRUE; -} diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 60c7fa83420..a545a0f2212 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -23,15 +23,12 @@ #ifndef R300_TEXTURE_H #define R300_TEXTURE_H -#include "pipe/p_video_state.h" #include "util/u_format.h" #include "r300_reg.h" struct r300_texture; -void r300_init_screen_texture_functions(struct pipe_screen* screen); - unsigned r300_texture_get_stride(struct r300_screen* screen, struct r300_texture* tex, unsigned level); @@ -39,7 +36,7 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, unsigned zslice, unsigned face); void r300_texture_reinterpret_format(struct pipe_screen *screen, - struct pipe_texture *tex, + struct pipe_resource *tex, enum pipe_format new_format); boolean r300_is_colorbuffer_format_supported(enum pipe_format format); @@ -48,23 +45,24 @@ boolean r300_is_zs_format_supported(enum pipe_format format); boolean r300_is_sampler_format_supported(enum pipe_format format); -struct r300_video_surface -{ - struct pipe_video_surface base; - struct pipe_texture *tex; -}; - -static INLINE struct r300_video_surface * -r300_video_surface(struct pipe_video_surface *pvs) -{ - return (struct r300_video_surface *)pvs; -} - -/* Used internally for texture_is_referenced() - */ -boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture *texture, - struct r300_winsys_buffer** buffer, - unsigned* stride); + +struct pipe_resource* +r300_texture_from_handle(struct pipe_screen* screen, + const struct pipe_resource* base, + struct winsys_handle *whandle); + +struct pipe_resource* +r300_texture_create(struct pipe_screen* screen, + const struct pipe_resource* template); + + +struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, + struct pipe_resource* texture, + unsigned face, + unsigned level, + unsigned zslice, + unsigned flags); + +void r300_tex_surface_destroy(struct pipe_surface* s); #endif /* R300_TEXTURE_H */ diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 3cc86bad382..8dc705a7d4f 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -38,9 +38,6 @@ struct r300_transfer { /* Pipe context. */ struct pipe_context *ctx; - /* Parameters of get_tex_transfer. */ - unsigned x, y, level, zslice, face; - /* Offset from start of buffer. */ unsigned offset; @@ -48,7 +45,7 @@ struct r300_transfer { struct r300_texture *detiled_texture; /* Transfer and format flags. */ - unsigned buffer_usage, render_target_usage; + unsigned render_target_usage; }; /* Convenience cast wrapper. */ @@ -64,22 +61,22 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx, { struct pipe_screen *screen = ctx->screen; struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; - struct pipe_texture *tex = transfer->texture; + struct pipe_resource *tex = transfer->resource; struct pipe_surface *src, *dst; - src = screen->get_tex_surface(screen, tex, r300transfer->face, - r300transfer->level, r300transfer->zslice, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_PIXEL); + src = screen->get_tex_surface(screen, tex, + transfer->sr.face, + transfer->sr.level, + transfer->box.z, + PIPE_BIND_BLIT_SOURCE); - dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex, + dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE | - PIPE_BUFFER_USAGE_PIXEL | - r300transfer->buffer_usage); + PIPE_BIND_BLIT_DESTINATION); - ctx->surface_copy(ctx, dst, 0, 0, src, r300transfer->x, r300transfer->y, - transfer->width, transfer->height); + ctx->surface_copy(ctx, dst, 0, 0, src, + transfer->box.x, transfer->box.y, + transfer->box.width, transfer->box.height); pipe_surface_reference(&src, NULL); pipe_surface_reference(&dst, NULL); @@ -91,26 +88,28 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, { struct pipe_screen *screen = ctx->screen; struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; - struct pipe_texture *tex = transfer->texture; + struct pipe_resource *tex = transfer->resource; struct pipe_surface *src, *dst; - src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex, + src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_PIXEL); + PIPE_BIND_BLIT_SOURCE); - dst = screen->get_tex_surface(screen, tex, r300transfer->face, - r300transfer->level, r300transfer->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE | - PIPE_BUFFER_USAGE_PIXEL); + dst = screen->get_tex_surface(screen, tex, + transfer->sr.face, + transfer->sr.level, + transfer->box.z, + PIPE_BIND_BLIT_DESTINATION); /* XXX this flush prevents the following DRM error from occuring: * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation ! * Reproducible with perf/copytex. */ ctx->flush(ctx, 0, NULL); - ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0, - transfer->width, transfer->height); + ctx->surface_copy(ctx, dst, + transfer->box.x, transfer->box.y, + src, 0, 0, + transfer->box.width, transfer->box.height); /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */ ctx->flush(ctx, 0, NULL); @@ -119,72 +118,71 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, pipe_surface_reference(&dst, NULL); } -static struct pipe_transfer* -r300_get_tex_transfer(struct pipe_context *ctx, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, unsigned x, unsigned y, - unsigned w, unsigned h) +struct pipe_transfer* +r300_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct r300_texture *tex = r300_texture(texture); struct r300_screen *r300screen = r300_screen(ctx->screen); struct r300_transfer *trans; - struct pipe_texture base; + struct pipe_resource base; trans = CALLOC_STRUCT(r300_transfer); if (trans) { /* Initialize the transfer object. */ - pipe_texture_reference(&trans->transfer.texture, texture); + pipe_resource_reference(&trans->transfer.resource, texture); + trans->transfer.sr = sr; trans->transfer.usage = usage; - trans->transfer.width = w; - trans->transfer.height = h; + trans->transfer.box = *box; trans->ctx = ctx; - trans->x = x; - trans->y = y; - trans->level = level; - trans->zslice = zslice; - trans->face = face; /* If the texture is tiled, we must create a temporary detiled texture * for this transfer. */ if (tex->microtile || tex->macrotile) { - trans->buffer_usage = pipe_transfer_buffer_flags(&trans->transfer); trans->render_target_usage = util_format_is_depth_or_stencil(texture->format) ? - PIPE_TEXTURE_USAGE_DEPTH_STENCIL : - PIPE_TEXTURE_USAGE_RENDER_TARGET; + PIPE_BIND_DEPTH_STENCIL : + PIPE_BIND_RENDER_TARGET; base.target = PIPE_TEXTURE_2D; base.format = texture->format; - base.width0 = w; - base.height0 = h; + base.width0 = box->width; + base.height0 = box->height; base.depth0 = 0; base.last_level = 0; base.nr_samples = 0; - base.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - R300_TEXTURE_USAGE_TRANSFER; + base._usage = PIPE_USAGE_DYNAMIC; + base.flags = R300_RESOURCE_FLAG_TRANSFER; /* For texture reading, the temporary (detiled) texture is used as * a render target when blitting from a tiled texture. */ if (usage & PIPE_TRANSFER_READ) { - base.tex_usage |= trans->render_target_usage; + base.bind |= trans->render_target_usage; } /* For texture writing, the temporary texture is used as a sampler * when blitting into a tiled texture. */ if (usage & PIPE_TRANSFER_WRITE) { - base.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER; + base.bind |= PIPE_BIND_SAMPLER_VIEW; } /* Create the temporary texture. */ trans->detiled_texture = r300_texture( - ctx->screen->texture_create(ctx->screen, - &base)); + ctx->screen->resource_create(ctx->screen, + &base)); assert(!trans->detiled_texture->microtile && !trans->detiled_texture->macrotile); /* Set the stride. - * Parameters x, y, level, zslice, and face remain zero. */ + * + * Even though we are using an internal texture for this, + * the transfer sr, box and usage parameters still reflect + * the arguments received to get_transfer. We just do the + * right thing internally. + */ trans->transfer.stride = r300_texture_get_stride(r300screen, trans->detiled_texture, 0); @@ -194,21 +192,16 @@ r300_get_tex_transfer(struct pipe_context *ctx, r300_copy_from_tiled_texture(ctx, trans); } } else { - trans->transfer.x = x; - trans->transfer.y = y; trans->transfer.stride = - r300_texture_get_stride(r300screen, tex, level); - trans->transfer.level = level; - trans->transfer.zslice = zslice; - trans->transfer.face = face; - trans->offset = r300_texture_get_offset(tex, level, zslice, face); + r300_texture_get_stride(r300screen, tex, sr.level); + trans->offset = r300_texture_get_offset(tex, sr.level, box->z, sr.face); } } return &trans->transfer; } -static void r300_tex_transfer_destroy(struct pipe_context *ctx, - struct pipe_transfer *trans) +void r300_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans) { struct r300_transfer *r300transfer = r300_transfer(trans); @@ -217,49 +210,49 @@ static void r300_tex_transfer_destroy(struct pipe_context *ctx, r300_copy_into_tiled_texture(r300transfer->ctx, r300transfer); } - pipe_texture_reference( - (struct pipe_texture**)&r300transfer->detiled_texture, NULL); + pipe_resource_reference( + (struct pipe_resource**)&r300transfer->detiled_texture, NULL); } - pipe_texture_reference(&trans->texture, NULL); + pipe_resource_reference(&trans->resource, NULL); FREE(trans); } -static void* r300_transfer_map(struct pipe_context *ctx, - struct pipe_transfer *transfer) +void* r300_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer *transfer) { struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys; struct r300_transfer *r300transfer = r300_transfer(transfer); - struct r300_texture *tex = r300_texture(transfer->texture); + struct r300_texture *tex = r300_texture(transfer->resource); char *map; - enum pipe_format format = tex->tex.format; + enum pipe_format format = tex->b.b.format; if (r300transfer->detiled_texture) { /* The detiled texture is of the same size as the region being mapped * (no offset needed). */ return rws->buffer_map(rws, r300transfer->detiled_texture->buffer, - pipe_transfer_buffer_flags(transfer)); + transfer->usage); } else { /* Tiling is disabled. */ map = rws->buffer_map(rws, tex->buffer, - pipe_transfer_buffer_flags(transfer)); + transfer->usage); if (!map) { return NULL; } return map + r300_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } } -static void r300_transfer_unmap(struct pipe_context *ctx, - struct pipe_transfer *transfer) +void r300_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer *transfer) { struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys; struct r300_transfer *r300transfer = r300_transfer(transfer); - struct r300_texture *tex = r300_texture(transfer->texture); + struct r300_texture *tex = r300_texture(transfer->resource); if (r300transfer->detiled_texture) { rws->buffer_unmap(rws, r300transfer->detiled_texture->buffer); @@ -268,13 +261,3 @@ static void r300_transfer_unmap(struct pipe_context *ctx, } } - -void r300_init_transfer_functions( struct r300_context *r300ctx ) -{ - struct pipe_context *ctx = &r300ctx->context; - - ctx->get_tex_transfer = r300_get_tex_transfer; - ctx->tex_transfer_destroy = r300_tex_transfer_destroy; - ctx->transfer_map = r300_transfer_map; - ctx->transfer_unmap = r300_transfer_unmap; -} diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h index 79baf6d0480..d72e54e5ed9 100644 --- a/src/gallium/drivers/r300/r300_transfer.h +++ b/src/gallium/drivers/r300/r300_transfer.h @@ -28,6 +28,24 @@ struct r300_context; -void r300_init_transfer_functions(struct r300_context *r300ctx); +struct pipe_transfer* +r300_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box); + +void +r300_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans); + +void* +r300_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer *transfer); + +void +r300_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer *transfer); + #endif diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index d8d0c609d25..80abaef4ba7 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -39,11 +39,12 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws); struct r300_winsys_buffer; +/* XXX: this is just a bandaid on larger problems in + * r300_screen_buffer.h which doesn't seem to be fully ported to + * gallium-resources. + */ +#define R300_BIND_OQBO (1<<21) -boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, - unsigned *stride); enum r300_value_id { R300_VID_PCI_ID, @@ -100,7 +101,7 @@ struct r300_winsys_screen { unsigned offset, unsigned length); - /* Add a pipe_buffer to the list of buffer objects to validate. */ + /* Add a pipe_resource to the list of buffer objects to validate. */ boolean (*add_buffer)(struct r300_winsys_screen *winsys, struct r300_winsys_buffer *buf, uint32_t rd, diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 239655d628b..83f3e4a19b6 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -6,7 +6,6 @@ LIBNAME = softpipe C_SOURCES = \ sp_fs_exec.c \ sp_fs_sse.c \ - sp_buffer.c \ sp_clear.c \ sp_fence.c \ sp_flush.c \ @@ -33,7 +32,6 @@ C_SOURCES = \ sp_tex_sample.c \ sp_tex_tile_cache.c \ sp_tile_cache.c \ - sp_surface.c \ - sp_video_context.c + sp_surface.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 9949a53adfd..b80c6dea93a 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -7,7 +7,6 @@ softpipe = env.ConvenienceLibrary( source = [ 'sp_fs_exec.c', 'sp_fs_sse.c', - 'sp_buffer.c', 'sp_clear.c', 'sp_context.c', 'sp_draw_arrays.c', @@ -35,7 +34,6 @@ softpipe = env.ConvenienceLibrary( 'sp_tex_tile_cache.c', 'sp_texture.c', 'sp_tile_cache.c', - 'sp_video_context.c' ]) Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c deleted file mode 100644 index 8f390250869..00000000000 --- a/src/gallium/drivers/softpipe/sp_buffer.c +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 VMWARE AND/OR ITS 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 "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "sp_screen.h" -#include "sp_buffer.h" - - -static void * -softpipe_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned flags) -{ - struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf); - return softpipe_buf->data; -} - - -static void -softpipe_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ -} - - -static void -softpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct softpipe_buffer *sbuf = softpipe_buffer(buf); - - if (!sbuf->userBuffer) - align_free(sbuf->data); - - FREE(sbuf); -} - - -static struct pipe_buffer * -softpipe_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.alignment = MAX2(alignment, 16); - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -softpipe_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct softpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(softpipe_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -void -softpipe_init_screen_buffer_funcs(struct pipe_screen *screen) -{ - screen->buffer_create = softpipe_buffer_create; - screen->user_buffer_create = softpipe_user_buffer_create; - screen->buffer_map = softpipe_buffer_map; - screen->buffer_unmap = softpipe_buffer_unmap; - screen->buffer_destroy = softpipe_buffer_destroy; -} diff --git a/src/gallium/drivers/softpipe/sp_buffer.h b/src/gallium/drivers/softpipe/sp_buffer.h deleted file mode 100644 index 9d8e56a176b..00000000000 --- a/src/gallium/drivers/softpipe/sp_buffer.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 VMWARE AND/OR ITS 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. - * - **************************************************************************/ - -#ifndef SP_BUFFER_H -#define SP_BUFFER_H - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - - -struct softpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; -}; - - -/** Cast wrapper */ -static INLINE struct softpipe_buffer * -softpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct softpipe_buffer *)buf; -} - - -void -softpipe_init_screen_buffer_funcs(struct pipe_screen *screen); - - -#endif /* SP_BUFFER_H */ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 937a573092f..d0c2978c246 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -117,7 +117,7 @@ softpipe_destroy( struct pipe_context *pipe ) for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { if (softpipe->constants[i][j]) { - pipe_buffer_reference(&softpipe->constants[i][j], NULL); + pipe_resource_reference(&softpipe->constants[i][j], NULL); } } } @@ -135,13 +135,16 @@ softpipe_destroy( struct pipe_context *pipe ) * return PIPE_UNREFERENCED */ static unsigned int -softpipe_is_texture_referenced( struct pipe_context *pipe, - struct pipe_texture *texture, +softpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, unsigned face, unsigned level) { struct softpipe_context *softpipe = softpipe_context( pipe ); unsigned i; + if (texture->target == PIPE_BUFFER) + return PIPE_UNREFERENCED; + /* check if any of the bound drawing surfaces are this texture */ if (softpipe->dirty_render_cache) { for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { @@ -172,12 +175,6 @@ softpipe_is_texture_referenced( struct pipe_context *pipe, } -static unsigned int -softpipe_is_buffer_referenced( struct pipe_context *pipe, - struct pipe_buffer *buf) -{ - return PIPE_UNREFERENCED; -} static void @@ -274,8 +271,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; - softpipe->pipe.is_texture_referenced = softpipe_is_texture_referenced; - softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced; + softpipe->pipe.is_resource_referenced = softpipe_is_resource_referenced; softpipe_init_query_funcs( softpipe ); softpipe_init_texture_funcs( &softpipe->pipe ); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 75e03c8ae6b..be8f2cb3e04 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -66,7 +66,7 @@ struct softpipe_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; + struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 7b77eb239fd..461c9a6c4d4 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -39,7 +39,7 @@ #include "sp_context.h" #include "sp_query.h" #include "sp_state.h" -#include "sp_buffer.h" +#include "sp_texture.h" #include "draw/draw_context.h" @@ -55,7 +55,7 @@ */ static void softpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -85,7 +85,7 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, void softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -106,7 +106,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe, void softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { @@ -144,7 +144,7 @@ softpipe_draw_arrays_instanced(struct pipe_context *pipe, void softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, @@ -166,7 +166,7 @@ softpipe_draw_elements_instanced(struct pipe_context *pipe, static void softpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -193,13 +193,13 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, /* Map vertex buffers */ for (i = 0; i < sp->num_vertex_buffers; i++) { - void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data; + void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = softpipe_buffer(indexBuffer)->data; + void *mapped_indexes = softpipe_resource(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, minIndex, diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index be64048abfc..7b1e058ac83 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -36,7 +36,6 @@ #include "sp_texture.h" #include "sp_screen.h" #include "sp_context.h" -#include "sp_buffer.h" #include "sp_fence.h" #include "sp_public.h" @@ -174,9 +173,9 @@ softpipe_is_format_supported( struct pipe_screen *screen, break; } - if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if(tex_usage & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } @@ -209,7 +208,7 @@ softpipe_flush_frontbuffer(struct pipe_screen *_screen, { struct softpipe_screen *screen = softpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; - struct softpipe_texture *texture = softpipe_texture(surface->texture); + struct softpipe_resource *texture = softpipe_resource(surface->texture); assert(texture->dt); if (texture->dt) @@ -244,7 +243,6 @@ softpipe_create_screen(struct sw_winsys *winsys) util_format_s3tc_init(); softpipe_init_screen_texture_funcs(&screen->base); - softpipe_init_screen_buffer_funcs(&screen->base); softpipe_init_screen_fence_funcs(&screen->base); return &screen->base; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index ade96b0fd4c..3c04c8bb07e 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -150,7 +150,7 @@ void softpipe_set_clip_state( struct pipe_context *, void softpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, - struct pipe_buffer *buf); + struct pipe_resource *buf); void *softpipe_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -188,7 +188,7 @@ softpipe_set_vertex_sampler_views(struct pipe_context *, struct pipe_sampler_view * softpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ); void @@ -210,12 +210,12 @@ void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); void softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); void softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -231,7 +231,7 @@ softpipe_draw_arrays_instanced(struct pipe_context *pipe, void softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index d2eda7324ca..4c6d4909f5b 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -202,7 +202,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[i]; if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); + struct softpipe_resource *spt = softpipe_resource(tc->texture); if (spt->timestamp != tc->timestamp) { sp_tex_tile_cache_validate_texture( tc ); /* @@ -217,7 +217,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) struct softpipe_tex_tile_cache *tc = softpipe->vertex_tex_cache[i]; if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); + struct softpipe_resource *spt = softpipe_resource(tc->texture); if (spt->timestamp != tc->timestamp) { sp_tex_tile_cache_validate_texture(tc); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index d6f3229bed7..7f072f5a269 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -28,7 +28,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" -#include "sp_buffer.h" +#include "sp_texture.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -167,11 +167,11 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) void softpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *constants) + struct pipe_resource *constants) { struct softpipe_context *softpipe = softpipe_context(pipe); - unsigned size = constants ? constants->size : 0; - const void *data = constants ? softpipe_buffer(constants)->data : NULL; + unsigned size = constants ? constants->width0 : 0; + const void *data = constants ? softpipe_resource(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -179,7 +179,7 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, draw_flush(softpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&softpipe->constants[shader][index], constants); + pipe_resource_reference(&softpipe->constants[shader][index], constants); if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index d501952bba9..2692f06c927 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -30,6 +30,7 @@ */ #include "util/u_memory.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" #include "draw/draw_context.h" @@ -123,7 +124,7 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, struct pipe_sampler_view * softpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *resource, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -132,7 +133,7 @@ softpipe_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, resource); view->context = pipe; } @@ -144,7 +145,7 @@ void softpipe_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } @@ -223,10 +224,10 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe, static struct sp_sampler_varient * get_sampler_varient( unsigned unit, struct sp_sampler *sampler, - struct pipe_texture *texture, + struct pipe_resource *resource, unsigned processor ) { - struct softpipe_texture *sp_texture = softpipe_texture(texture); + struct softpipe_resource *sp_texture = softpipe_resource(resource); struct sp_sampler_varient *v = NULL; union sp_sampler_key key; @@ -274,7 +275,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) */ for (i = 0; i <= softpipe->vs->max_sampler; i++) { if (softpipe->vertex_samplers[i]) { - struct pipe_texture *texture = NULL; + struct pipe_resource *texture = NULL; if (softpipe->vertex_sampler_views[i]) { texture = softpipe->vertex_sampler_views[i]->texture; @@ -294,7 +295,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { if (softpipe->sampler[i]) { - struct pipe_texture *texture = NULL; + struct pipe_resource *texture = NULL; if (softpipe->sampler_views[i]) { texture = softpipe->sampler_views[i]->texture; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index fa9e19b282b..ff83c66d8b2 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -547,7 +547,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float rho = MAX2(dsdx, dsdy) * texture->width0; @@ -562,7 +562,7 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -581,7 +581,7 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -651,7 +651,7 @@ static INLINE const float * get_texel_2d(const struct sp_sampler_varient *samp, union tex_tile_address addr, int x, int y) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level = addr.bits.level; if (x < 0 || x >= (int) u_minify(texture->width0, level) || @@ -744,7 +744,7 @@ static INLINE const float * get_texel_3d(const struct sp_sampler_varient *samp, union tex_tile_address addr, int x, int y, int z) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level = addr.bits.level; if (x < 0 || x >= (int) u_minify(texture->width0, level) || @@ -932,7 +932,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; int x[4]; @@ -968,7 +968,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; int x[4], y[4]; @@ -1016,7 +1016,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1056,7 +1056,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; int x[4], y[4], z[4]; @@ -1098,7 +1098,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; int x0[4], x1[4]; @@ -1138,7 +1138,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; int x0[4], y0[4], x1[4], y1[4]; @@ -1185,7 +1185,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1234,7 +1234,7 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; @@ -1310,7 +1310,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1373,7 +1373,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float lambda; float lod[QUAD_SIZE]; @@ -1461,7 +1461,7 @@ mip_filter_linear_2d_linear_repeat_POT( float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1867,7 +1867,7 @@ get_img_filter(const union sp_sampler_key key, void sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, struct softpipe_tex_tile_cache *tex_cache, - const struct pipe_texture *texture ) + const struct pipe_resource *texture ) { const struct pipe_sampler_state *sampler = samp->sampler; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index b6e66c998ae..6114acf7371 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -85,7 +85,7 @@ struct sp_sampler_varient /* Currently bound texture: */ - const struct pipe_texture *texture; + const struct pipe_resource *texture; struct softpipe_tex_tile_cache *cache; unsigned processor; @@ -129,7 +129,7 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, void sp_sampler_varient_bind_texture( struct sp_sampler_varient *varient, struct softpipe_tex_tile_cache *tex_cache, - const struct pipe_texture *tex ); + const struct pipe_resource *tex ); void sp_sampler_varient_destroy( struct sp_sampler_varient * ); diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index 6594514c38f..c79f5fb05a1 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -69,10 +69,10 @@ sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc) /*assert(tc->entries[pos].x < 0);*/ } if (tc->transfer) { - tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer); + tc->pipe->transfer_destroy(tc->pipe, tc->transfer); } if (tc->tex_trans) { - tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); + tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans); } FREE( tc ); @@ -122,13 +122,13 @@ void sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, struct pipe_sampler_view *view) { - struct pipe_texture *texture = view ? view->texture : NULL; + struct pipe_resource *texture = view ? view->texture : NULL; uint i; assert(!tc->transfer); if (tc->texture != texture) { - pipe_texture_reference(&tc->texture, texture); + pipe_resource_reference(&tc->texture, texture); if (tc->tex_trans) { if (tc->tex_trans_map) { @@ -136,7 +136,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, tc->tex_trans_map = NULL; } - tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); + tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans); tc->tex_trans = NULL; } @@ -239,18 +239,18 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, tc->tex_trans_map = NULL; } - tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); + tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans); tc->tex_trans = NULL; } tc->tex_trans = - tc->pipe->get_tex_transfer(tc->pipe, tc->texture, - addr.bits.face, - addr.bits.level, - addr.bits.z, - PIPE_TRANSFER_READ, 0, 0, - u_minify(tc->texture->width0, addr.bits.level), - u_minify(tc->texture->height0, addr.bits.level)); + pipe_get_transfer(tc->pipe, tc->texture, + addr.bits.face, + addr.bits.level, + addr.bits.z, + PIPE_TRANSFER_READ, 0, 0, + u_minify(tc->texture->width0, addr.bits.level), + u_minify(tc->texture->height0, addr.bits.level)); tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index 12ae7ba12d6..0794ffa0c53 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -74,7 +74,7 @@ struct softpipe_tex_tile_cache struct pipe_transfer *transfer; void *transfer_map; - struct pipe_texture *texture; /**< if caching a texture */ + struct pipe_resource *texture; /**< if caching a texture */ unsigned timestamp; struct softpipe_tex_cached_tile entries[NUM_ENTRIES]; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index f4983b7c8e8..27cc6f27b2e 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -36,6 +36,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_transfer.h" #include "sp_context.h" #include "sp_texture.h" @@ -49,10 +50,10 @@ * Use a simple, maximally packed layout. */ static boolean -softpipe_texture_layout(struct pipe_screen *screen, - struct softpipe_texture * spt) +softpipe_resource_layout(struct pipe_screen *screen, + struct softpipe_resource * spt) { - struct pipe_texture *pt = &spt->base; + struct pipe_resource *pt = &spt->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; @@ -84,14 +85,14 @@ softpipe_texture_layout(struct pipe_screen *screen, */ static boolean softpipe_displaytarget_layout(struct pipe_screen *screen, - struct softpipe_texture * spt) + struct softpipe_resource * spt) { struct sw_winsys *winsys = softpipe_screen(screen)->winsys; /* Round up the surface size to a multiple of the tile size? */ spt->dt = winsys->displaytarget_create(winsys, - spt->base.tex_usage, + spt->base.bind, spt->base.format, spt->base.width0, spt->base.height0, @@ -103,16 +104,18 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /** - * Create new pipe_texture given the template information. + * Create new pipe_resource given the template information. */ -static struct pipe_texture * -softpipe_texture_create(struct pipe_screen *screen, - const struct pipe_texture *template) +static struct pipe_resource * +softpipe_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) { - struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + struct softpipe_resource *spt = CALLOC_STRUCT(softpipe_resource); if (!spt) return NULL; + assert(template->format != PIPE_FORMAT_NONE); + spt->base = *template; pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; @@ -121,14 +124,14 @@ softpipe_texture_create(struct pipe_screen *screen, util_is_power_of_two(template->height0) && util_is_power_of_two(template->depth0)); - if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if (spt->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; } else { - if (!softpipe_texture_layout(screen, spt)) + if (!softpipe_resource_layout(screen, spt)) goto fail; } @@ -141,17 +144,18 @@ softpipe_texture_create(struct pipe_screen *screen, static void -softpipe_texture_destroy(struct pipe_texture *pt) +softpipe_resource_destroy(struct pipe_screen *pscreen, + struct pipe_resource *pt) { - struct softpipe_screen *screen = softpipe_screen(pt->screen); - struct softpipe_texture *spt = softpipe_texture(pt); + struct softpipe_screen *screen = softpipe_screen(pscreen); + struct softpipe_resource *spt = softpipe_resource(pt); if (spt->dt) { /* display target */ struct sw_winsys *winsys = screen->winsys; winsys->displaytarget_destroy(winsys, spt->dt); } - else { + else if (!spt->userBuffer) { /* regular texture */ align_free(spt->data); } @@ -160,13 +164,13 @@ softpipe_texture_destroy(struct pipe_texture *pt) } -static struct pipe_texture * -softpipe_texture_from_handle(struct pipe_screen *screen, - const struct pipe_texture *template, +static struct pipe_resource * +softpipe_resource_from_handle(struct pipe_screen *screen, + const struct pipe_resource *template, struct winsys_handle *whandle) { struct sw_winsys *winsys = softpipe_screen(screen)->winsys; - struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + struct softpipe_resource *spt = CALLOC_STRUCT(softpipe_resource); if (!spt) return NULL; @@ -194,12 +198,12 @@ softpipe_texture_from_handle(struct pipe_screen *screen, static boolean -softpipe_texture_get_handle(struct pipe_screen *screen, - struct pipe_texture *pt, +softpipe_resource_get_handle(struct pipe_screen *screen, + struct pipe_resource *pt, struct winsys_handle *whandle) { struct sw_winsys *winsys = softpipe_screen(screen)->winsys; - struct softpipe_texture *spt = softpipe_texture(pt); + struct softpipe_resource *spt = softpipe_resource(pt); assert(spt->dt); if (!spt->dt) @@ -214,11 +218,11 @@ softpipe_texture_get_handle(struct pipe_screen *screen, */ static struct pipe_surface * softpipe_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage) { - struct softpipe_texture *spt = softpipe_texture(pt); + struct softpipe_resource *spt = softpipe_resource(pt); struct pipe_surface *ps; assert(level <= pt->last_level); @@ -226,33 +230,13 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); ps->offset = spt->level_offset[level]; ps->usage = usage; - /* Because we are softpipe, anything that the state tracker - * thought was going to be done with the GPU will actually get - * done with the CPU. Let's adjust the flags to take that into - * account. - */ - if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - /* GPU_WRITE means "render" and that can involve reads (blending) */ - ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; - } - - if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) - ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; - - if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. The tile cache will look for this. */ - spt->timestamp++; - softpipe_screen(screen)->timestamp++; - } - ps->face = face; ps->level = level; ps->zslice = zslice; @@ -285,7 +269,7 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf) * where it would happen. For softpipe, nothing to do. */ assert(surf->texture); - pipe_texture_reference(&surf->texture, NULL); + pipe_resource_reference(&surf->texture, NULL); FREE(surf); } @@ -303,49 +287,52 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf) * \param height height of region to read/write */ static struct pipe_transfer * -softpipe_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +softpipe_get_transfer(struct pipe_context *pipe, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { - struct softpipe_texture *sptex = softpipe_texture(texture); + struct softpipe_resource *sptex = softpipe_resource(resource); struct softpipe_transfer *spt; - assert(texture); - assert(level <= texture->last_level); + assert(resource); + assert(sr.level <= resource->last_level); /* make sure the requested region is in the image bounds */ - assert(x + w <= u_minify(texture->width0, level)); - assert(y + h <= u_minify(texture->height0, level)); + assert(box->x + box->width <= u_minify(resource->width0, sr.level)); + assert(box->y + box->height <= u_minify(resource->height0, sr.level)); + assert(box->z + box->depth <= u_minify(resource->depth0, sr.level)); spt = CALLOC_STRUCT(softpipe_transfer); if (spt) { struct pipe_transfer *pt = &spt->base; - int nblocksy = util_format_get_nblocksy(texture->format, u_minify(texture->height0, level)); - pipe_texture_reference(&pt->texture, texture); - pt->x = x; - pt->y = y; - pt->width = w; - pt->height = h; - pt->stride = sptex->stride[level]; + enum pipe_format format = resource->format; + int nblocksy = util_format_get_nblocksy(resource->format, + u_minify(resource->height0, sr.level)); + pipe_resource_reference(&pt->resource, resource); + pt->sr = sr; pt->usage = usage; - pt->face = face; - pt->level = level; - pt->zslice = zslice; + pt->box = *box; + pt->stride = sptex->stride[sr.level]; - spt->offset = sptex->level_offset[level]; + spt->offset = sptex->level_offset[sr.level]; - if (texture->target == PIPE_TEXTURE_CUBE) { - spt->offset += face * nblocksy * pt->stride; + if (resource->target == PIPE_TEXTURE_CUBE) { + spt->offset += sr.face * nblocksy * pt->stride; } - else if (texture->target == PIPE_TEXTURE_3D) { - spt->offset += zslice * nblocksy * pt->stride; + else if (resource->target == PIPE_TEXTURE_3D) { + spt->offset += box->z * nblocksy * pt->stride; } else { - assert(face == 0); - assert(zslice == 0); + assert(sr.face == 0); + assert(box->z == 0); } + + spt->offset += + box->y / util_format_get_blockheight(format) * spt->base.stride + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + return pt; } return NULL; @@ -354,18 +341,13 @@ softpipe_get_tex_transfer(struct pipe_context *pipe, /** * Free a pipe_transfer object which was created with - * softpipe_get_tex_transfer(). + * softpipe_get_transfer(). */ static void -softpipe_tex_transfer_destroy(struct pipe_context *pipe, +softpipe_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { - /* Effectively do the texture_update work here - if texture images - * needed post-processing to put them into hardware layout, this is - * where it would happen. For softpipe, nothing to do. - */ - assert (transfer->texture); - pipe_texture_reference(&transfer->texture, NULL); + pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } @@ -377,44 +359,26 @@ static void * softpipe_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { - ubyte *map, *xfer_map; - struct softpipe_texture *spt; - enum pipe_format format; - - assert(transfer->texture); - spt = softpipe_texture(transfer->texture); - format = transfer->texture->format; - - if (spt->dt) { - /* display target */ - struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys; - - map = winsys->displaytarget_map(winsys, spt->dt, - pipe_transfer_buffer_flags(transfer)); - if (map == NULL) - return NULL; + struct softpipe_transfer *sp_transfer = softpipe_transfer(transfer); + struct softpipe_resource *sp_resource = softpipe_resource(transfer->resource); + struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys; + uint8_t *map; + + /* resources backed by display target treated specially: + */ + if (sp_resource->dt) { + map = winsys->displaytarget_map(winsys, + sp_resource->dt, + transfer->usage); } else { - map = spt->data; - if (map == NULL) - return NULL; - } - - /* May want to different things here depending on read/write nature - * of the map: - */ - if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { - /* Do something to notify sharing contexts of a texture change. - * In softpipe, that would mean flushing the texture cache. - */ - softpipe_screen(pipe->screen)->timestamp++; + map = sp_resource->data; } - xfer_map = map + softpipe_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); - /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ - return xfer_map; + if (map == NULL) + return NULL; + else + return map + sp_transfer->offset; } @@ -425,10 +389,10 @@ static void softpipe_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - struct softpipe_texture *spt; + struct softpipe_resource *spt; - assert(transfer->texture); - spt = softpipe_texture(transfer->texture); + assert(transfer->resource); + spt = softpipe_resource(transfer->resource); if (spt->dt) { /* display target */ @@ -442,81 +406,64 @@ softpipe_transfer_unmap(struct pipe_context *pipe, } } - -static struct pipe_video_surface* -softpipe_video_surface_create(struct pipe_screen *screen, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_resource * +softpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags) { - struct softpipe_video_surface *sp_vsfc; - struct pipe_texture template; + struct softpipe_resource *buffer; - assert(screen); - assert(width && height); - - sp_vsfc = CALLOC_STRUCT(softpipe_video_surface); - if (!sp_vsfc) + buffer = CALLOC_STRUCT(softpipe_resource); + if(!buffer) return NULL; - pipe_reference_init(&sp_vsfc->base.reference, 1); - sp_vsfc->base.screen = screen; - sp_vsfc->base.chroma_format = chroma_format; - /*sp_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/ - sp_vsfc->base.width = width; - sp_vsfc->base.height = height; - - memset(&template, 0, sizeof(struct pipe_texture)); - template.target = PIPE_TEXTURE_2D; - template.format = PIPE_FORMAT_B8G8R8X8_UNORM; - template.last_level = 0; - /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */ - template.width0 = util_next_power_of_two(width); - template.height0 = util_next_power_of_two(height); - template.depth0 = 1; - template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; - - sp_vsfc->tex = screen->texture_create(screen, &template); - if (!sp_vsfc->tex) { - FREE(sp_vsfc); - return NULL; - } - - return &sp_vsfc->base; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buffer->base.bind = bind_flags; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.flags = 0; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; } -static void -softpipe_video_surface_destroy(struct pipe_video_surface *vsfc) -{ - struct softpipe_video_surface *sp_vsfc = softpipe_video_surface(vsfc); - pipe_texture_reference(&sp_vsfc->tex, NULL); - FREE(sp_vsfc); -} void softpipe_init_texture_funcs(struct pipe_context *pipe) { - pipe->get_tex_transfer = softpipe_get_tex_transfer; - pipe->tex_transfer_destroy = softpipe_tex_transfer_destroy; + pipe->get_transfer = softpipe_get_transfer; + pipe->transfer_destroy = softpipe_transfer_destroy; pipe->transfer_map = softpipe_transfer_map; pipe->transfer_unmap = softpipe_transfer_unmap; + + pipe->transfer_flush_region = u_default_transfer_flush_region; + pipe->transfer_inline_write = u_default_transfer_inline_write; } void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { - screen->texture_create = softpipe_texture_create; - screen->texture_destroy = softpipe_texture_destroy; - screen->texture_from_handle = softpipe_texture_from_handle; - screen->texture_get_handle = softpipe_texture_get_handle; + screen->resource_create = softpipe_resource_create; + screen->resource_destroy = softpipe_resource_destroy; + screen->resource_from_handle = softpipe_resource_from_handle; + screen->resource_get_handle = softpipe_resource_get_handle; + screen->user_buffer_create = softpipe_user_buffer_create; screen->get_tex_surface = softpipe_get_tex_surface; screen->tex_surface_destroy = softpipe_tex_surface_destroy; - - screen->video_surface_create = softpipe_video_surface_create; - screen->video_surface_destroy = softpipe_video_surface_destroy; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index c0e6ba8a869..500f42fb0fd 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -30,7 +30,6 @@ #include "pipe/p_state.h" -#include "pipe/p_video_state.h" #define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */ @@ -42,27 +41,28 @@ struct pipe_screen; struct softpipe_context; -struct softpipe_texture +struct softpipe_resource { - struct pipe_texture base; + struct pipe_resource base; unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS]; unsigned stride[SP_MAX_TEXTURE_2D_LEVELS]; /** - * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET - * usage. + * Display target, only valid for PIPE_TEXTURE_2D with the + * PIPE_BIND_DISPLAY_TARGET usage. */ struct sw_displaytarget *dt; /** - * Malloc'ed data for regular textures, or a mapping to dt above. + * Malloc'ed data for regular buffers and textures, or a mapping to dt above. */ void *data; /* True if texture images are power-of-two in all dimensions: */ boolean pot; + boolean userBuffer; unsigned timestamp; }; @@ -74,21 +74,13 @@ struct softpipe_transfer unsigned long offset; }; -struct softpipe_video_surface -{ - struct pipe_video_surface base; - - /* The data is held here: - */ - struct pipe_texture *tex; -}; /** cast wrappers */ -static INLINE struct softpipe_texture * -softpipe_texture(struct pipe_texture *pt) +static INLINE struct softpipe_resource * +softpipe_resource(struct pipe_resource *pt) { - return (struct softpipe_texture *) pt; + return (struct softpipe_resource *) pt; } static INLINE struct softpipe_transfer * @@ -97,12 +89,6 @@ softpipe_transfer(struct pipe_transfer *pt) return (struct softpipe_transfer *) pt; } -static INLINE struct softpipe_video_surface * -softpipe_video_surface(struct pipe_video_surface *pvs) -{ - return (struct softpipe_video_surface *) pvs; -} - extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 7551b923fb7..d996c2a3427 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -121,7 +121,7 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc) /*assert(tc->entries[pos].x < 0);*/ } if (tc->transfer) { - tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer); + tc->pipe->transfer_destroy(tc->pipe, tc->transfer); } FREE( tc ); @@ -146,17 +146,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, tc->transfer_map = NULL; } - pipe->tex_transfer_destroy(pipe, tc->transfer); + pipe->transfer_destroy(pipe, tc->transfer); tc->transfer = NULL; } tc->surface = ps; if (ps) { - tc->transfer = pipe->get_tex_transfer(pipe, ps->texture, ps->face, - ps->level, ps->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, ps->width, ps->height); + tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->face, + ps->level, ps->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, ps->width, ps->height); tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || ps->format == PIPE_FORMAT_Z24X8_UNORM || @@ -276,14 +276,14 @@ static void sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; - const uint w = tc->transfer->width; - const uint h = tc->transfer->height; + const uint w = tc->transfer->box.width; + const uint h = tc->transfer->box.height; uint x, y; uint numCleared = 0; - assert(pt->texture); + assert(pt->resource); /* clear the scratch tile to the clear value */ - clear_tile(&tc->tile, pt->texture->format, tc->clear_val); + clear_tile(&tc->tile, pt->resource->format, tc->clear_val); /* push the tile to all positions marked as clear */ for (y = 0; y < h; y += TILE_SIZE) { @@ -372,7 +372,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, if (addr.value != tile->addr.value) { - assert(pt->texture); + assert(pt->resource); if (tile->addr.bits.invalid == 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { @@ -396,10 +396,10 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, if (is_clear_flag_set(tc->clear_flags, addr)) { /* don't get tile from framebuffer, just clear it */ if (tc->depth_stencil) { - clear_tile(tile, pt->texture->format, tc->clear_val); + clear_tile(tile, pt->resource->format, tc->clear_val); } else { - clear_tile_rgba(tile, pt->texture->format, tc->clear_color); + clear_tile_rgba(tile, pt->resource->format, tc->clear_color); } clear_clear_flag(tc->clear_flags, addr); } diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c deleted file mode 100644 index 242aaac4665..00000000000 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ /dev/null @@ -1,304 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * All Rights Reserved. - * - * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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 "util/u_inlines.h" -#include "util/u_memory.h" - -#include "sp_video_context.h" -#include "sp_texture.h" - - -static void -sp_mpeg12_destroy(struct pipe_video_context *vpipe) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - - assert(vpipe); - - /* Asserted in softpipe_delete_fs_state() for some reason */ - ctx->pipe->bind_vs_state(ctx->pipe, NULL); - ctx->pipe->bind_fs_state(ctx->pipe, NULL); - - ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend); - ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast); - ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); - - pipe_video_surface_reference(&ctx->decode_target, NULL); - vl_compositor_cleanup(&ctx->compositor); - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); - - FREE(ctx); -} - -static void -sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe, - struct pipe_video_surface *past, - struct pipe_video_surface *future, - unsigned num_macroblocks, - struct pipe_macroblock *macroblocks, - struct pipe_fence_handle **fence) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks; - - assert(vpipe); - assert(num_macroblocks); - assert(macroblocks); - assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); - assert(ctx->decode_target); - - vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer, - softpipe_video_surface(ctx->decode_target)->tex, - past ? softpipe_video_surface(past)->tex : NULL, - future ? softpipe_video_surface(future)->tex : NULL, - num_macroblocks, mpeg12_macroblocks, fence); -} - -static void -sp_mpeg12_clear_surface(struct pipe_video_context *vpipe, - unsigned x, unsigned y, - unsigned width, unsigned height, - unsigned value, - struct pipe_surface *surface) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - - assert(vpipe); - assert(surface); - - ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); -} - -static void -sp_mpeg12_render_picture(struct pipe_video_context *vpipe, - /*struct pipe_surface *backround, - struct pipe_video_rect *backround_area,*/ - struct pipe_video_surface *src_surface, - enum pipe_mpeg12_picture_type picture_type, - /*unsigned num_past_surfaces, - struct pipe_video_surface *past_surfaces, - unsigned num_future_surfaces, - struct pipe_video_surface *future_surfaces,*/ - struct pipe_video_rect *src_area, - struct pipe_surface *dst_surface, - struct pipe_video_rect *dst_area, - /*unsigned num_layers, - struct pipe_surface *layers, - struct pipe_video_rect *layer_src_areas, - struct pipe_video_rect *layer_dst_areas*/ - struct pipe_fence_handle **fence) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - - assert(vpipe); - assert(src_surface); - assert(src_area); - assert(dst_surface); - assert(dst_area); - - vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex, - picture_type, src_area, dst_surface->texture, dst_area, fence); -} - -static void -sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, - struct pipe_video_surface *dt) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - - assert(vpipe); - assert(dt); - - pipe_video_surface_reference(&ctx->decode_target, dt); -} - -static void sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat) -{ - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - - assert(vpipe); - - vl_compositor_set_csc_matrix(&ctx->compositor, mat); -} - -static bool -init_pipe_state(struct sp_mpeg12_context *ctx) -{ - struct pipe_rasterizer_state rast; - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state dsa; - unsigned i; - - assert(ctx); - - rast.flatshade = 1; - rast.flatshade_first = 0; - rast.light_twoside = 0; - rast.front_winding = PIPE_WINDING_CCW; - rast.cull_mode = PIPE_WINDING_CW; - rast.fill_cw = PIPE_POLYGON_MODE_FILL; - rast.fill_ccw = PIPE_POLYGON_MODE_FILL; - rast.offset_cw = 0; - rast.offset_ccw = 0; - rast.scissor = 0; - rast.poly_smooth = 0; - rast.poly_stipple_enable = 0; - rast.sprite_coord_enable = 0; - rast.point_size_per_vertex = 0; - rast.multisample = 0; - rast.line_smooth = 0; - rast.line_stipple_enable = 0; - rast.line_stipple_factor = 0; - rast.line_stipple_pattern = 0; - rast.line_last_pixel = 0; - rast.line_width = 1; - rast.point_smooth = 0; - rast.point_quad_rasterization = 0; - rast.point_size = 1; - rast.offset_units = 1; - rast.offset_scale = 1; - ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); - ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); - - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 0; - blend.rt[0].rgb_func = PIPE_BLEND_ADD; - blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_func = PIPE_BLEND_ADD; - blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.logicop_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - /* Needed to allow color writes to FB, even if blending disabled */ - blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.dither = 0; - ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); - ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); - - dsa.depth.enabled = 0; - dsa.depth.writemask = 0; - dsa.depth.func = PIPE_FUNC_ALWAYS; - for (i = 0; i < 2; ++i) { - dsa.stencil[i].enabled = 0; - dsa.stencil[i].func = PIPE_FUNC_ALWAYS; - dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].valuemask = 0; - dsa.stencil[i].writemask = 0; - } - dsa.alpha.enabled = 0; - dsa.alpha.func = PIPE_FUNC_ALWAYS; - dsa.alpha.ref_value = 0; - ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); - ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); - - return true; -} - -static struct pipe_video_context * -sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) -{ - struct sp_mpeg12_context *ctx; - - assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); - - ctx = CALLOC_STRUCT(sp_mpeg12_context); - - if (!ctx) - return NULL; - - ctx->base.profile = profile; - ctx->base.chroma_format = chroma_format; - ctx->base.width = width; - ctx->base.height = height; - - ctx->base.screen = screen; - ctx->base.destroy = sp_mpeg12_destroy; - ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks; - ctx->base.clear_surface = sp_mpeg12_clear_surface; - ctx->base.render_picture = sp_mpeg12_render_picture; - ctx->base.set_decode_target = sp_mpeg12_set_decode_target; - ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; - - ctx->pipe = screen->context_create(screen, NULL); - if (!ctx->pipe) { - FREE(ctx); - return NULL; - } - - /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture */ - if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, - width, height, chroma_format, - VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, - /* TODO: Use XFER_NONE when implemented */ - VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, - true)) { - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } - - if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) { - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } - - if (!init_pipe_state(ctx)) { - vl_compositor_cleanup(&ctx->compositor); - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } - - return &ctx->base; -} - -struct pipe_video_context * -sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) -{ - assert(screen); - assert(width && height); - - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG12: - return sp_mpeg12_create(screen, profile, - chroma_format, - width, height); - default: - return NULL; - } -} diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h deleted file mode 100644 index ccbd1ffe4c8..00000000000 --- a/src/gallium/drivers/softpipe/sp_video_context.h +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * All Rights Reserved. - * - * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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. - * - **************************************************************************/ - -#ifndef SP_VIDEO_CONTEXT_H -#define SP_VIDEO_CONTEXT_H - -#include <pipe/p_video_context.h> -#include <vl/vl_mpeg12_mc_renderer.h> -#include <vl/vl_compositor.h> - -struct pipe_screen; -struct pipe_context; -struct pipe_video_surface; - -struct sp_mpeg12_context -{ - struct pipe_video_context base; - struct pipe_context *pipe; - struct pipe_video_surface *decode_target; - struct vl_mpeg12_mc_renderer mc_renderer; - struct vl_compositor compositor; - - void *rast; - void *dsa; - void *blend; -}; - -struct pipe_video_context * -sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height); - -#endif /* SP_VIDEO_CONTEXT_H */ diff --git a/src/gallium/drivers/svga/Makefile b/src/gallium/drivers/svga/Makefile index f3619081875..27287793bda 100644 --- a/src/gallium/drivers/svga/Makefile +++ b/src/gallium/drivers/svga/Makefile @@ -27,8 +27,6 @@ C_SOURCES = \ svga_pipe_vertex.c \ svga_pipe_vs.c \ svga_screen.c \ - svga_screen_buffer.c \ - svga_screen_texture.c \ svga_screen_cache.c \ svga_state.c \ svga_state_need_swtnl.c \ @@ -45,7 +43,14 @@ C_SOURCES = \ svga_tgsi.c \ svga_tgsi_decl_sm20.c \ svga_tgsi_decl_sm30.c \ - svga_tgsi_insn.c + svga_tgsi_insn.c \ + svga_sampler_view.c \ + svga_surface.c \ + svga_resource.c \ + svga_resource_texture.c \ + svga_resource_buffer.c \ + svga_resource_buffer_upload.c + LIBRARY_INCLUDES = \ -I$(TOP)/src/gallium/drivers/svga/include diff --git a/src/gallium/drivers/svga/SConscript b/src/gallium/drivers/svga/SConscript index 737b791ceb0..12ce4732d15 100644 --- a/src/gallium/drivers/svga/SConscript +++ b/src/gallium/drivers/svga/SConscript @@ -38,10 +38,13 @@ sources = [ 'svga_pipe_sampler.c', 'svga_pipe_vertex.c', 'svga_pipe_vs.c', + 'svga_resource.c', + 'svga_resource_buffer.c', + 'svga_resource_buffer_upload.c', + 'svga_resource_texture.c', + 'svga_sampler_view.c', 'svga_screen.c', - 'svga_screen_buffer.c', 'svga_screen_cache.c', - 'svga_screen_texture.c', 'svga_state.c', 'svga_state_constants.c', 'svga_state_framebuffer.c', @@ -51,6 +54,7 @@ sources = [ 'svga_state_vdecl.c', 'svga_state_fs.c', 'svga_state_vs.c', + 'svga_surface.c', 'svga_swtnl_backend.c', 'svga_swtnl_draw.c', 'svga_swtnl_state.c', diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c index 04307d17fe0..7b2dfe25496 100644 --- a/src/gallium/drivers/svga/svga_cmd.c +++ b/src/gallium/drivers/svga/svga_cmd.c @@ -31,8 +31,9 @@ */ #include "svga_winsys.h" -#include "svga_screen_buffer.h" -#include "svga_screen_texture.h" +#include "svga_resource_buffer.h" +#include "svga_resource_texture.h" +#include "svga_surface.h" #include "svga_cmd.h" /* @@ -279,7 +280,7 @@ SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc, if(!cmd) return PIPE_ERROR_OUT_OF_MEMORY; - swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_WRITE); + swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE); cmd->surfaceFlags = flags; cmd->format = format; @@ -365,7 +366,7 @@ SVGA3D_DestroySurface(struct svga_winsys_context *swc, if(!cmd) return PIPE_ERROR_OUT_OF_MEMORY; - swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_READ); + swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ); swc->commit(swc);; return PIPE_OK; @@ -423,7 +424,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, const SVGA3dCopyBox *boxes, // IN uint32 numBoxes) // IN { - struct svga_texture *texture = svga_texture(st->base.texture); + struct svga_texture *texture = svga_texture(st->base.resource); SVGA3dCmdSurfaceDMA *cmd; SVGA3dCmdSurfaceDMASuffix *pSuffix; uint32 boxesSize = sizeof *boxes * numBoxes; @@ -431,12 +432,12 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, unsigned surface_flags; if(transfer == SVGA3D_WRITE_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_READ; - surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + region_flags = SVGA_RELOC_READ; + surface_flags = SVGA_RELOC_WRITE; } else if(transfer == SVGA3D_READ_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; - surface_flags = PIPE_BUFFER_USAGE_GPU_READ; + region_flags = SVGA_RELOC_WRITE; + surface_flags = SVGA_RELOC_READ; } else { assert(0); @@ -454,8 +455,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, cmd->guest.pitch = st->base.stride; swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags); - cmd->host.face = st->base.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */ - cmd->host.mipmap = st->base.level; + cmd->host.face = st->base.sr.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */ + cmd->host.mipmap = st->base.sr.level; cmd->transfer = transfer; @@ -489,12 +490,12 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc, unsigned surface_flags; if(transfer == SVGA3D_WRITE_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_READ; - surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + region_flags = SVGA_RELOC_READ; + surface_flags = SVGA_RELOC_WRITE; } else if(transfer == SVGA3D_READ_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; - surface_flags = PIPE_BUFFER_USAGE_GPU_READ; + region_flags = SVGA_RELOC_WRITE; + surface_flags = SVGA_RELOC_READ; } else { assert(0); @@ -584,7 +585,7 @@ SVGA3D_SetRenderTarget(struct svga_winsys_context *swc, cmd->type = type; - surface_to_surfaceid(swc, surface, &cmd->target, PIPE_BUFFER_USAGE_GPU_WRITE); + surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE); swc->commit(swc); @@ -1000,8 +1001,8 @@ SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc, if(!cmd) return PIPE_ERROR_OUT_OF_MEMORY; - surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); - surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); + surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); + surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); *boxes = (SVGA3dCopyBox*) &cmd[1]; memset(*boxes, 0, boxesSize); @@ -1043,8 +1044,8 @@ SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc, if(!cmd) return PIPE_ERROR_OUT_OF_MEMORY; - surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); - surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); + surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); + surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); cmd->boxSrc = *boxSrc; cmd->boxDest = *boxDest; cmd->mode = mode; @@ -1373,7 +1374,7 @@ SVGA3D_EndQuery(struct svga_winsys_context *swc, cmd->type = type; swc->region_relocation(swc, &cmd->guestResult, buffer, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); + SVGA_RELOC_WRITE); swc->commit(swc); @@ -1420,7 +1421,7 @@ SVGA3D_WaitForQuery(struct svga_winsys_context *swc, cmd->type = type; swc->region_relocation(swc, &cmd->guestResult, buffer, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); + SVGA_RELOC_WRITE); swc->commit(swc); diff --git a/src/gallium/drivers/svga/svga_cmd.h b/src/gallium/drivers/svga/svga_cmd.h index da9fc4355fa..0e568d78e65 100644 --- a/src/gallium/drivers/svga/svga_cmd.h +++ b/src/gallium/drivers/svga/svga_cmd.h @@ -41,7 +41,6 @@ #include "pipe/p_defines.h" -struct pipe_buffer; struct pipe_surface; struct svga_transfer; struct svga_winsys_context; diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index adb7840182b..3228a6d3d7f 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -34,8 +34,9 @@ #include "svga_context.h" #include "svga_screen.h" -#include "svga_screen_texture.h" -#include "svga_screen_buffer.h" +#include "svga_resource_texture.h" +#include "svga_resource_buffer.h" +#include "svga_resource.h" #include "svga_winsys.h" #include "svga_swtnl.h" #include "svga_draw.h" @@ -66,64 +67,11 @@ static void svga_destroy( struct pipe_context *pipe ) util_bitmask_destroy( svga->fs_bm ); for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader) - pipe_buffer_reference( &svga->curr.cb[shader], NULL ); + pipe_resource_reference( &svga->curr.cb[shader], NULL ); FREE( svga ); } -static unsigned int -svga_is_texture_referenced( struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - struct svga_texture *tex = svga_texture(texture); - struct svga_screen *ss = svga_screen(pipe->screen); - - /** - * The screen does not cache texture writes. - */ - - if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle)) - return PIPE_UNREFERENCED; - - /** - * sws->surface_is_flushed() does not distinguish between read references - * and write references. So assume a reference is both. - */ - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - -static unsigned int -svga_is_buffer_referenced( struct pipe_context *pipe, - struct pipe_buffer *buf) - -{ - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_buffer *sbuf = svga_buffer(buf); - - /** - * XXX: Check this. - * The screen may cache buffer writes, but when we map, we map out - * of those cached writes, so we don't need to set a - * PIPE_REFERENCED_FOR_WRITE flag for cached buffers. - */ - - if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle)) - return PIPE_UNREFERENCED; - - /** - * sws->surface_is_flushed() does not distinguish between read references - * and write references. So assume a reference is both, - * however, we make an exception for index- and vertex buffers, to avoid - * a flush in st_bufferobj_get_subdata, during display list replay. - */ - - if (sbuf->base.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX)) - return PIPE_REFERENCED_FOR_READ; - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} struct pipe_context *svga_context_create( struct pipe_screen *screen, @@ -143,13 +91,11 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen, svga->pipe.destroy = svga_destroy; svga->pipe.clear = svga_clear; - svga->pipe.is_texture_referenced = svga_is_texture_referenced; - svga->pipe.is_buffer_referenced = svga_is_buffer_referenced; - svga->swc = svgascreen->sws->context_create(svgascreen->sws); if(!svga->swc) goto no_swc; + svga_init_resource_functions(svga); svga_init_blend_functions(svga); svga_init_blit_functions(svga); svga_init_depth_stencil_functions(svga); @@ -164,7 +110,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen, svga_init_constbuffer_functions(svga); svga_init_query_functions(svga); - svga_init_texture_functions(&svga->pipe); /* debug */ svga->debug.no_swtnl = debug_get_bool_option("SVGA_NO_SWTNL", FALSE); @@ -183,17 +128,17 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen, if (svga->vs_bm == NULL) goto no_vs_bm; - svga->upload_ib = u_upload_create( svga->pipe.screen, + svga->upload_ib = u_upload_create( &svga->pipe, 32 * 1024, 16, - PIPE_BUFFER_USAGE_INDEX ); + PIPE_BIND_INDEX_BUFFER ); if (svga->upload_ib == NULL) goto no_upload_ib; - svga->upload_vb = u_upload_create( svga->pipe.screen, + svga->upload_vb = u_upload_create( &svga->pipe, 128 * 1024, 16, - PIPE_BUFFER_USAGE_VERTEX ); + PIPE_BIND_VERTEX_BUFFER ); if (svga->upload_vb == NULL) goto no_upload_vb; diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 1f66437dfe1..9a46de643fd 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -190,7 +190,7 @@ struct svga_state struct svga_vertex_shader *vs; struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; - struct pipe_buffer *cb[PIPE_SHADER_TYPES]; + struct pipe_resource *cb[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; float depthscale; @@ -254,7 +254,7 @@ struct svga_hw_clear_state struct svga_hw_view_state { - struct pipe_texture *texture; + struct pipe_resource *texture; struct svga_sampler_view *v; unsigned min_lod; unsigned max_lod; diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index 8b7ca2e1123..81dd4778d0a 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -34,8 +34,9 @@ #include "svga_draw_private.h" #include "svga_debug.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" -#include "svga_screen_texture.h" +#include "svga_resource_buffer.h" +#include "svga_resource_texture.h" +#include "svga_surface.h" #include "svga_winsys.h" #include "svga_cmd.h" @@ -65,16 +66,16 @@ void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl ) for (i = 0; i < PIPE_PRIM_MAX; i++) { for (j = 0; j < IDX_CACHE_MAX; j++) { - pipe_buffer_reference( &hwtnl->index_cache[i][j].buffer, + pipe_resource_reference( &hwtnl->index_cache[i][j].buffer, NULL ); } } for (i = 0; i < hwtnl->cmd.vdecl_count; i++) - pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], NULL); + pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], NULL); for (i = 0; i < hwtnl->cmd.prim_count; i++) - pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL); + pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); FREE(hwtnl); @@ -103,7 +104,7 @@ void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl, assert(hwtnl->cmd.prim_count == 0); for (i = count; i < hwtnl->cmd.vdecl_count; i++) { - pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], + pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], NULL); } @@ -112,9 +113,9 @@ void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl, void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl, - unsigned i, - const SVGA3dVertexDecl *decl, - struct pipe_buffer *vb) + unsigned i, + const SVGA3dVertexDecl *decl, + struct pipe_resource *vb) { assert(hwtnl->cmd.prim_count == 0); @@ -122,8 +123,7 @@ void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl, hwtnl->cmd.vdecl[i] = *decl; - pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], - vb); + pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], vb); } @@ -198,7 +198,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) swc->surface_relocation(swc, &vdecl[i].array.surfaceId, vb_handle[i], - PIPE_BUFFER_USAGE_GPU_READ); + SVGA_RELOC_READ); } memcpy( prim, @@ -209,8 +209,8 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) swc->surface_relocation(swc, &prim[i].indexArray.surfaceId, ib_handle[i], - PIPE_BUFFER_USAGE_GPU_READ); - pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL); + SVGA_RELOC_READ); + pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); } SVGA_FIFOCommitAll( swc ); @@ -232,7 +232,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, const SVGA3dPrimitiveRange *range, unsigned min_index, unsigned max_index, - struct pipe_buffer *ib ) + struct pipe_resource *ib ) { int ret = PIPE_OK; @@ -240,8 +240,8 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, { unsigned i; for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { - struct pipe_buffer *vb = hwtnl->cmd.vdecl_vb[i]; - unsigned size = vb ? vb->size : 0; + struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i]; + unsigned size = vb ? vb->width0 : 0; unsigned offset = hwtnl->cmd.vdecl[i].array.offset; unsigned stride = hwtnl->cmd.vdecl[i].array.stride; unsigned index_bias = range->indexBias; @@ -324,7 +324,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, assert(range->indexWidth == range->indexArray.stride); if(ib) { - unsigned size = ib->size; + unsigned size = ib->width0; unsigned offset = range->indexArray.offset; unsigned stride = range->indexArray.stride; unsigned count; @@ -375,7 +375,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range; - pipe_buffer_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); + pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); hwtnl->cmd.prim_count++; return ret; diff --git a/src/gallium/drivers/svga/svga_draw.h b/src/gallium/drivers/svga/svga_draw.h index 14553b17b58..81c7f8377de 100644 --- a/src/gallium/drivers/svga/svga_draw.h +++ b/src/gallium/drivers/svga/svga_draw.h @@ -34,7 +34,7 @@ struct svga_hwtnl; struct svga_winsys_context; struct svga_screen; struct svga_context; -struct pipe_buffer; +struct pipe_resource; struct u_upload_mgr; struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga, @@ -53,7 +53,7 @@ void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl, void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl, unsigned i, const SVGA3dVertexDecl *decl, - struct pipe_buffer *vb); + struct pipe_resource *vb); void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl, unsigned count ); @@ -67,7 +67,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, enum pipe_error svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned index_size, unsigned min_index, unsigned max_index, diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c index 6192aa96b11..005996d05d3 100644 --- a/src/gallium/drivers/svga/svga_draw_arrays.c +++ b/src/gallium/drivers/svga/svga_draw_arrays.c @@ -43,40 +43,40 @@ static enum pipe_error generate_indices( struct svga_hwtnl *hwtnl, unsigned nr, unsigned index_size, u_generate_func generate, - struct pipe_buffer **out_buf ) + struct pipe_resource **out_buf ) { - struct pipe_screen *screen = hwtnl->svga->pipe.screen; + struct pipe_context *pipe = &hwtnl->svga->pipe; + struct pipe_transfer *transfer; unsigned size = index_size * nr; - struct pipe_buffer *dst = NULL; + struct pipe_resource *dst = NULL; void *dst_map = NULL; - dst = screen->buffer_create( screen, 32, - PIPE_BUFFER_USAGE_INDEX | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ, - size ); + dst = pipe_buffer_create( pipe->screen, + PIPE_BIND_INDEX_BUFFER, + size ); if (dst == NULL) goto fail; - dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); + dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE, + &transfer); if (dst_map == NULL) goto fail; generate( nr, dst_map ); - pipe_buffer_unmap( screen, dst ); + pipe_buffer_unmap( pipe, dst, transfer ); *out_buf = dst; return PIPE_OK; fail: if (dst_map) - screen->buffer_unmap( screen, dst ); + pipe_buffer_unmap( pipe, dst, transfer ); if (dst) - screen->buffer_destroy( dst ); - + pipe->screen->resource_destroy( pipe->screen, dst ); + return PIPE_ERROR_OUT_OF_MEMORY; } @@ -96,7 +96,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl, unsigned gen_nr, unsigned gen_size, u_generate_func generate, - struct pipe_buffer **out_buf ) + struct pipe_resource **out_buf ) { enum pipe_error ret = PIPE_OK; int i; @@ -107,7 +107,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl, { if (compare(hwtnl->index_cache[prim][i].gen_nr, gen_nr, gen_type)) { - pipe_buffer_reference( out_buf, + pipe_resource_reference( out_buf, hwtnl->index_cache[prim][i].buffer ); if (DBG) @@ -117,7 +117,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl, } else if (gen_type == U_GENERATE_REUSABLE) { - pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer, + pipe_resource_reference( &hwtnl->index_cache[prim][i].buffer, NULL ); if (DBG) @@ -149,7 +149,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl, assert (smallest != IDX_CACHE_MAX); - pipe_buffer_reference( &hwtnl->index_cache[prim][smallest].buffer, + pipe_resource_reference( &hwtnl->index_cache[prim][smallest].buffer, NULL ); if (DBG) @@ -171,7 +171,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl, hwtnl->index_cache[prim][i].generate = generate; hwtnl->index_cache[prim][i].gen_nr = gen_nr; - pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer, + pipe_resource_reference( &hwtnl->index_cache[prim][i].buffer, *out_buf ); if (DBG) @@ -259,7 +259,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, return simple_draw_arrays( hwtnl, gen_prim, start, count ); } else { - struct pipe_buffer *gen_buf = NULL; + struct pipe_resource *gen_buf = NULL; /* Need to draw as indexed primitive. * Potentially need to run the gen func to build an index buffer. @@ -288,7 +288,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, done: if (gen_buf) - pipe_buffer_reference( &gen_buf, NULL ); + pipe_resource_reference( &gen_buf, NULL ); return ret; } diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index e8097d82f16..7ec4a058fc7 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -30,7 +30,7 @@ #include "svga_cmd.h" #include "svga_draw.h" #include "svga_draw_private.h" -#include "svga_screen_buffer.h" +#include "svga_resource_buffer.h" #include "svga_winsys.h" #include "svga_context.h" @@ -39,32 +39,32 @@ static enum pipe_error translate_indices( struct svga_hwtnl *hwtnl, - struct pipe_buffer *src, + struct pipe_resource *src, unsigned offset, unsigned nr, unsigned index_size, u_translate_func translate, - struct pipe_buffer **out_buf ) + struct pipe_resource **out_buf ) { - struct pipe_screen *screen = hwtnl->svga->pipe.screen; + struct pipe_context *pipe = &hwtnl->svga->pipe; + struct pipe_transfer *src_transfer = NULL; + struct pipe_transfer *dst_transfer = NULL; unsigned size = index_size * nr; const void *src_map = NULL; - struct pipe_buffer *dst = NULL; + struct pipe_resource *dst = NULL; void *dst_map = NULL; - dst = screen->buffer_create( screen, 32, - PIPE_BUFFER_USAGE_INDEX | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ, - size ); + dst = pipe_buffer_create( pipe->screen, + PIPE_BIND_INDEX_BUFFER, + size ); if (dst == NULL) goto fail; - src_map = pipe_buffer_map( screen, src, PIPE_BUFFER_USAGE_CPU_READ ); + src_map = pipe_buffer_map( pipe, src, PIPE_TRANSFER_READ, &src_transfer ); if (src_map == NULL) goto fail; - dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); + dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE, &dst_transfer ); if (dst_map == NULL) goto fail; @@ -72,21 +72,21 @@ translate_indices( struct svga_hwtnl *hwtnl, nr, dst_map ); - pipe_buffer_unmap( screen, src ); - pipe_buffer_unmap( screen, dst ); + pipe_buffer_unmap( pipe, src, src_transfer ); + pipe_buffer_unmap( pipe, dst, dst_transfer ); *out_buf = dst; return PIPE_OK; fail: if (src_map) - screen->buffer_unmap( screen, src ); + pipe_buffer_unmap( pipe, src, src_transfer ); if (dst_map) - screen->buffer_unmap( screen, dst ); + pipe_buffer_unmap( pipe, dst, dst_transfer ); if (dst) - screen->buffer_destroy( dst ); + pipe->screen->resource_destroy( pipe->screen, dst ); return PIPE_ERROR_OUT_OF_MEMORY; } @@ -97,7 +97,7 @@ fail: enum pipe_error svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned min_index, unsigned max_index, @@ -106,7 +106,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, unsigned count, unsigned bias ) { - struct pipe_buffer *upload_buffer = NULL; + struct pipe_resource *upload_buffer = NULL; SVGA3dPrimitiveRange range; unsigned hw_prim; unsigned hw_count; @@ -120,7 +120,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, if (index_buffer && svga_buffer_is_user_buffer(index_buffer)) { - assert( index_buffer->size >= index_offset + count * index_size ); + assert( index_buffer->width0 >= index_offset + count * index_size ); ret = u_upload_buffer( hwtnl->upload_ib, index_offset, @@ -151,7 +151,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, done: if (upload_buffer) - pipe_buffer_reference( &upload_buffer, NULL ); + pipe_resource_reference( &upload_buffer, NULL ); return ret; } @@ -161,7 +161,7 @@ done: enum pipe_error svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned min_index, unsigned max_index, @@ -209,7 +209,7 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl, gen_prim, start, count, bias ); } else { - struct pipe_buffer *gen_buf = NULL; + struct pipe_resource *gen_buf = NULL; /* Need to allocate a new index buffer and run the translate * func to populate it. Could potentially cache this translated @@ -242,7 +242,7 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl, done: if (gen_buf) - pipe_buffer_reference( &gen_buf, NULL ); + pipe_resource_reference( &gen_buf, NULL ); return ret; } diff --git a/src/gallium/drivers/svga/svga_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h index 9aa40e16642..b6fcd6854c5 100644 --- a/src/gallium/drivers/svga/svga_draw_private.h +++ b/src/gallium/drivers/svga/svga_draw_private.h @@ -90,7 +90,7 @@ struct index_cache { /* If non-null, this buffer is filled by calling * generate(nr, map(buffer)) */ - struct pipe_buffer *buffer; + struct pipe_resource *buffer; }; #define QSZ 32 @@ -99,11 +99,11 @@ struct draw_cmd { struct svga_winsys_context *swc; SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX]; - struct pipe_buffer *vdecl_vb[SVGA3D_INPUTREG_MAX]; + struct pipe_resource *vdecl_vb[SVGA3D_INPUTREG_MAX]; unsigned vdecl_count; SVGA3dPrimitiveRange prim[QSZ]; - struct pipe_buffer *prim_ib[QSZ]; + struct pipe_resource *prim_ib[QSZ]; unsigned prim_count; unsigned min_index[QSZ]; unsigned max_index[QSZ]; @@ -141,11 +141,11 @@ svga_hwtnl_prim( struct svga_hwtnl *hwtnl, const SVGA3dPrimitiveRange *range, unsigned min_index, unsigned max_index, - struct pipe_buffer *ib ); + struct pipe_resource *ib ); enum pipe_error svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned index_size, unsigned min_index, unsigned max_index, diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c index 4f575b06e62..889da29e28b 100644 --- a/src/gallium/drivers/svga/svga_pipe_blit.c +++ b/src/gallium/drivers/svga/svga_pipe_blit.c @@ -23,10 +23,11 @@ * **********************************************************/ -#include "svga_screen_texture.h" +#include "svga_resource_texture.h" #include "svga_context.h" #include "svga_debug.h" #include "svga_cmd.h" +#include "svga_surface.h" #define FILE_DEBUG_FLAG DEBUG_BLIT diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index bb1664fbed9..cbff95c9179 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -31,7 +31,7 @@ #include "svga_context.h" #include "svga_state.h" -#include "svga_screen_texture.h" +#include "svga_surface.h" static enum pipe_error diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c index 73a0cd6b3a8..2fa2142d07d 100644 --- a/src/gallium/drivers/svga/svga_pipe_constants.c +++ b/src/gallium/drivers/svga/svga_pipe_constants.c @@ -45,14 +45,14 @@ struct svga_constbuf static void svga_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_resource *buf) { struct svga_context *svga = svga_context(pipe); assert(shader < PIPE_SHADER_TYPES); assert(index == 0); - pipe_buffer_reference( &svga->curr.cb[shader], + pipe_resource_reference( &svga->curr.cb[shader], buf ); if (shader == PIPE_SHADER_FRAGMENT) diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index f00cf23935e..a05272b2e40 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -42,7 +42,7 @@ static enum pipe_error retry_draw_range_elements( struct svga_context *svga, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned min_index, unsigned max_index, @@ -150,7 +150,7 @@ retry: static void svga_draw_range_elements( struct pipe_context *pipe, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned min_index, unsigned max_index, @@ -224,7 +224,7 @@ svga_draw_range_elements( struct pipe_context *pipe, static void svga_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *index_buffer, + struct pipe_resource *index_buffer, unsigned index_size, unsigned prim, unsigned start, unsigned count) { diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c index 7fa2205ae5f..ab243aa6ec5 100644 --- a/src/gallium/drivers/svga/svga_pipe_flush.c +++ b/src/gallium/drivers/svga/svga_pipe_flush.c @@ -25,7 +25,7 @@ #include "pipe/p_defines.h" #include "svga_screen.h" -#include "svga_screen_texture.h" +#include "svga_surface.h" #include "svga_context.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c index 2c43f9a24f4..8c24fb302f7 100644 --- a/src/gallium/drivers/svga/svga_pipe_misc.c +++ b/src/gallium/drivers/svga/svga_pipe_misc.c @@ -28,7 +28,7 @@ #include "util/u_inlines.h" #include "svga_context.h" -#include "svga_screen_texture.h" +#include "svga_surface.h" static void svga_set_scissor_state( struct pipe_context *pipe, diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 08283e37317..9c6f5858ba4 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -30,7 +30,7 @@ #include "svga_cmd.h" #include "svga_context.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" +#include "svga_resource_buffer.h" #include "svga_winsys.h" #include "svga_debug.h" @@ -89,7 +89,7 @@ static struct pipe_query *svga_create_query( struct pipe_context *pipe, sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws, sq->hwbuf, - PIPE_BUFFER_USAGE_CPU_WRITE); + PIPE_TRANSFER_WRITE); if(!sq->queryResult) goto no_query_result; diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 82d525ca33f..f44a0e1325a 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -30,7 +30,7 @@ #include "tgsi/tgsi_parse.h" #include "svga_context.h" -#include "svga_screen_texture.h" +#include "svga_resource_texture.h" #include "svga_debug.h" @@ -178,7 +178,7 @@ static void svga_delete_sampler_state(struct pipe_context *pipe, static struct pipe_sampler_view * svga_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -187,7 +187,7 @@ svga_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -199,7 +199,7 @@ static void svga_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 1715a47fc62..23808ad08e0 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -30,7 +30,7 @@ #include "tgsi/tgsi_parse.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" +#include "svga_resource_buffer.h" #include "svga_context.h" @@ -49,13 +49,13 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe, /* Adjust refcounts */ for (i = 0; i < count; i++) { - pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer); + pipe_resource_reference(&svga->curr.vb[i].buffer, buffers[i].buffer); if (svga_buffer_is_user_buffer(buffers[i].buffer)) any_user_buffer = TRUE; } for ( ; i < svga->curr.num_vertex_buffers; i++) - pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL); + pipe_resource_reference(&svga->curr.vb[i].buffer, NULL); /* Copy remaining data */ memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]); @@ -102,7 +102,7 @@ void svga_cleanup_vertex_state( struct svga_context *svga ) unsigned i; for (i = 0 ; i < svga->curr.num_vertex_buffers; i++) - pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL); + pipe_resource_reference(&svga->curr.vb[i].buffer, NULL); } diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c new file mode 100644 index 00000000000..15258c1966b --- /dev/null +++ b/src/gallium/drivers/svga/svga_resource.c @@ -0,0 +1,55 @@ +#include "util/u_debug.h" + +#include "svga_resource.h" +#include "svga_resource_buffer.h" +#include "svga_resource_texture.h" +#include "svga_context.h" +#include "svga_screen.h" + + +static struct pipe_resource * +svga_resource_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + if (template->target == PIPE_BUFFER) + return svga_buffer_create(screen, template); + else + return svga_resource_create(screen, template); + +} + +static struct pipe_resource * +svga_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + if (template->target == PIPE_BUFFER) + return NULL; + else + return svga_resource_from_handle(screen, template, whandle); +} + + +void +svga_init_resource_functions(struct svga_context *svga) +{ + svga->pipe.get_transfer = u_get_transfer_vtbl; + svga->pipe.transfer_map = u_transfer_map_vtbl; + svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl; + svga->pipe.transfer_unmap = u_transfer_unmap_vtbl; + svga->pipe.transfer_destroy = u_transfer_destroy_vtbl; + svga->pipe.transfer_inline_write = u_transfer_inline_write_vtbl; +} + +void +svga_init_screen_resource_functions(struct svga_screen *is) +{ + is->screen.resource_create = svga_resource_create; + is->screen.resource_from_handle = svga_resource_from_handle; + is->screen.resource_get_handle = u_resource_get_handle_vtbl; + is->screen.resource_destroy = u_resource_destroy_vtbl; + is->screen.user_buffer_create = svga_user_buffer_create; +} + + + diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.h b/src/gallium/drivers/svga/svga_resource.h index ef0a8a70e59..851e3b50ce3 100644 --- a/src/gallium/drivers/cell/ppu/cell_buffer.h +++ b/src/gallium/drivers/svga/svga_resource.h @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2009 VMware, Inc. + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * 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 @@ -10,46 +10,34 @@ * 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS 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. - * + * **************************************************************************/ -#ifndef SP_BUFFER_H -#define SP_BUFFER_H +#ifndef SVGA_RESOURCE_H +#define SVGA_RESOURCE_H -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" +struct svga_screen; +#include "util/u_debug.h" -struct cell_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; -}; +struct svga_context; +struct svga_screen; -/** Cast wrapper */ -static INLINE struct cell_buffer * -cell_buffer( struct pipe_buffer *buf ) -{ - return (struct cell_buffer *)buf; -} +void svga_init_screen_resource_functions(struct svga_screen *is); +void svga_init_resource_functions(struct svga_context *svga ); -void -cell_init_screen_buffer_funcs(struct pipe_screen *screen); - - -#endif /* SP_BUFFER_H */ +#endif /* SVGA_RESOURCE_H */ diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c new file mode 100644 index 00000000000..cfa7d1015ee --- /dev/null +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -0,0 +1,355 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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 "svga_cmd.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "svga_context.h" +#include "svga_screen.h" +#include "svga_resource_buffer.h" +#include "svga_resource_buffer_upload.h" +#include "svga_winsys.h" +#include "svga_debug.h" + + +/** + * Vertex and index buffers need hardware backing. Constant buffers + * do not. No other types of buffers currently supported. + */ +static INLINE boolean +svga_buffer_needs_hw_storage(unsigned usage) +{ + return usage & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER); +} + + +static unsigned int +svga_buffer_is_referenced( struct pipe_context *pipe, + struct pipe_resource *buf, + unsigned face, unsigned level) +{ + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_buffer *sbuf = svga_buffer(buf); + + /** + * XXX: Check this. + * The screen may cache buffer writes, but when we map, we map out + * of those cached writes, so we don't need to set a + * PIPE_REFERENCED_FOR_WRITE flag for cached buffers. + */ + + if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle)) + return PIPE_UNREFERENCED; + + /** + * sws->surface_is_flushed() does not distinguish between read references + * and write references. So assume a reference is both, + * however, we make an exception for index- and vertex buffers, to avoid + * a flush in st_bufferobj_get_subdata, during display list replay. + */ + + if (sbuf->b.b.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) + return PIPE_REFERENCED_FOR_READ; + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + + + + + + +static void * +svga_buffer_map_range( struct pipe_screen *screen, + struct pipe_resource *buf, + unsigned offset, + unsigned length, + unsigned usage ) +{ + struct svga_screen *ss = svga_screen(screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_buffer *sbuf = svga_buffer( buf ); + void *map; + + if (!sbuf->swbuf && !sbuf->hwbuf) { + if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) { + /* + * We can't create a hardware buffer big enough, so create a malloc + * buffer instead. + */ + debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n", + __FUNCTION__, + (sbuf->b.b.width0 + 1023)/1024); + + sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16); + } + } + + if (sbuf->swbuf) { + /* User/malloc buffer */ + map = sbuf->swbuf; + } + else if (sbuf->hwbuf) { + map = sws->buffer_map(sws, sbuf->hwbuf, usage); + } + else { + map = NULL; + } + + if(map) { + pipe_mutex_lock(ss->swc_mutex); + + ++sbuf->map.count; + + if (usage & PIPE_TRANSFER_WRITE) { + assert(sbuf->map.count <= 1); + sbuf->map.writing = TRUE; + if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) + sbuf->map.flush_explicit = TRUE; + } + + pipe_mutex_unlock(ss->swc_mutex); + } + + return map; +} + + + +static void +svga_buffer_flush_mapped_range( struct pipe_screen *screen, + struct pipe_resource *buf, + unsigned offset, unsigned length) +{ + struct svga_buffer *sbuf = svga_buffer( buf ); + struct svga_screen *ss = svga_screen(screen); + + pipe_mutex_lock(ss->swc_mutex); + assert(sbuf->map.writing); + if(sbuf->map.writing) { + assert(sbuf->map.flush_explicit); + svga_buffer_add_range(sbuf, offset, offset + length); + } + pipe_mutex_unlock(ss->swc_mutex); +} + +static void +svga_buffer_unmap( struct pipe_screen *screen, + struct pipe_resource *buf) +{ + struct svga_screen *ss = svga_screen(screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_buffer *sbuf = svga_buffer( buf ); + + pipe_mutex_lock(ss->swc_mutex); + + assert(sbuf->map.count); + if(sbuf->map.count) + --sbuf->map.count; + + if(sbuf->hwbuf) + sws->buffer_unmap(sws, sbuf->hwbuf); + + if(sbuf->map.writing) { + if(!sbuf->map.flush_explicit) { + /* No mapped range was flushed -- flush the whole buffer */ + SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n"); + + svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0); + } + + sbuf->map.writing = FALSE; + sbuf->map.flush_explicit = FALSE; + } + + pipe_mutex_unlock(ss->swc_mutex); +} + + + +static void +svga_buffer_destroy( struct pipe_screen *screen, + struct pipe_resource *buf ) +{ + struct svga_screen *ss = svga_screen(screen); + struct svga_buffer *sbuf = svga_buffer( buf ); + + assert(!p_atomic_read(&buf->reference.count)); + + assert(!sbuf->dma.pending); + + if(sbuf->handle) + svga_buffer_destroy_host_surface(ss, sbuf); + + if(sbuf->uploaded.buffer) + pipe_resource_reference(&sbuf->uploaded.buffer, NULL); + + if(sbuf->hwbuf) + svga_buffer_destroy_hw_storage(ss, sbuf); + + if(sbuf->swbuf && !sbuf->user) + align_free(sbuf->swbuf); + + FREE(sbuf); +} + + +/* Keep the original code more or less intact, implement transfers in + * terms of the old functions. + */ +static void * +svga_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + uint8_t *map = svga_buffer_map_range( pipe->screen, + transfer->resource, + transfer->box.x, + transfer->box.width, + transfer->usage ); + if (map == NULL) + return NULL; + + /* map_buffer() returned a pointer to the beginning of the buffer, + * but transfers are expected to return a pointer to just the + * region specified in the box. + */ + return map + transfer->box.x; +} + + + +static void svga_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + assert(box->x + box->width <= transfer->box.width); + + svga_buffer_flush_mapped_range(pipe->screen, + transfer->resource, + transfer->box.x + box->x, + box->width); +} + +static void svga_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + svga_buffer_unmap(pipe->screen, + transfer->resource); +} + + + + + + + +struct u_resource_vtbl svga_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + svga_buffer_destroy, /* resource_destroy */ + svga_buffer_is_referenced, /* is_resource_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + svga_buffer_transfer_map, /* transfer_map */ + svga_buffer_transfer_flush_region, /* transfer_flush_region */ + svga_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + +struct pipe_resource * +svga_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + struct svga_screen *ss = svga_screen(screen); + struct svga_buffer *sbuf; + + sbuf = CALLOC_STRUCT(svga_buffer); + if(!sbuf) + goto error1; + + sbuf->b.b = *template; + sbuf->b.vtbl = &svga_buffer_vtbl; + pipe_reference_init(&sbuf->b.b.reference, 1); + sbuf->b.b.screen = screen; + + if(svga_buffer_needs_hw_storage(template->bind)) { + if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK) + goto error2; + } + else { + sbuf->swbuf = align_malloc(template->width0, 64); + if(!sbuf->swbuf) + goto error2; + } + + return &sbuf->b.b; + +error2: + FREE(sbuf); +error1: + return NULL; +} + +struct pipe_resource * +svga_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind) +{ + struct svga_buffer *sbuf; + + sbuf = CALLOC_STRUCT(svga_buffer); + if(!sbuf) + goto no_sbuf; + + pipe_reference_init(&sbuf->b.b.reference, 1); + sbuf->b.vtbl = &svga_buffer_vtbl; + sbuf->b.b.screen = screen; + sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + sbuf->b.b._usage = PIPE_USAGE_IMMUTABLE; + sbuf->b.b.bind = bind; + sbuf->b.b.width0 = bytes; + sbuf->b.b.height0 = 1; + sbuf->b.b.depth0 = 1; + + sbuf->swbuf = ptr; + sbuf->user = TRUE; + + return &sbuf->b.b; + +no_sbuf: + return NULL; +} + + + diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index 8c862fa62d6..55e7321184f 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -29,14 +29,13 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "util/u_transfer.h" #include "util/u_double_list.h" #include "svga_screen_cache.h" -#define SVGA_BUFFER_MAGIC 0x344f9005 - /** * Maximum number of discontiguous ranges */ @@ -49,6 +48,8 @@ struct svga_winsys_buffer; struct svga_winsys_surface; +extern struct u_resource_vtbl svga_buffer_vtbl; + struct svga_buffer_range { unsigned start; @@ -61,12 +62,7 @@ struct svga_buffer_range */ struct svga_buffer { - struct pipe_buffer base; - - /** - * Marker to detect bad casts in runtime. - */ - uint32_t magic; + struct u_resource b; /** * Regular (non DMA'able) memory. @@ -138,7 +134,7 @@ struct svga_buffer * Information about uploaded version of user buffers. */ struct { - struct pipe_buffer *buffer; + struct pipe_resource *buffer; /** * We combine multiple user buffers into the same hardware buffer. This @@ -190,10 +186,10 @@ struct svga_buffer static INLINE struct svga_buffer * -svga_buffer(struct pipe_buffer *buffer) +svga_buffer(struct pipe_resource *buffer) { if (buffer) { - assert(((struct svga_buffer *)buffer)->magic == SVGA_BUFFER_MAGIC); + assert(((struct svga_buffer *)buffer)->b.vtbl == &svga_buffer_vtbl); return (struct svga_buffer *)buffer; } return NULL; @@ -205,14 +201,24 @@ svga_buffer(struct pipe_buffer *buffer) * decide to use an alternate upload path for these buffers. */ static INLINE boolean -svga_buffer_is_user_buffer( struct pipe_buffer *buffer ) +svga_buffer_is_user_buffer( struct pipe_resource *buffer ) { return svga_buffer(buffer)->user; } -void -svga_screen_init_buffer_functions(struct pipe_screen *screen); + + +struct pipe_resource * +svga_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage); + +struct pipe_resource * +svga_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *template); + /** @@ -226,7 +232,7 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen); */ struct svga_winsys_surface * svga_buffer_handle(struct svga_context *svga, - struct pipe_buffer *buf); + struct pipe_resource *buf); void svga_context_flush_buffers(struct svga_context *svga); diff --git a/src/gallium/drivers/svga/svga_resource_buffer_host.c b/src/gallium/drivers/svga/svga_resource_buffer_host.c new file mode 100644 index 00000000000..139597f9cb0 --- /dev/null +++ b/src/gallium/drivers/svga/svga_resource_buffer_host.c @@ -0,0 +1,2 @@ + + diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index 1ff6a3a5b31..acef60f4647 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -34,88 +34,14 @@ #include "svga_context.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" +#include "svga_resource_buffer.h" +#include "svga_resource_buffer_upload.h" #include "svga_winsys.h" #include "svga_debug.h" -/** - * Vertex and index buffers have to be treated slightly differently from - * regular guest memory regions because the SVGA device sees them as - * surfaces, and the state tracker can create/destroy without the pipe - * driver, therefore we must do the uploads from the vws. +/* Allocate a winsys_buffer (ie. DMA, aka GMR memory). */ -static INLINE boolean -svga_buffer_needs_hw_storage(unsigned usage) -{ - return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX); -} - - -static INLINE enum pipe_error -svga_buffer_create_host_surface(struct svga_screen *ss, - struct svga_buffer *sbuf) -{ - if(!sbuf->handle) { - sbuf->key.flags = 0; - - sbuf->key.format = SVGA3D_BUFFER; - if(sbuf->base.usage & PIPE_BUFFER_USAGE_VERTEX) - sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; - if(sbuf->base.usage & PIPE_BUFFER_USAGE_INDEX) - sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; - - sbuf->key.size.width = sbuf->base.size; - sbuf->key.size.height = 1; - sbuf->key.size.depth = 1; - - sbuf->key.numFaces = 1; - sbuf->key.numMipLevels = 1; - sbuf->key.cachable = 1; - - SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size); - - sbuf->handle = svga_screen_surface_create(ss, &sbuf->key); - if(!sbuf->handle) - return PIPE_ERROR_OUT_OF_MEMORY; - - /* Always set the discard flag on the first time the buffer is written - * as svga_screen_surface_create might have passed a recycled host - * buffer. - */ - sbuf->dma.flags.discard = TRUE; - - SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size); - } - - return PIPE_OK; -} - - -static INLINE void -svga_buffer_destroy_host_surface(struct svga_screen *ss, - struct svga_buffer *sbuf) -{ - if(sbuf->handle) { - SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->base.size); - svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle); - } -} - - -static INLINE void -svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) -{ - struct svga_winsys_screen *sws = ss->sws; - - assert(!sbuf->map.count); - assert(sbuf->hwbuf); - if(sbuf->hwbuf) { - sws->buffer_destroy(sws, sbuf->hwbuf); - sbuf->hwbuf = NULL; - } -} - struct svga_winsys_buffer * svga_winsys_buffer_create( struct svga_screen *ss, unsigned alignment, @@ -142,21 +68,36 @@ svga_winsys_buffer_create( struct svga_screen *ss, } +void +svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) +{ + struct svga_winsys_screen *sws = ss->sws; + + assert(!sbuf->map.count); + assert(sbuf->hwbuf); + if(sbuf->hwbuf) { + sws->buffer_destroy(sws, sbuf->hwbuf); + sbuf->hwbuf = NULL; + } +} + + + /** * Allocate DMA'ble storage for the buffer. * * Called before mapping a buffer. */ -static INLINE enum pipe_error +enum pipe_error svga_buffer_create_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) { assert(!sbuf->user); if(!sbuf->hwbuf) { - unsigned alignment = sbuf->base.alignment; + unsigned alignment = 16; unsigned usage = 0; - unsigned size = sbuf->base.size; + unsigned size = sbuf->b.b.width0; sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size); if(!sbuf->hwbuf) @@ -169,6 +110,58 @@ svga_buffer_create_hw_storage(struct svga_screen *ss, } + +enum pipe_error +svga_buffer_create_host_surface(struct svga_screen *ss, + struct svga_buffer *sbuf) +{ + if(!sbuf->handle) { + sbuf->key.flags = 0; + + sbuf->key.format = SVGA3D_BUFFER; + if(sbuf->b.b.bind & PIPE_BIND_VERTEX_BUFFER) + sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; + if(sbuf->b.b.bind & PIPE_BIND_INDEX_BUFFER) + sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; + + sbuf->key.size.width = sbuf->b.b.width0; + sbuf->key.size.height = 1; + sbuf->key.size.depth = 1; + + sbuf->key.numFaces = 1; + sbuf->key.numMipLevels = 1; + sbuf->key.cachable = 1; + + SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->b.b.width0); + + sbuf->handle = svga_screen_surface_create(ss, &sbuf->key); + if(!sbuf->handle) + return PIPE_ERROR_OUT_OF_MEMORY; + + /* Always set the discard flag on the first time the buffer is written + * as svga_screen_surface_create might have passed a recycled host + * buffer. + */ + sbuf->dma.flags.discard = TRUE; + + SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->b.b.width0); + } + + return PIPE_OK; +} + + +void +svga_buffer_destroy_host_surface(struct svga_screen *ss, + struct svga_buffer *sbuf) +{ + if(sbuf->handle) { + SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->b.b.width0); + svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle); + } +} + + /** * Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank. */ @@ -186,15 +179,15 @@ svga_buffer_upload_command(struct svga_context *svga, SVGA3dCmdSurfaceDMASuffix *pSuffix; unsigned region_flags; unsigned surface_flags; - struct pipe_buffer *dummy; + struct pipe_resource *dummy; if(transfer == SVGA3D_WRITE_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_READ; - surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + region_flags = SVGA_RELOC_READ; + surface_flags = SVGA_RELOC_WRITE; } else if(transfer == SVGA3D_READ_HOST_VRAM) { - region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; - surface_flags = PIPE_BUFFER_USAGE_GPU_READ; + region_flags = SVGA_RELOC_WRITE; + surface_flags = SVGA_RELOC_READ; } else { assert(0); @@ -224,11 +217,11 @@ svga_buffer_upload_command(struct svga_context *svga, /* Increment reference count */ dummy = NULL; - pipe_buffer_reference(&dummy, &sbuf->base); + pipe_resource_reference(&dummy, &sbuf->b.b); pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes); pSuffix->suffixSize = sizeof *pSuffix; - pSuffix->maximumOffset = sbuf->base.size; + pSuffix->maximumOffset = sbuf->b.b.width0; pSuffix->flags = sbuf->dma.flags; SVGA_FIFOCommitAll(swc); @@ -291,11 +284,12 @@ svga_buffer_upload_flush(struct svga_context *svga, sbuf->dma.boxes = NULL; /* Decrement reference count */ - pipe_reference(&(sbuf->base.reference), NULL); + pipe_reference(&(sbuf->b.b.reference), NULL); sbuf = NULL; } + /** * Note a dirty range. * @@ -305,7 +299,7 @@ svga_buffer_upload_flush(struct svga_context *svga, * * We try to lump as many contiguous DMA transfers together as possible. */ -static void +void svga_buffer_add_range(struct svga_buffer *sbuf, unsigned start, unsigned end) @@ -330,7 +324,7 @@ svga_buffer_add_range(struct svga_buffer *sbuf, * Note that it is not this function task to care about overlapping ranges, * as the GMR was already given so it is too late to do anything. Situations * where overlapping ranges may pose a problem should be detected via - * pipe_context::is_buffer_referenced and the context that refers to the + * pipe_context::is_resource_referenced and the context that refers to the * buffer should be flushed. */ @@ -400,222 +394,6 @@ svga_buffer_add_range(struct svga_buffer *sbuf, } -static void * -svga_buffer_map_range( struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned offset, unsigned length, - unsigned usage ) -{ - struct svga_screen *ss = svga_screen(screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_buffer *sbuf = svga_buffer( buf ); - void *map; - - if (!sbuf->swbuf && !sbuf->hwbuf) { - if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) { - /* - * We can't create a hardware buffer big enough, so create a malloc - * buffer instead. - */ - - debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n", - __FUNCTION__, - (sbuf->base.size + 1023)/1024); - - sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment); - } - } - - if (sbuf->swbuf) { - /* User/malloc buffer */ - map = sbuf->swbuf; - } - else if (sbuf->hwbuf) { - map = sws->buffer_map(sws, sbuf->hwbuf, usage); - } - else { - map = NULL; - } - - if(map) { - pipe_mutex_lock(ss->swc_mutex); - - ++sbuf->map.count; - - if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) { - assert(sbuf->map.count <= 1); - sbuf->map.writing = TRUE; - if (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) - sbuf->map.flush_explicit = TRUE; - } - - pipe_mutex_unlock(ss->swc_mutex); - } - - return map; -} - -static void -svga_buffer_flush_mapped_range( struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned offset, unsigned length) -{ - struct svga_buffer *sbuf = svga_buffer( buf ); - struct svga_screen *ss = svga_screen(screen); - - pipe_mutex_lock(ss->swc_mutex); - assert(sbuf->map.writing); - if(sbuf->map.writing) { - assert(sbuf->map.flush_explicit); - svga_buffer_add_range(sbuf, offset, offset + length); - } - pipe_mutex_unlock(ss->swc_mutex); -} - -static void -svga_buffer_unmap( struct pipe_screen *screen, - struct pipe_buffer *buf) -{ - struct svga_screen *ss = svga_screen(screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_buffer *sbuf = svga_buffer( buf ); - - pipe_mutex_lock(ss->swc_mutex); - - assert(sbuf->map.count); - if(sbuf->map.count) - --sbuf->map.count; - - if(sbuf->hwbuf) - sws->buffer_unmap(sws, sbuf->hwbuf); - - if(sbuf->map.writing) { - if(!sbuf->map.flush_explicit) { - /* No mapped range was flushed -- flush the whole buffer */ - SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n"); - - svga_buffer_add_range(sbuf, 0, sbuf->base.size); - } - - sbuf->map.writing = FALSE; - sbuf->map.flush_explicit = FALSE; - } - - pipe_mutex_unlock(ss->swc_mutex); -} - -static void -svga_buffer_destroy( struct pipe_buffer *buf ) -{ - struct svga_screen *ss = svga_screen(buf->screen); - struct svga_buffer *sbuf = svga_buffer( buf ); - - assert(!p_atomic_read(&buf->reference.count)); - - assert(!sbuf->dma.pending); - - if(sbuf->handle) - svga_buffer_destroy_host_surface(ss, sbuf); - - if(sbuf->uploaded.buffer) - pipe_buffer_reference(&sbuf->uploaded.buffer, NULL); - - if(sbuf->hwbuf) - svga_buffer_destroy_hw_storage(ss, sbuf); - - if(sbuf->swbuf && !sbuf->user) - align_free(sbuf->swbuf); - - FREE(sbuf); -} - -static struct pipe_buffer * -svga_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct svga_screen *ss = svga_screen(screen); - struct svga_buffer *sbuf; - - assert(size); - assert(alignment); - - sbuf = CALLOC_STRUCT(svga_buffer); - if(!sbuf) - goto error1; - - sbuf->magic = SVGA_BUFFER_MAGIC; - - pipe_reference_init(&sbuf->base.reference, 1); - sbuf->base.screen = screen; - sbuf->base.alignment = alignment; - sbuf->base.usage = usage; - sbuf->base.size = size; - - if(svga_buffer_needs_hw_storage(usage)) { - if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK) - goto error2; - } - else { - if(alignment < sizeof(void*)) - alignment = sizeof(void*); - - usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - - sbuf->swbuf = align_malloc(size, alignment); - if(!sbuf->swbuf) - goto error2; - } - - return &sbuf->base; - -error2: - FREE(sbuf); -error1: - return NULL; -} - -static struct pipe_buffer * -svga_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct svga_buffer *sbuf; - - sbuf = CALLOC_STRUCT(svga_buffer); - if(!sbuf) - goto no_sbuf; - - sbuf->magic = SVGA_BUFFER_MAGIC; - - sbuf->swbuf = ptr; - sbuf->user = TRUE; - - pipe_reference_init(&sbuf->base.reference, 1); - sbuf->base.screen = screen; - sbuf->base.alignment = 1; - sbuf->base.usage = 0; - sbuf->base.size = bytes; - - return &sbuf->base; - -no_sbuf: - return NULL; -} - - -void -svga_screen_init_buffer_functions(struct pipe_screen *screen) -{ - screen->buffer_create = svga_buffer_create; - screen->user_buffer_create = svga_user_buffer_create; - screen->buffer_map_range = svga_buffer_map_range; - screen->buffer_flush_mapped_range = svga_buffer_flush_mapped_range; - screen->buffer_unmap = svga_buffer_unmap; - screen->buffer_destroy = svga_buffer_destroy; -} - /** * Copy the contents of the malloc buffer to a hardware buffer. @@ -637,7 +415,7 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) return ret; pipe_mutex_lock(ss->swc_mutex); - map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); + map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_TRANSFER_WRITE); assert(map); if(!map) { pipe_mutex_unlock(ss->swc_mutex); @@ -645,7 +423,7 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf) return PIPE_ERROR; } - memcpy(map, sbuf->swbuf, sbuf->base.size); + memcpy(map, sbuf->swbuf, sbuf->b.b.width0); ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf); /* This user/malloc buffer is now indistinguishable from a gpu buffer */ @@ -710,8 +488,8 @@ svga_buffer_upload_piecewise(struct svga_screen *ss, offset, offset + size); map = sws->buffer_map(sws, hwbuf, - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_DISCARD); + PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_DISCARD); assert(map); if (map) { memcpy(map, sbuf->swbuf, size); @@ -745,9 +523,14 @@ svga_buffer_upload_piecewise(struct svga_screen *ss, } + + +/* Get (or create/upload) the winsys surface handle so that we can + * refer to this buffer in fifo commands. + */ struct svga_winsys_surface * svga_buffer_handle(struct svga_context *svga, - struct pipe_buffer *buf) + struct pipe_resource *buf) { struct pipe_screen *screen = svga->pipe.screen; struct svga_screen *ss = svga_screen(screen); @@ -828,45 +611,6 @@ svga_buffer_handle(struct svga_context *svga, } -struct pipe_buffer * -svga_screen_buffer_wrap_surface(struct pipe_screen *screen, - enum SVGA3dSurfaceFormat format, - struct svga_winsys_surface *srf) -{ - struct pipe_buffer *buf; - struct svga_buffer *sbuf; - struct svga_winsys_screen *sws = svga_winsys_screen(screen); - - buf = svga_buffer_create(screen, 0, SVGA_BUFFER_USAGE_WRAPPED, 0); - if (!buf) - return NULL; - - sbuf = svga_buffer(buf); - - /* - * We are not the creator of this surface and therefore we must not - * cache it for reuse. Set the cacheable flag to zero in the key to - * prevent this. - */ - sbuf->key.format = format; - sbuf->key.cachable = 0; - sws->surface_reference(sws, &sbuf->handle, srf); - - return buf; -} - - -struct svga_winsys_surface * -svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer) -{ - struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen); - struct svga_winsys_surface *vsurf = NULL; - - assert(svga_buffer(buffer)->key.cachable == 0); - svga_buffer(buffer)->key.cachable = 0; - sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle); - return vsurf; -} void svga_context_flush_buffers(struct svga_context *svga) @@ -879,7 +623,7 @@ svga_context_flush_buffers(struct svga_context *svga) while(curr != &svga->dirty_buffers) { sbuf = LIST_ENTRY(struct svga_buffer, curr, head); - assert(p_atomic_read(&sbuf->base.reference.count) != 0); + assert(p_atomic_read(&sbuf->b.b.reference.count) != 0); assert(sbuf->dma.pending); svga_buffer_upload_flush(svga, sbuf); diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.h b/src/gallium/drivers/svga/svga_resource_buffer_upload.h new file mode 100644 index 00000000000..11df3065263 --- /dev/null +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.h @@ -0,0 +1,54 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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. + * + **********************************************************/ + +#ifndef SVGA_BUFFER_UPLOAD_H +#define SVGA_BUFFER_UPLOAD_H + + +void +svga_buffer_add_range(struct svga_buffer *sbuf, + unsigned start, + unsigned end); + +enum pipe_error +svga_buffer_create_hw_storage(struct svga_screen *ss, + struct svga_buffer *sbuf); + +void +svga_buffer_destroy_hw_storage(struct svga_screen *ss, + struct svga_buffer *sbuf); + +enum pipe_error +svga_buffer_create_host_surface(struct svga_screen *ss, + struct svga_buffer *sbuf); + +void +svga_buffer_destroy_host_surface(struct svga_screen *ss, + struct svga_buffer *sbuf); + + + + +#endif /* SVGA_BUFFER_H */ diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c new file mode 100644 index 00000000000..fd008bda092 --- /dev/null +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -0,0 +1,635 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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 "svga_cmd.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "svga_screen.h" +#include "svga_context.h" +#include "svga_resource_texture.h" +#include "svga_resource_buffer.h" +#include "svga_sampler_view.h" +#include "svga_winsys.h" +#include "svga_debug.h" + +#include <util/u_string.h> + + +/* XXX: This isn't a real hardware flag, but just a hack for kernel to + * know about primary surfaces. Find a better way to accomplish this. + */ +#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9) + + +static unsigned int +svga_texture_is_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, + unsigned face, unsigned level) +{ + struct svga_texture *tex = svga_texture(texture); + struct svga_screen *ss = svga_screen(pipe->screen); + + /** + * The screen does not cache texture writes. + */ + + if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle)) + return PIPE_UNREFERENCED; + + /** + * sws->surface_is_flushed() does not distinguish between read references + * and write references. So assume a reference is both. + */ + + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + + + +/* + * Helper function and arrays + */ + +SVGA3dSurfaceFormat +svga_translate_format(enum pipe_format format) +{ + switch(format) { + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return SVGA3D_A8R8G8B8; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return SVGA3D_X8R8G8B8; + + /* Required for GL2.1: + */ + case PIPE_FORMAT_B8G8R8A8_SRGB: + return SVGA3D_A8R8G8B8; + + case PIPE_FORMAT_B5G6R5_UNORM: + return SVGA3D_R5G6B5; + case PIPE_FORMAT_B5G5R5A1_UNORM: + return SVGA3D_A1R5G5B5; + case PIPE_FORMAT_B4G4R4A4_UNORM: + return SVGA3D_A4R4G4B4; + + + /* XXX: Doesn't seem to work properly. + case PIPE_FORMAT_Z32_UNORM: + return SVGA3D_Z_D32; + */ + case PIPE_FORMAT_Z16_UNORM: + return SVGA3D_Z_D16; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return SVGA3D_Z_D24S8; + case PIPE_FORMAT_X8Z24_UNORM: + return SVGA3D_Z_D24X8; + + case PIPE_FORMAT_A8_UNORM: + return SVGA3D_ALPHA8; + case PIPE_FORMAT_L8_UNORM: + return SVGA3D_LUMINANCE8; + + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + return SVGA3D_DXT1; + case PIPE_FORMAT_DXT3_RGBA: + return SVGA3D_DXT3; + case PIPE_FORMAT_DXT5_RGBA: + return SVGA3D_DXT5; + + default: + return SVGA3D_FORMAT_INVALID; + } +} + + +SVGA3dSurfaceFormat +svga_translate_format_render(enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_L8_UNORM: + return svga_translate_format(format); + +#if 1 + /* For on host conversion */ + case PIPE_FORMAT_DXT1_RGB: + return SVGA3D_X8R8G8B8; + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return SVGA3D_A8R8G8B8; +#endif + + default: + return SVGA3D_FORMAT_INVALID; + } +} + + +static INLINE void +svga_transfer_dma_band(struct svga_transfer *st, + SVGA3dTransferType transfer, + unsigned y, unsigned h, unsigned srcy) +{ + struct svga_texture *texture = svga_texture(st->base.resource); + struct svga_screen *screen = svga_screen(texture->b.b.screen); + SVGA3dCopyBox box; + enum pipe_error ret; + + SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n", + transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from", + texture->handle, + st->base.sr.face, + st->base.box.x, + y, + st->base.box.z, + st->base.box.x + st->base.box.width, + y + h, + st->base.box.z + 1, + util_format_get_blocksize(texture->b.b.format) * 8 / + (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format))); + + box.x = st->base.box.x; + box.y = y; + box.z = st->base.box.z; + box.w = st->base.box.width; + box.h = h; + box.d = 1; + box.srcx = 0; + box.srcy = srcy; + box.srcz = 0; + + pipe_mutex_lock(screen->swc_mutex); + ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); + if(ret != PIPE_OK) { + screen->swc->flush(screen->swc, NULL); + ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); + assert(ret == PIPE_OK); + } + pipe_mutex_unlock(screen->swc_mutex); +} + + +static INLINE void +svga_transfer_dma(struct svga_transfer *st, + SVGA3dTransferType transfer) +{ + struct svga_texture *texture = svga_texture(st->base.resource); + struct svga_screen *screen = svga_screen(texture->b.b.screen); + struct svga_winsys_screen *sws = screen->sws; + struct pipe_fence_handle *fence = NULL; + + if (transfer == SVGA3D_READ_HOST_VRAM) { + SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__); + } + + + if(!st->swbuf) { + /* Do the DMA transfer in a single go */ + + svga_transfer_dma_band(st, transfer, st->base.box.y, st->base.box.height, 0); + + if(transfer == SVGA3D_READ_HOST_VRAM) { + svga_screen_flush(screen, &fence); + sws->fence_finish(sws, fence, 0); + sws->fence_reference(sws, &fence, NULL); + } + } + else { + unsigned y, h, srcy; + unsigned blockheight = util_format_get_blockheight(st->base.resource->format); + h = st->hw_nblocksy * blockheight; + srcy = 0; + for(y = 0; y < st->base.box.height; y += h) { + unsigned offset, length; + void *hw, *sw; + + if (y + h > st->base.box.height) + h = st->base.box.height - y; + + /* Transfer band must be aligned to pixel block boundaries */ + assert(y % blockheight == 0); + assert(h % blockheight == 0); + + offset = y * st->base.stride / blockheight; + length = h * st->base.stride / blockheight; + + sw = (uint8_t *)st->swbuf + offset; + + if(transfer == SVGA3D_WRITE_HOST_VRAM) { + /* Wait for the previous DMAs to complete */ + /* TODO: keep one DMA (at half the size) in the background */ + if(y) { + svga_screen_flush(screen, &fence); + sws->fence_finish(sws, fence, 0); + sws->fence_reference(sws, &fence, NULL); + } + + hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_WRITE); + assert(hw); + if(hw) { + memcpy(hw, sw, length); + sws->buffer_unmap(sws, st->hwbuf); + } + } + + svga_transfer_dma_band(st, transfer, y, h, srcy); + + if(transfer == SVGA3D_READ_HOST_VRAM) { + svga_screen_flush(screen, &fence); + sws->fence_finish(sws, fence, 0); + + hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ); + assert(hw); + if(hw) { + memcpy(sw, hw, length); + sws->buffer_unmap(sws, st->hwbuf); + } + } + } + } +} + + + + + +static boolean +svga_texture_get_handle(struct pipe_screen *screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) +{ + struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen); + unsigned stride; + + assert(svga_texture(texture)->key.cachable == 0); + svga_texture(texture)->key.cachable = 0; + stride = util_format_get_nblocksx(texture->format, texture->width0) * + util_format_get_blocksize(texture->format); + return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle); +} + + +static void +svga_texture_destroy(struct pipe_screen *screen, + struct pipe_resource *pt) +{ + struct svga_screen *ss = svga_screen(screen); + struct svga_texture *tex = (struct svga_texture *)pt; + + ss->texture_timestamp++; + + svga_sampler_view_reference(&tex->cached_view, NULL); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); + */ + SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); + svga_screen_surface_destroy(ss, &tex->key, &tex->handle); + + FREE(tex); +} + + + + + + + +/* XXX: Still implementing this as if it was a screen function, but + * can now modify it to queue transfers on the context. + */ +static struct pipe_transfer * +svga_texture_get_transfer(struct pipe_context *pipe, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_transfer *st; + unsigned nblocksx = util_format_get_nblocksx(texture->format, box->width); + unsigned nblocksy = util_format_get_nblocksy(texture->format, box->height); + + /* We can't map texture storage directly */ + if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + return NULL; + + st = CALLOC_STRUCT(svga_transfer); + if (!st) + return NULL; + + pipe_resource_reference(&st->base.resource, texture); + st->base.sr = sr; + st->base.usage = usage; + st->base.box = *box; + st->base.stride = nblocksx*util_format_get_blocksize(texture->format); + st->base.slice_stride = 0; + + st->hw_nblocksy = nblocksy; + + st->hwbuf = svga_winsys_buffer_create(ss, + 1, + 0, + st->hw_nblocksy*st->base.stride); + while(!st->hwbuf && (st->hw_nblocksy /= 2)) { + st->hwbuf = svga_winsys_buffer_create(ss, + 1, + 0, + st->hw_nblocksy*st->base.stride); + } + + if(!st->hwbuf) + goto no_hwbuf; + + if(st->hw_nblocksy < nblocksy) { + /* We couldn't allocate a hardware buffer big enough for the transfer, + * so allocate regular malloc memory instead */ + debug_printf("%s: failed to allocate %u KB of DMA, splitting into %u x %u KB DMA transfers\n", + __FUNCTION__, + (nblocksy*st->base.stride + 1023)/1024, + (nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy, + (st->hw_nblocksy*st->base.stride + 1023)/1024); + st->swbuf = MALLOC(nblocksy*st->base.stride); + if(!st->swbuf) + goto no_swbuf; + } + + if (usage & PIPE_TRANSFER_READ) + svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM); + + return &st->base; + +no_swbuf: + sws->buffer_destroy(sws, st->hwbuf); +no_hwbuf: + FREE(st); + return NULL; +} + + +/* XXX: Still implementing this as if it was a screen function, but + * can now modify it to queue transfers on the context. + */ +static void * +svga_texture_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_transfer *st = svga_transfer(transfer); + + if(st->swbuf) + return st->swbuf; + else + /* The wait for read transfers already happened when svga_transfer_dma + * was called. */ + return sws->buffer_map(sws, st->hwbuf, transfer->usage); +} + + +/* XXX: Still implementing this as if it was a screen function, but + * can now modify it to queue transfers on the context. + */ +static void +svga_texture_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_transfer *st = svga_transfer(transfer); + + if(!st->swbuf) + sws->buffer_unmap(sws, st->hwbuf); +} + + +static void +svga_texture_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct svga_texture *tex = svga_texture(transfer->resource); + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_screen *sws = ss->sws; + struct svga_transfer *st = svga_transfer(transfer); + + if (st->base.usage & PIPE_TRANSFER_WRITE) { + svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM); + ss->texture_timestamp++; + tex->view_age[transfer->sr.level] = ++(tex->age); + tex->defined[transfer->sr.face][transfer->sr.level] = TRUE; + } + + pipe_resource_reference(&st->base.resource, NULL); + FREE(st->swbuf); + sws->buffer_destroy(sws, st->hwbuf); + FREE(st); +} + + + + + +struct u_resource_vtbl svga_texture_vtbl = +{ + svga_texture_get_handle, /* get_handle */ + svga_texture_destroy, /* resource_destroy */ + svga_texture_is_referenced, /* is_resource_referenced */ + svga_texture_get_transfer, /* get_transfer */ + svga_texture_transfer_destroy, /* transfer_destroy */ + svga_texture_transfer_map, /* transfer_map */ + u_default_transfer_flush_region, /* transfer_flush_region */ + svga_texture_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + + + + +struct pipe_resource * +svga_texture_create(struct pipe_screen *screen, + const struct pipe_resource *template) +{ + struct svga_screen *svgascreen = svga_screen(screen); + struct svga_texture *tex = CALLOC_STRUCT(svga_texture); + + if (!tex) + goto error1; + + tex->b.b = *template; + tex->b.vtbl = &svga_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; + + assert(template->last_level < SVGA_MAX_TEXTURE_LEVELS); + if(template->last_level >= SVGA_MAX_TEXTURE_LEVELS) + goto error2; + + tex->key.flags = 0; + tex->key.size.width = template->width0; + tex->key.size.height = template->height0; + tex->key.size.depth = template->depth0; + + if(template->target == PIPE_TEXTURE_CUBE) { + tex->key.flags |= SVGA3D_SURFACE_CUBEMAP; + tex->key.numFaces = 6; + } + else { + tex->key.numFaces = 1; + } + + tex->key.cachable = 1; + + if (template->bind & PIPE_BIND_SAMPLER_VIEW) + tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; + + if (template->bind & PIPE_BIND_DISPLAY_TARGET) { + tex->key.cachable = 0; + } + + if (template->bind & PIPE_BIND_SHARED) { + tex->key.cachable = 0; + } + + if (template->bind & PIPE_BIND_SCANOUT) { + tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; + tex->key.cachable = 0; + } + + /* + * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot + * know beforehand whether a texture will be used as a rendertarget or not + * and it always requests PIPE_BIND_RENDER_TARGET, therefore + * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose. + */ +#if 0 + if((template->bind & PIPE_BIND_RENDER_TARGET) && + !util_format_is_s3tc(template->format)) + tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; +#endif + + if(template->bind & PIPE_BIND_DEPTH_STENCIL) + tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; + + tex->key.numMipLevels = template->last_level + 1; + + tex->key.format = svga_translate_format(template->format); + if(tex->key.format == SVGA3D_FORMAT_INVALID) + goto error2; + + SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle); + tex->handle = svga_screen_surface_create(svgascreen, &tex->key); + if (tex->handle) + SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle); + + return &tex->b.b; + +error2: + FREE(tex); +error1: + return NULL; +} + + + + +struct pipe_resource * +svga_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) +{ + struct svga_winsys_screen *sws = svga_winsys_screen(screen); + struct svga_winsys_surface *srf; + struct svga_texture *tex; + enum SVGA3dSurfaceFormat format = 0; + assert(screen); + + /* Only supports one type */ + if (template->target != PIPE_TEXTURE_2D || + template->last_level != 0 || + template->depth0 != 1) { + return NULL; + } + + srf = sws->surface_from_handle(sws, whandle, &format); + + if (!srf) + return NULL; + + if (svga_translate_format(template->format) != format) { + unsigned f1 = svga_translate_format(template->format); + unsigned f2 = format; + + /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */ + if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) || + (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) || + (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) { + debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2); + return NULL; + } + } + + tex = CALLOC_STRUCT(svga_texture); + if (!tex) + return NULL; + + tex->b.b = *template; + tex->b.vtbl = &svga_texture_vtbl; + pipe_reference_init(&tex->b.b.reference, 1); + tex->b.b.screen = screen; + + if (format == SVGA3D_X8R8G8B8) + tex->b.b.format = PIPE_FORMAT_B8G8R8X8_UNORM; + else if (format == SVGA3D_A8R8G8B8) + tex->b.b.format = PIPE_FORMAT_B8G8R8A8_UNORM; + else { + /* ?? */ + } + + SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf); + + tex->key.cachable = 0; + tex->handle = srf; + + return &tex->b.b; +} + diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_resource_texture.h index 96d035b12d8..631937f2eb0 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.h +++ b/src/gallium/drivers/svga/svga_resource_texture.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_transfer.h" #include "svga_screen_cache.h" struct pipe_context; @@ -42,41 +43,12 @@ enum SVGA3dSurfaceFormat; #define SVGA_MAX_TEXTURE_LEVELS 16 -/** - * A sampler's view into a texture - * - * We currently cache one sampler view on - * the texture and in there by holding a reference - * from the texture to the sampler view. - * - * Because of this we can not hold a refernce to the - * texture from the sampler view. So the user - * of the sampler views must make sure that the - * texture has a reference take for as long as - * the sampler view is refrenced. - * - * Just unreferencing the sampler_view before the - * texture is enough. - */ -struct svga_sampler_view -{ - struct pipe_reference reference; - - struct pipe_texture *texture; - - int min_lod; - int max_lod; - - unsigned age; - - struct svga_host_surface_cache_key key; - struct svga_winsys_surface *handle; -}; +extern struct u_resource_vtbl svga_texture_vtbl; struct svga_texture { - struct pipe_texture base; + struct u_resource b; boolean defined[6][SVGA_MAX_TEXTURE_LEVELS]; @@ -106,21 +78,9 @@ struct svga_texture }; -struct svga_surface -{ - struct pipe_surface base; - - struct svga_host_surface_cache_key key; - struct svga_winsys_surface *handle; - - unsigned real_face; - unsigned real_level; - unsigned real_zslice; - - boolean dirty; -}; - +/* Note this is only used for texture (not buffer) transfers: + */ struct svga_transfer { struct pipe_transfer base; @@ -136,18 +96,13 @@ struct svga_transfer }; -static INLINE struct svga_texture * -svga_texture(struct pipe_texture *texture) +static INLINE struct svga_texture *svga_texture( struct pipe_resource *resource ) { - return (struct svga_texture *)texture; + struct svga_texture *tex = (struct svga_texture *)resource; + assert(tex == NULL || tex->b.vtbl == &svga_texture_vtbl); + return tex; } -static INLINE struct svga_surface * -svga_surface(struct pipe_surface *surface) -{ - assert(surface); - return (struct svga_surface *)surface; -} static INLINE struct svga_transfer * svga_transfer(struct pipe_transfer *transfer) @@ -156,38 +111,18 @@ svga_transfer(struct pipe_transfer *transfer) return (struct svga_transfer *)transfer; } -extern struct svga_sampler_view * -svga_get_tex_sampler_view(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned min_lod, unsigned max_lod); - -void -svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v); - -void -svga_destroy_sampler_view_priv(struct svga_sampler_view *v); -static INLINE void -svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v) -{ - struct svga_sampler_view *old = *ptr; - - if (pipe_reference(&(*ptr)->reference, &v->reference)) - svga_destroy_sampler_view_priv(old); - *ptr = v; -} -extern void -svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf); +struct pipe_resource * +svga_texture_create(struct pipe_screen *screen, + const struct pipe_resource *template); -extern boolean -svga_surface_needs_propagation(struct pipe_surface *surf); +struct pipe_resource * +svga_texture_from_handle(struct pipe_screen * screen, + const struct pipe_resource *template, + struct winsys_handle *whandle); -extern void -svga_screen_init_texture_functions(struct pipe_screen *screen); -void -svga_init_texture_functions(struct pipe_context *pipe); enum SVGA3dSurfaceFormat svga_translate_format(enum pipe_format format); diff --git a/src/gallium/drivers/svga/svga_sampler_view.c b/src/gallium/drivers/svga/svga_sampler_view.c new file mode 100644 index 00000000000..5386db7d1b4 --- /dev/null +++ b/src/gallium/drivers/svga/svga_sampler_view.c @@ -0,0 +1,199 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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 "svga_cmd.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "svga_screen.h" +#include "svga_context.h" +#include "svga_resource_texture.h" +#include "svga_sampler_view.h" +#include "svga_winsys.h" +#include "svga_debug.h" +#include "svga_surface.h" + +#include <util/u_string.h> + + +struct svga_sampler_view * +svga_get_tex_sampler_view(struct pipe_context *pipe, + struct pipe_resource *pt, + unsigned min_lod, unsigned max_lod) +{ + struct svga_screen *ss = svga_screen(pt->screen); + struct svga_texture *tex = svga_texture(pt); + struct svga_sampler_view *sv = NULL; + SVGA3dSurfaceFormat format = svga_translate_format(pt->format); + boolean view = TRUE; + + assert(pt); + assert(min_lod >= 0); + assert(min_lod <= max_lod); + assert(max_lod <= pt->last_level); + + + /* Is a view needed */ + { + /* + * Can't control max lod. For first level views and when we only + * look at one level we disable mip filtering to achive the same + * results as a view. + */ + if (min_lod == 0 && max_lod >= pt->last_level) + view = FALSE; + + if (util_format_is_s3tc(pt->format) && view) { + format = svga_translate_format_render(pt->format); + } + + if (ss->debug.no_sampler_view) + view = FALSE; + + if (ss->debug.force_sampler_view) + view = TRUE; + } + + /* First try the cache */ + if (view) { + pipe_mutex_lock(ss->tex_mutex); + if (tex->cached_view && + tex->cached_view->min_lod == min_lod && + tex->cached_view->max_lod == max_lod) { + svga_sampler_view_reference(&sv, tex->cached_view); + pipe_mutex_unlock(ss->tex_mutex); + SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n", + pt, min_lod, max_lod, pt->last_level); + svga_validate_sampler_view(svga_context(pipe), sv); + return sv; + } + pipe_mutex_unlock(ss->tex_mutex); + } + + sv = CALLOC_STRUCT(svga_sampler_view); + pipe_reference_init(&sv->reference, 1); + pipe_resource_reference(&sv->texture, pt); + sv->min_lod = min_lod; + sv->max_lod = max_lod; + + /* No view needed just use the whole texture */ + if (!view) { + SVGA_DBG(DEBUG_VIEWS, + "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", + pt, min_lod, max_lod, + max_lod - min_lod + 1, + pt->width0, + pt->height0, + pt->depth0, + pt->last_level); + sv->key.cachable = 0; + sv->handle = tex->handle; + return sv; + } + + SVGA_DBG(DEBUG_VIEWS, + "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", + pt, min_lod, max_lod, + max_lod - min_lod + 1, + pt->width0, + pt->height0, + pt->depth0, + pt->last_level); + + sv->age = tex->age; + sv->handle = svga_texture_view_surface(pipe, tex, format, + min_lod, + max_lod - min_lod + 1, + -1, -1, + &sv->key); + + if (!sv->handle) { + assert(0); + sv->key.cachable = 0; + sv->handle = tex->handle; + return sv; + } + + pipe_mutex_lock(ss->tex_mutex); + svga_sampler_view_reference(&tex->cached_view, sv); + pipe_mutex_unlock(ss->tex_mutex); + + return sv; +} + +void +svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v) +{ + struct svga_texture *tex = svga_texture(v->texture); + unsigned numFaces; + unsigned age = 0; + int i, k; + + assert(svga); + + if (v->handle == tex->handle) + return; + + age = tex->age; + + if(tex->b.b.target == PIPE_TEXTURE_CUBE) + numFaces = 6; + else + numFaces = 1; + + for (i = v->min_lod; i <= v->max_lod; i++) { + for (k = 0; k < numFaces; k++) { + if (v->age < tex->view_age[i]) + svga_texture_copy_handle(svga, NULL, + tex->handle, 0, 0, 0, i, k, + v->handle, 0, 0, 0, i - v->min_lod, k, + u_minify(tex->b.b.width0, i), + u_minify(tex->b.b.height0, i), + u_minify(tex->b.b.depth0, i)); + } + } + + v->age = age; +} + +void +svga_destroy_sampler_view_priv(struct svga_sampler_view *v) +{ + struct svga_texture *tex = svga_texture(v->texture); + + if(v->handle != tex->handle) { + struct svga_screen *ss = svga_screen(v->texture->screen); + SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle); + svga_screen_surface_destroy(ss, &v->key, &v->handle); + } + pipe_resource_reference(&v->texture, NULL); + FREE(v); +} diff --git a/src/gallium/drivers/svga/svga_sampler_view.h b/src/gallium/drivers/svga/svga_sampler_view.h new file mode 100644 index 00000000000..e64665f2e58 --- /dev/null +++ b/src/gallium/drivers/svga/svga_sampler_view.h @@ -0,0 +1,97 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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. + * + **********************************************************/ + +#ifndef SVGA_SAMPLER_VIEW_H +#define SVGA_SAMPLER_VIEW_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "util/u_inlines.h" +#include "svga_screen_cache.h" + +struct pipe_context; +struct pipe_screen; +struct svga_context; +struct svga_winsys_surface; +enum SVGA3dSurfaceFormat; + + +/** + * A sampler's view into a texture + * + * We currently cache one sampler view on + * the texture and in there by holding a reference + * from the texture to the sampler view. + * + * Because of this we can not hold a refernce to the + * texture from the sampler view. So the user + * of the sampler views must make sure that the + * texture has a reference take for as long as + * the sampler view is refrenced. + * + * Just unreferencing the sampler_view before the + * texture is enough. + */ +struct svga_sampler_view +{ + struct pipe_reference reference; + + struct pipe_resource *texture; + + int min_lod; + int max_lod; + + unsigned age; + + struct svga_host_surface_cache_key key; + struct svga_winsys_surface *handle; +}; + + + +extern struct svga_sampler_view * +svga_get_tex_sampler_view(struct pipe_context *pipe, + struct pipe_resource *pt, + unsigned min_lod, unsigned max_lod); + +void +svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v); + +void +svga_destroy_sampler_view_priv(struct svga_sampler_view *v); + +static INLINE void +svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v) +{ + struct svga_sampler_view *old = *ptr; + + if (pipe_reference(&(*ptr)->reference, &v->reference)) + svga_destroy_sampler_view_priv(old); + *ptr = v; +} + + +#endif diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 9a2e7c6f5b0..9a75e456cf5 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -31,8 +31,9 @@ #include "svga_winsys.h" #include "svga_context.h" #include "svga_screen.h" -#include "svga_screen_texture.h" -#include "svga_screen_buffer.h" +#include "svga_resource_texture.h" +#include "svga_resource_buffer.h" +#include "svga_resource.h" #include "svga_debug.h" #include "svga3d_shaderdefs.h" @@ -248,7 +249,7 @@ svga_is_format_supported( struct pipe_screen *screen, assert(tex_usage); /* Override host capabilities */ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch(format) { /* Often unsupported/problematic. This means we end up with the same @@ -278,11 +279,11 @@ svga_is_format_supported( struct pipe_screen *screen, SVGA3dSurfaceFormatCaps mask; mask.value = 0; - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) + if (tex_usage & PIPE_BIND_RENDER_TARGET) mask.offscreenRenderTarget = 1; - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) + if (tex_usage & PIPE_BIND_DEPTH_STENCIL) mask.zStencil = 1; - if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) + if (tex_usage & PIPE_BIND_SAMPLER_VIEW) mask.texture = 1; if ((result.u & mask.value) == mask.value) @@ -295,7 +296,7 @@ svga_is_format_supported( struct pipe_screen *screen, * duplicated list of supported formats which is prone to getting * out of sync: */ - if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) + if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; else return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; @@ -397,8 +398,7 @@ svga_screen_create(struct svga_winsys_screen *sws) screen->fence_finish = svga_fence_finish; svgascreen->sws = sws; - svga_screen_init_texture_functions(screen); - svga_screen_init_buffer_functions(screen); + svga_init_screen_resource_functions(svgascreen); svgascreen->use_ps30 = sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c deleted file mode 100644 index 811c7466956..00000000000 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ /dev/null @@ -1,1097 +0,0 @@ -/********************************************************** - * Copyright 2008-2009 VMware, Inc. All rights reserved. - * - * 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 the rights to use, copy, - * modify, merge, publish, distribute, sublicense, 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 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 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * 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 "svga_cmd.h" - -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "os/os_thread.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" - -#include "svga_screen.h" -#include "svga_context.h" -#include "svga_screen_texture.h" -#include "svga_screen_buffer.h" -#include "svga_winsys.h" -#include "svga_debug.h" -#include "svga_screen_buffer.h" - - -/* XXX: This isn't a real hardware flag, but just a hack for kernel to - * know about primary surfaces. Find a better way to accomplish this. - */ -#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9) - - -/* - * Helper function and arrays - */ - -SVGA3dSurfaceFormat -svga_translate_format(enum pipe_format format) -{ - switch(format) { - - case PIPE_FORMAT_B8G8R8A8_UNORM: - return SVGA3D_A8R8G8B8; - case PIPE_FORMAT_B8G8R8X8_UNORM: - return SVGA3D_X8R8G8B8; - - /* Required for GL2.1: - */ - case PIPE_FORMAT_B8G8R8A8_SRGB: - return SVGA3D_A8R8G8B8; - - case PIPE_FORMAT_B5G6R5_UNORM: - return SVGA3D_R5G6B5; - case PIPE_FORMAT_B5G5R5A1_UNORM: - return SVGA3D_A1R5G5B5; - case PIPE_FORMAT_B4G4R4A4_UNORM: - return SVGA3D_A4R4G4B4; - - - /* XXX: Doesn't seem to work properly. - case PIPE_FORMAT_Z32_UNORM: - return SVGA3D_Z_D32; - */ - case PIPE_FORMAT_Z16_UNORM: - return SVGA3D_Z_D16; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return SVGA3D_Z_D24S8; - case PIPE_FORMAT_X8Z24_UNORM: - return SVGA3D_Z_D24X8; - - case PIPE_FORMAT_A8_UNORM: - return SVGA3D_ALPHA8; - case PIPE_FORMAT_L8_UNORM: - return SVGA3D_LUMINANCE8; - - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - return SVGA3D_DXT1; - case PIPE_FORMAT_DXT3_RGBA: - return SVGA3D_DXT3; - case PIPE_FORMAT_DXT5_RGBA: - return SVGA3D_DXT5; - - default: - return SVGA3D_FORMAT_INVALID; - } -} - - -SVGA3dSurfaceFormat -svga_translate_format_render(enum pipe_format format) -{ - switch(format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - case PIPE_FORMAT_B4G4R4A4_UNORM: - case PIPE_FORMAT_B5G6R5_UNORM: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_L8_UNORM: - return svga_translate_format(format); - -#if 1 - /* For on host conversion */ - case PIPE_FORMAT_DXT1_RGB: - return SVGA3D_X8R8G8B8; - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return SVGA3D_A8R8G8B8; -#endif - - default: - return SVGA3D_FORMAT_INVALID; - } -} - - -static INLINE void -svga_transfer_dma_band(struct svga_transfer *st, - SVGA3dTransferType transfer, - unsigned y, unsigned h, unsigned srcy) -{ - struct svga_texture *texture = svga_texture(st->base.texture); - struct svga_screen *screen = svga_screen(texture->base.screen); - SVGA3dCopyBox box; - enum pipe_error ret; - - SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n", - transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from", - texture->handle, - st->base.face, - st->base.x, - y, - st->base.zslice, - st->base.x + st->base.width, - y + h, - st->base.zslice + 1, - util_format_get_blocksize(texture->base.format)*8/ - (util_format_get_blockwidth(texture->base.format)*util_format_get_blockheight(texture->base.format))); - - box.x = st->base.x; - box.y = y; - box.z = st->base.zslice; - box.w = st->base.width; - box.h = h; - box.d = 1; - box.srcx = 0; - box.srcy = srcy; - box.srcz = 0; - - pipe_mutex_lock(screen->swc_mutex); - ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); - if(ret != PIPE_OK) { - screen->swc->flush(screen->swc, NULL); - ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); - assert(ret == PIPE_OK); - } - pipe_mutex_unlock(screen->swc_mutex); -} - - -static INLINE void -svga_transfer_dma(struct svga_transfer *st, - SVGA3dTransferType transfer) -{ - struct svga_texture *texture = svga_texture(st->base.texture); - struct svga_screen *screen = svga_screen(texture->base.screen); - struct svga_winsys_screen *sws = screen->sws; - struct pipe_fence_handle *fence = NULL; - - if (transfer == SVGA3D_READ_HOST_VRAM) { - SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__); - } - - - if(!st->swbuf) { - /* Do the DMA transfer in a single go */ - - svga_transfer_dma_band(st, transfer, st->base.y, st->base.height, 0); - - if(transfer == SVGA3D_READ_HOST_VRAM) { - svga_screen_flush(screen, &fence); - sws->fence_finish(sws, fence, 0); - sws->fence_reference(sws, &fence, NULL); - } - } - else { - unsigned y, h, srcy; - unsigned blockheight = util_format_get_blockheight(st->base.texture->format); - h = st->hw_nblocksy * blockheight; - srcy = 0; - for(y = 0; y < st->base.height; y += h) { - unsigned offset, length; - void *hw, *sw; - - if (y + h > st->base.height) - h = st->base.height - y; - - /* Transfer band must be aligned to pixel block boundaries */ - assert(y % blockheight == 0); - assert(h % blockheight == 0); - - offset = y * st->base.stride / blockheight; - length = h * st->base.stride / blockheight; - - sw = (uint8_t *)st->swbuf + offset; - - if(transfer == SVGA3D_WRITE_HOST_VRAM) { - /* Wait for the previous DMAs to complete */ - /* TODO: keep one DMA (at half the size) in the background */ - if(y) { - svga_screen_flush(screen, &fence); - sws->fence_finish(sws, fence, 0); - sws->fence_reference(sws, &fence, NULL); - } - - hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); - assert(hw); - if(hw) { - memcpy(hw, sw, length); - sws->buffer_unmap(sws, st->hwbuf); - } - } - - svga_transfer_dma_band(st, transfer, y, h, srcy); - - if(transfer == SVGA3D_READ_HOST_VRAM) { - svga_screen_flush(screen, &fence); - sws->fence_finish(sws, fence, 0); - - hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_READ); - assert(hw); - if(hw) { - memcpy(sw, hw, length); - sws->buffer_unmap(sws, st->hwbuf); - } - } - } - } -} - - -static struct pipe_texture * -svga_texture_create(struct pipe_screen *screen, - const struct pipe_texture *templat) -{ - struct svga_screen *svgascreen = svga_screen(screen); - struct svga_texture *tex = CALLOC_STRUCT(svga_texture); - unsigned width, height, depth; - unsigned level; - - if (!tex) - goto error1; - - tex->base = *templat; - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; - - assert(templat->last_level < SVGA_MAX_TEXTURE_LEVELS); - if(templat->last_level >= SVGA_MAX_TEXTURE_LEVELS) - goto error2; - - width = templat->width0; - height = templat->height0; - depth = templat->depth0; - for(level = 0; level <= templat->last_level; ++level) { - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); - } - - tex->key.flags = 0; - tex->key.size.width = templat->width0; - tex->key.size.height = templat->height0; - tex->key.size.depth = templat->depth0; - - if(templat->target == PIPE_TEXTURE_CUBE) { - tex->key.flags |= SVGA3D_SURFACE_CUBEMAP; - tex->key.numFaces = 6; - } - else { - tex->key.numFaces = 1; - } - - tex->key.cachable = 1; - - if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) - tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; - - if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - tex->key.cachable = 0; - } - - if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) { - tex->key.cachable = 0; - } - - if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) { - tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; - tex->key.cachable = 0; - } - - /* - * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot - * know beforehand whether a texture will be used as a rendertarget or not - * and it always requests PIPE_TEXTURE_USAGE_RENDER_TARGET, therefore - * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose. - */ -#if 0 - if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) && - !util_format_is_s3tc(templat->format)) - tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; -#endif - - if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) - tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; - - tex->key.numMipLevels = templat->last_level + 1; - - tex->key.format = svga_translate_format(templat->format); - if(tex->key.format == SVGA3D_FORMAT_INVALID) - goto error2; - - SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle); - tex->handle = svga_screen_surface_create(svgascreen, &tex->key); - if (tex->handle) - SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle); - - return &tex->base; - -error2: - FREE(tex); -error1: - return NULL; -} - - - - - -static struct pipe_texture * -svga_screen_texture_from_handle(struct pipe_screen *screen, - const struct pipe_texture *base, - struct winsys_handle *whandle) -{ - struct svga_winsys_screen *sws = svga_winsys_screen(screen); - struct svga_winsys_surface *srf; - struct svga_texture *tex; - enum SVGA3dSurfaceFormat format = 0; - assert(screen); - - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; - } - - srf = sws->surface_from_handle(sws, whandle, &format); - - if (!srf) - return NULL; - - if (svga_translate_format(base->format) != format) { - unsigned f1 = svga_translate_format(base->format); - unsigned f2 = format; - - /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */ - if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) || - (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) || - (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) { - debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2); - return NULL; - } - } - - tex = CALLOC_STRUCT(svga_texture); - if (!tex) - return NULL; - - tex->base = *base; - - - if (format == 1) - tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM; - else if (format == 2) - tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM; - - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; - - SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf); - - tex->key.cachable = 0; - tex->handle = srf; - - return &tex->base; -} - - -static boolean -svga_screen_texture_get_handle(struct pipe_screen *screen, - struct pipe_texture *texture, - struct winsys_handle *whandle) -{ - struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen); - unsigned stride; - - assert(svga_texture(texture)->key.cachable == 0); - svga_texture(texture)->key.cachable = 0; - stride = util_format_get_nblocksx(texture->format, texture->width0) * - util_format_get_blocksize(texture->format); - return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle); -} - - -static void -svga_texture_destroy(struct pipe_texture *pt) -{ - struct svga_screen *ss = svga_screen(pt->screen); - struct svga_texture *tex = (struct svga_texture *)pt; - - ss->texture_timestamp++; - - svga_sampler_view_reference(&tex->cached_view, NULL); - - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); - */ - SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); - svga_screen_surface_destroy(ss, &tex->key, &tex->handle); - - FREE(tex); -} - - -static void -svga_texture_copy_handle(struct svga_context *svga, - struct svga_screen *ss, - struct svga_winsys_surface *src_handle, - unsigned src_x, unsigned src_y, unsigned src_z, - unsigned src_level, unsigned src_face, - struct svga_winsys_surface *dst_handle, - unsigned dst_x, unsigned dst_y, unsigned dst_z, - unsigned dst_level, unsigned dst_face, - unsigned width, unsigned height, unsigned depth) -{ - struct svga_surface dst, src; - enum pipe_error ret; - SVGA3dCopyBox box, *boxes; - - assert(svga || ss); - - src.handle = src_handle; - src.real_level = src_level; - src.real_face = src_face; - src.real_zslice = 0; - - dst.handle = dst_handle; - dst.real_level = dst_level; - dst.real_face = dst_face; - dst.real_zslice = 0; - - box.x = dst_x; - box.y = dst_y; - box.z = dst_z; - box.w = width; - box.h = height; - box.d = depth; - box.srcx = src_x; - box.srcy = src_y; - box.srcz = src_z; - -/* - SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n", - src_handle, src_level, src_x, src_y, src_z, - dst_handle, dst_level, dst_x, dst_y, dst_z); -*/ - - if (svga) { - ret = SVGA3D_BeginSurfaceCopy(svga->swc, - &src.base, - &dst.base, - &boxes, 1); - if(ret != PIPE_OK) { - svga_context_flush(svga, NULL); - ret = SVGA3D_BeginSurfaceCopy(svga->swc, - &src.base, - &dst.base, - &boxes, 1); - assert(ret == PIPE_OK); - } - *boxes = box; - SVGA_FIFOCommitAll(svga->swc); - } else { - pipe_mutex_lock(ss->swc_mutex); - ret = SVGA3D_BeginSurfaceCopy(ss->swc, - &src.base, - &dst.base, - &boxes, 1); - if(ret != PIPE_OK) { - ss->swc->flush(ss->swc, NULL); - ret = SVGA3D_BeginSurfaceCopy(ss->swc, - &src.base, - &dst.base, - &boxes, 1); - assert(ret == PIPE_OK); - } - *boxes = box; - SVGA_FIFOCommitAll(ss->swc); - pipe_mutex_unlock(ss->swc_mutex); - } -} - -static struct svga_winsys_surface * -svga_texture_view_surface(struct pipe_context *pipe, - struct svga_texture *tex, - SVGA3dSurfaceFormat format, - unsigned start_mip, - unsigned num_mip, - int face_pick, - int zslice_pick, - struct svga_host_surface_cache_key *key) /* OUT */ -{ - struct svga_screen *ss = svga_screen(tex->base.screen); - struct svga_winsys_surface *handle; - uint32_t i, j; - unsigned z_offset = 0; - - SVGA_DBG(DEBUG_PERF, - "svga: Create surface view: face %d zslice %d mips %d..%d\n", - face_pick, zslice_pick, start_mip, start_mip+num_mip-1); - - key->flags = 0; - key->format = format; - key->numMipLevels = num_mip; - key->size.width = u_minify(tex->base.width0, start_mip); - key->size.height = u_minify(tex->base.height0, start_mip); - key->size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1; - key->cachable = 1; - assert(key->size.depth == 1); - - if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) { - key->flags |= SVGA3D_SURFACE_CUBEMAP; - key->numFaces = 6; - } else { - key->numFaces = 1; - } - - if(key->format == SVGA3D_FORMAT_INVALID) { - key->cachable = 0; - return NULL; - } - - SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); - handle = svga_screen_surface_create(ss, key); - if (!handle) { - key->cachable = 0; - return NULL; - } - - SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle); - - if (face_pick < 0) - face_pick = 0; - - if (zslice_pick >= 0) - z_offset = zslice_pick; - - for (i = 0; i < key->numMipLevels; i++) { - for (j = 0; j < key->numFaces; j++) { - if(tex->defined[j + face_pick][i + start_mip]) { - unsigned depth = (zslice_pick < 0 ? - u_minify(tex->base.depth0, i + start_mip) : - 1); - - svga_texture_copy_handle(svga_context(pipe), - ss, - tex->handle, - 0, 0, z_offset, - i + start_mip, - j + face_pick, - handle, 0, 0, 0, i, j, - u_minify(tex->base.width0, i + start_mip), - u_minify(tex->base.height0, i + start_mip), - depth); - } - } - } - - return handle; -} - - -static struct pipe_surface * -svga_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct svga_texture *tex = svga_texture(pt); - struct svga_surface *s; - boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE; - boolean view = FALSE; - SVGA3dSurfaceFormat format; - - s = CALLOC_STRUCT(svga_surface); - if (!s) - return NULL; - - pipe_reference_init(&s->base.reference, 1); - pipe_texture_reference(&s->base.texture, pt); - s->base.format = pt->format; - s->base.width = u_minify(pt->width0, level); - s->base.height = u_minify(pt->height0, level); - s->base.usage = flags; - s->base.level = level; - s->base.face = face; - s->base.zslice = zslice; - - if (!render) - format = svga_translate_format(pt->format); - else - format = svga_translate_format_render(pt->format); - - assert(format != SVGA3D_FORMAT_INVALID); - assert(!(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE)); - - - if (svga_screen(screen)->debug.force_surface_view) - view = TRUE; - - /* Currently only used for compressed textures */ - if (render && - format != svga_translate_format(pt->format)) { - view = TRUE; - } - - if (level != 0 && - svga_screen(screen)->debug.force_level_surface_view) - view = TRUE; - - if (pt->target == PIPE_TEXTURE_3D) - view = TRUE; - - if (svga_screen(screen)->debug.no_surface_view) - view = FALSE; - - if (view) { - SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n", - pt, level, face, zslice, s); - - s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice, - &s->key); - s->real_face = 0; - s->real_level = 0; - s->real_zslice = 0; - } else { - SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n", - pt, level, face, zslice, s); - - memset(&s->key, 0, sizeof s->key); - s->handle = tex->handle; - s->real_face = face; - s->real_level = level; - s->real_zslice = zslice; - } - - return &s->base; -} - - -static void -svga_tex_surface_destroy(struct pipe_surface *surf) -{ - struct svga_surface *s = svga_surface(surf); - struct svga_texture *t = svga_texture(surf->texture); - struct svga_screen *ss = svga_screen(surf->texture->screen); - - if(s->handle != t->handle) { - SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle); - svga_screen_surface_destroy(ss, &s->key, &s->handle); - } - - pipe_texture_reference(&surf->texture, NULL); - FREE(surf); -} - - -static INLINE void -svga_mark_surface_dirty(struct pipe_surface *surf) -{ - struct svga_surface *s = svga_surface(surf); - - if(!s->dirty) { - struct svga_texture *tex = svga_texture(surf->texture); - - s->dirty = TRUE; - - if (s->handle == tex->handle) - tex->defined[surf->face][surf->level] = TRUE; - else { - /* this will happen later in svga_propagate_surface */ - } - } -} - - -void svga_mark_surfaces_dirty(struct svga_context *svga) -{ - unsigned i; - - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - if (svga->curr.framebuffer.cbufs[i]) - svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]); - } - if (svga->curr.framebuffer.zsbuf) - svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf); -} - -/** - * Progagate any changes from surfaces to texture. - * pipe is optional context to inline the blit command in. - */ -void -svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf) -{ - struct svga_surface *s = svga_surface(surf); - struct svga_texture *tex = svga_texture(surf->texture); - struct svga_screen *ss = svga_screen(surf->texture->screen); - - if (!s->dirty) - return; - - s->dirty = FALSE; - ss->texture_timestamp++; - tex->view_age[surf->level] = ++(tex->age); - - if (s->handle != tex->handle) { - SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf); - svga_texture_copy_handle(svga_context(pipe), ss, - s->handle, 0, 0, 0, s->real_level, s->real_face, - tex->handle, 0, 0, surf->zslice, surf->level, surf->face, - u_minify(tex->base.width0, surf->level), - u_minify(tex->base.height0, surf->level), 1); - tex->defined[surf->face][surf->level] = TRUE; - } -} - -/** - * Check if we should call svga_propagate_surface on the surface. - */ -extern boolean -svga_surface_needs_propagation(struct pipe_surface *surf) -{ - struct svga_surface *s = svga_surface(surf); - struct svga_texture *tex = svga_texture(surf->texture); - - return s->dirty && s->handle != tex->handle; -} - -/* XXX: Still implementing this as if it was a screen function, but - * can now modify it to queue transfers on the context. - */ -static struct pipe_transfer * -svga_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, unsigned x, unsigned y, - unsigned w, unsigned h) -{ - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_transfer *st; - unsigned nblocksx = util_format_get_nblocksx(texture->format, w); - unsigned nblocksy = util_format_get_nblocksy(texture->format, h); - - /* We can't map texture storage directly */ - if (usage & PIPE_TRANSFER_MAP_DIRECTLY) - return NULL; - - st = CALLOC_STRUCT(svga_transfer); - if (!st) - return NULL; - - st->base.x = x; - st->base.y = y; - st->base.width = w; - st->base.height = h; - st->base.stride = nblocksx*util_format_get_blocksize(texture->format); - st->base.usage = usage; - st->base.face = face; - st->base.level = level; - st->base.zslice = zslice; - - st->hw_nblocksy = nblocksy; - - st->hwbuf = svga_winsys_buffer_create(ss, - 1, - 0, - st->hw_nblocksy*st->base.stride); - while(!st->hwbuf && (st->hw_nblocksy /= 2)) { - st->hwbuf = svga_winsys_buffer_create(ss, - 1, - 0, - st->hw_nblocksy*st->base.stride); - } - - if(!st->hwbuf) - goto no_hwbuf; - - if(st->hw_nblocksy < nblocksy) { - /* We couldn't allocate a hardware buffer big enough for the transfer, - * so allocate regular malloc memory instead */ - debug_printf("%s: failed to allocate %u KB of DMA, splitting into %u x %u KB DMA transfers\n", - __FUNCTION__, - (nblocksy*st->base.stride + 1023)/1024, - (nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy, - (st->hw_nblocksy*st->base.stride + 1023)/1024); - st->swbuf = MALLOC(nblocksy*st->base.stride); - if(!st->swbuf) - goto no_swbuf; - } - - pipe_texture_reference(&st->base.texture, texture); - - if (usage & PIPE_TRANSFER_READ) - svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM); - - return &st->base; - -no_swbuf: - sws->buffer_destroy(sws, st->hwbuf); -no_hwbuf: - FREE(st); - return NULL; -} - - -/* XXX: Still implementing this as if it was a screen function, but - * can now modify it to queue transfers on the context. - */ -static void * -svga_transfer_map( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_transfer *st = svga_transfer(transfer); - - if(st->swbuf) - return st->swbuf; - else - /* The wait for read transfers already happened when svga_transfer_dma - * was called. */ - return sws->buffer_map(sws, st->hwbuf, - pipe_transfer_buffer_flags(transfer)); -} - - -/* XXX: Still implementing this as if it was a screen function, but - * can now modify it to queue transfers on the context. - */ -static void -svga_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_transfer *st = svga_transfer(transfer); - - if(!st->swbuf) - sws->buffer_unmap(sws, st->hwbuf); -} - - -static void -svga_tex_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct svga_texture *tex = svga_texture(transfer->texture); - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_transfer *st = svga_transfer(transfer); - - if (st->base.usage & PIPE_TRANSFER_WRITE) { - svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM); - ss->texture_timestamp++; - tex->view_age[transfer->level] = ++(tex->age); - tex->defined[transfer->face][transfer->level] = TRUE; - } - - pipe_texture_reference(&st->base.texture, NULL); - FREE(st->swbuf); - sws->buffer_destroy(sws, st->hwbuf); - FREE(st); -} - - -void -svga_init_texture_functions(struct pipe_context *pipe) -{ - pipe->get_tex_transfer = svga_get_tex_transfer; - pipe->transfer_map = svga_transfer_map; - pipe->transfer_unmap = svga_transfer_unmap; - pipe->tex_transfer_destroy = svga_tex_transfer_destroy; -} - - -void -svga_screen_init_texture_functions(struct pipe_screen *screen) -{ - screen->texture_create = svga_texture_create; - screen->texture_from_handle = svga_screen_texture_from_handle; - screen->texture_get_handle = svga_screen_texture_get_handle; - screen->texture_destroy = svga_texture_destroy; - screen->get_tex_surface = svga_get_tex_surface; - screen->tex_surface_destroy = svga_tex_surface_destroy; -} - -/*********************************************************************** - */ - -struct svga_sampler_view * -svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned min_lod, unsigned max_lod) -{ - struct svga_screen *ss = svga_screen(pt->screen); - struct svga_texture *tex = svga_texture(pt); - struct svga_sampler_view *sv = NULL; - SVGA3dSurfaceFormat format = svga_translate_format(pt->format); - boolean view = TRUE; - - assert(pt); - assert(min_lod >= 0); - assert(min_lod <= max_lod); - assert(max_lod <= pt->last_level); - - - /* Is a view needed */ - { - /* - * Can't control max lod. For first level views and when we only - * look at one level we disable mip filtering to achive the same - * results as a view. - */ - if (min_lod == 0 && max_lod >= pt->last_level) - view = FALSE; - - if (util_format_is_s3tc(pt->format) && view) { - format = svga_translate_format_render(pt->format); - } - - if (ss->debug.no_sampler_view) - view = FALSE; - - if (ss->debug.force_sampler_view) - view = TRUE; - } - - /* First try the cache */ - if (view) { - pipe_mutex_lock(ss->tex_mutex); - if (tex->cached_view && - tex->cached_view->min_lod == min_lod && - tex->cached_view->max_lod == max_lod) { - svga_sampler_view_reference(&sv, tex->cached_view); - pipe_mutex_unlock(ss->tex_mutex); - SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n", - pt, min_lod, max_lod, pt->last_level); - svga_validate_sampler_view(svga_context(pipe), sv); - return sv; - } - pipe_mutex_unlock(ss->tex_mutex); - } - - sv = CALLOC_STRUCT(svga_sampler_view); - pipe_reference_init(&sv->reference, 1); - pipe_texture_reference(&sv->texture, pt); - sv->min_lod = min_lod; - sv->max_lod = max_lod; - - /* No view needed just use the whole texture */ - if (!view) { - SVGA_DBG(DEBUG_VIEWS, - "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", - pt, min_lod, max_lod, - max_lod - min_lod + 1, - pt->width0, - pt->height0, - pt->depth0, - pt->last_level); - sv->key.cachable = 0; - sv->handle = tex->handle; - return sv; - } - - SVGA_DBG(DEBUG_VIEWS, - "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", - pt, min_lod, max_lod, - max_lod - min_lod + 1, - pt->width0, - pt->height0, - pt->depth0, - pt->last_level); - - sv->age = tex->age; - sv->handle = svga_texture_view_surface(pipe, tex, format, - min_lod, - max_lod - min_lod + 1, - -1, -1, - &sv->key); - - if (!sv->handle) { - assert(0); - sv->key.cachable = 0; - sv->handle = tex->handle; - return sv; - } - - pipe_mutex_lock(ss->tex_mutex); - svga_sampler_view_reference(&tex->cached_view, sv); - pipe_mutex_unlock(ss->tex_mutex); - - return sv; -} - -void -svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v) -{ - struct svga_texture *tex = svga_texture(v->texture); - unsigned numFaces; - unsigned age = 0; - int i, k; - - assert(svga); - - if (v->handle == tex->handle) - return; - - age = tex->age; - - if(tex->base.target == PIPE_TEXTURE_CUBE) - numFaces = 6; - else - numFaces = 1; - - for (i = v->min_lod; i <= v->max_lod; i++) { - for (k = 0; k < numFaces; k++) { - if (v->age < tex->view_age[i]) - svga_texture_copy_handle(svga, NULL, - tex->handle, 0, 0, 0, i, k, - v->handle, 0, 0, 0, i - v->min_lod, k, - u_minify(tex->base.width0, i), - u_minify(tex->base.height0, i), - u_minify(tex->base.depth0, i)); - } - } - - v->age = age; -} - -void -svga_destroy_sampler_view_priv(struct svga_sampler_view *v) -{ - struct svga_texture *tex = svga_texture(v->texture); - - if(v->handle != tex->handle) { - struct svga_screen *ss = svga_screen(v->texture->screen); - SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle); - svga_screen_surface_destroy(ss, &v->key, &v->handle); - } - pipe_texture_reference(&v->texture, NULL); - FREE(v); -} diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index 493f78a9908..97c818cd379 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -82,7 +82,7 @@ static int emit_consts( struct svga_context *svga, int offset, int unit ) { - struct pipe_screen *screen = svga->pipe.screen; + struct pipe_transfer *transfer = NULL; unsigned count; const float (*data)[4] = NULL; unsigned i; @@ -91,11 +91,12 @@ static int emit_consts( struct svga_context *svga, if (svga->curr.cb[unit] == NULL) goto done; - count = svga->curr.cb[unit]->size / (4 * sizeof(float)); + count = svga->curr.cb[unit]->width0 / (4 * sizeof(float)); - data = (const float (*)[4])pipe_buffer_map(screen, + data = (const float (*)[4])pipe_buffer_map(&svga->pipe, svga->curr.cb[unit], - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &transfer); if (data == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto done; @@ -109,7 +110,7 @@ static int emit_consts( struct svga_context *svga, done: if (data) - pipe_buffer_unmap(screen, svga->curr.cb[unit]); + pipe_buffer_unmap(&svga->pipe, svga->curr.cb[unit], transfer); return ret; } @@ -137,7 +138,7 @@ static int emit_fs_consts( struct svga_context *svga, for (i = 0; i < key->num_textures; i++) { if (key->tex[i].unnormalized) { - struct pipe_texture *tex = svga->curr.sampler_views[i]->texture; + struct pipe_resource *tex = svga->curr.sampler_views[i]->texture; float data[4]; data[0] = 1.0 / (float)tex->width0; diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index c08ec7c2e8c..76a2dae1435 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -27,7 +27,7 @@ #include "pipe/p_defines.h" #include "util/u_math.h" -#include "svga_screen_texture.h" +#include "svga_sampler_view.h" #include "svga_winsys.h" #include "svga_context.h" #include "svga_state.h" @@ -45,7 +45,7 @@ void svga_cleanup_tss_binding(struct svga_context *svga) svga_sampler_view_reference(&view->v, NULL); pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL ); - pipe_texture_reference( &view->texture, NULL ); + pipe_resource_reference( &view->texture, NULL ); view->dirty = 1; } @@ -77,7 +77,7 @@ update_tss_binding(struct svga_context *svga, for (i = 0; i < count; i++) { const struct svga_sampler_state *s = svga->curr.sampler[i]; struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; - struct pipe_texture *texture = NULL; + struct pipe_resource *texture = NULL; /* get min max lod */ if (svga->curr.sampler_views[i]) { @@ -94,7 +94,7 @@ update_tss_binding(struct svga_context *svga, view->max_lod != max_lod) { svga_sampler_view_reference(&view->v, NULL); - pipe_texture_reference( &view->texture, texture ); + pipe_resource_reference( &view->texture, texture ); view->dirty = TRUE; view->min_lod = min_lod; @@ -135,7 +135,7 @@ update_tss_binding(struct svga_context *svga, svga->swc->surface_relocation(svga->swc, &ts[i].value, queue.bind[i].view->v->handle, - PIPE_BUFFER_USAGE_GPU_READ); + SVGA_RELOC_READ); } else { ts[i].value = SVGA3D_INVALID_ID; diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index f531e223048..3af7bf2b358 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -33,7 +33,7 @@ #include "svga_draw.h" #include "svga_tgsi.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" +#include "svga_resource_buffer.h" #include "svga_hw_reg.h" @@ -59,8 +59,8 @@ upload_user_buffers( struct svga_context *svga ) if (!buffer->uploaded.buffer) { ret = u_upload_buffer( svga->upload_vb, 0, - buffer->base.size, - &buffer->base, + buffer->b.b.width0, + &buffer->b.b, &buffer->uploaded.offset, &buffer->uploaded.buffer ); if (ret) @@ -73,10 +73,10 @@ upload_user_buffers( struct svga_context *svga ) buffer, buffer->uploaded.buffer, buffer->uploaded.offset, - buffer->base.size); + buffer->b.b.width0); } - pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); + pipe_resource_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); svga->curr.vb[i].buffer_offset = buffer->uploaded.offset; } } diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c index 781f7bf5339..a6215c68cbe 100644 --- a/src/gallium/drivers/svga/svga_state_vs.c +++ b/src/gallium/drivers/svga/svga_state_vs.c @@ -190,9 +190,11 @@ static int update_zero_stride( struct svga_context *svga, const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i]; const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[ vel->vertex_buffer_index]; + if (vbuffer->stride == 0) { unsigned const_idx = svga->curr.num_zero_stride_vertex_elements; + struct pipe_transfer *transfer; struct translate *translate; struct translate_key key; void *mapped_buffer; @@ -218,19 +220,23 @@ static int update_zero_stride( struct svga_context *svga, assert(vel->src_offset == 0); - mapped_buffer = pipe_buffer_map_range(svga->pipe.screen, + mapped_buffer = pipe_buffer_map_range(&svga->pipe, vbuffer->buffer, vel->src_offset, util_format_get_blocksize(vel->src_format), - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &transfer); + translate->set_buffer(translate, vel->vertex_buffer_index, mapped_buffer, vbuffer->stride); translate->run(translate, 0, 1, 0, svga->curr.zero_stride_constants); - pipe_buffer_unmap(svga->pipe.screen, - vbuffer->buffer); + pipe_buffer_unmap(&svga->pipe, + vbuffer->buffer, + transfer); + translate->release(translate); } } diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c new file mode 100644 index 00000000000..126b0787518 --- /dev/null +++ b/src/gallium/drivers/svga/svga_surface.c @@ -0,0 +1,383 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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 "svga_cmd.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "svga_screen.h" +#include "svga_context.h" +#include "svga_resource_texture.h" +#include "svga_surface.h" +#include "svga_winsys.h" +#include "svga_debug.h" + +#include <util/u_string.h> + + +void +svga_texture_copy_handle(struct svga_context *svga, + struct svga_screen *ss, + struct svga_winsys_surface *src_handle, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned src_level, unsigned src_face, + struct svga_winsys_surface *dst_handle, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + unsigned dst_level, unsigned dst_face, + unsigned width, unsigned height, unsigned depth) +{ + struct svga_surface dst, src; + enum pipe_error ret; + SVGA3dCopyBox box, *boxes; + + assert(svga || ss); + + src.handle = src_handle; + src.real_level = src_level; + src.real_face = src_face; + src.real_zslice = 0; + + dst.handle = dst_handle; + dst.real_level = dst_level; + dst.real_face = dst_face; + dst.real_zslice = 0; + + box.x = dst_x; + box.y = dst_y; + box.z = dst_z; + box.w = width; + box.h = height; + box.d = depth; + box.srcx = src_x; + box.srcy = src_y; + box.srcz = src_z; + +/* + SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n", + src_handle, src_level, src_x, src_y, src_z, + dst_handle, dst_level, dst_x, dst_y, dst_z); +*/ + + if (svga) { + ret = SVGA3D_BeginSurfaceCopy(svga->swc, + &src.base, + &dst.base, + &boxes, 1); + if(ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_BeginSurfaceCopy(svga->swc, + &src.base, + &dst.base, + &boxes, 1); + assert(ret == PIPE_OK); + } + *boxes = box; + SVGA_FIFOCommitAll(svga->swc); + } else { + pipe_mutex_lock(ss->swc_mutex); + ret = SVGA3D_BeginSurfaceCopy(ss->swc, + &src.base, + &dst.base, + &boxes, 1); + if(ret != PIPE_OK) { + ss->swc->flush(ss->swc, NULL); + ret = SVGA3D_BeginSurfaceCopy(ss->swc, + &src.base, + &dst.base, + &boxes, 1); + assert(ret == PIPE_OK); + } + *boxes = box; + SVGA_FIFOCommitAll(ss->swc); + pipe_mutex_unlock(ss->swc_mutex); + } +} + + +struct svga_winsys_surface * +svga_texture_view_surface(struct pipe_context *pipe, + struct svga_texture *tex, + SVGA3dSurfaceFormat format, + unsigned start_mip, + unsigned num_mip, + int face_pick, + int zslice_pick, + struct svga_host_surface_cache_key *key) /* OUT */ +{ + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_surface *handle; + uint32_t i, j; + unsigned z_offset = 0; + + SVGA_DBG(DEBUG_PERF, + "svga: Create surface view: face %d zslice %d mips %d..%d\n", + face_pick, zslice_pick, start_mip, start_mip+num_mip-1); + + key->flags = 0; + key->format = format; + key->numMipLevels = num_mip; + key->size.width = u_minify(tex->b.b.width0, start_mip); + key->size.height = u_minify(tex->b.b.height0, start_mip); + key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1; + key->cachable = 1; + assert(key->size.depth == 1); + + if(tex->b.b.target == PIPE_TEXTURE_CUBE && face_pick < 0) { + key->flags |= SVGA3D_SURFACE_CUBEMAP; + key->numFaces = 6; + } else { + key->numFaces = 1; + } + + if(key->format == SVGA3D_FORMAT_INVALID) { + key->cachable = 0; + return NULL; + } + + SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); + handle = svga_screen_surface_create(ss, key); + if (!handle) { + key->cachable = 0; + return NULL; + } + + SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle); + + if (face_pick < 0) + face_pick = 0; + + if (zslice_pick >= 0) + z_offset = zslice_pick; + + for (i = 0; i < key->numMipLevels; i++) { + for (j = 0; j < key->numFaces; j++) { + if(tex->defined[j + face_pick][i + start_mip]) { + unsigned depth = (zslice_pick < 0 ? + u_minify(tex->b.b.depth0, i + start_mip) : + 1); + + svga_texture_copy_handle(svga_context(pipe), + ss, + tex->handle, + 0, 0, z_offset, + i + start_mip, + j + face_pick, + handle, 0, 0, 0, i, j, + u_minify(tex->b.b.width0, i + start_mip), + u_minify(tex->b.b.height0, i + start_mip), + depth); + } + } + } + + return handle; +} + + +static struct pipe_surface * +svga_get_tex_surface(struct pipe_screen *screen, + struct pipe_resource *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct svga_texture *tex = svga_texture(pt); + struct svga_surface *s; + boolean render = (flags & (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DEPTH_STENCIL)) ? TRUE : FALSE; + boolean view = FALSE; + SVGA3dSurfaceFormat format; + + s = CALLOC_STRUCT(svga_surface); + if (!s) + return NULL; + + pipe_reference_init(&s->base.reference, 1); + pipe_resource_reference(&s->base.texture, pt); + s->base.format = pt->format; + s->base.width = u_minify(pt->width0, level); + s->base.height = u_minify(pt->height0, level); + s->base.usage = flags; + s->base.level = level; + s->base.face = face; + s->base.zslice = zslice; + + if (!render) + format = svga_translate_format(pt->format); + else + format = svga_translate_format_render(pt->format); + + assert(format != SVGA3D_FORMAT_INVALID); + + if (svga_screen(screen)->debug.force_surface_view) + view = TRUE; + + /* Currently only used for compressed textures */ + if (render && + format != svga_translate_format(pt->format)) { + view = TRUE; + } + + if (level != 0 && + svga_screen(screen)->debug.force_level_surface_view) + view = TRUE; + + if (pt->target == PIPE_TEXTURE_3D) + view = TRUE; + + if (svga_screen(screen)->debug.no_surface_view) + view = FALSE; + + if (view) { + SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n", + pt, level, face, zslice, s); + + s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice, + &s->key); + s->real_face = 0; + s->real_level = 0; + s->real_zslice = 0; + } else { + SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n", + pt, level, face, zslice, s); + + memset(&s->key, 0, sizeof s->key); + s->handle = tex->handle; + s->real_face = face; + s->real_level = level; + s->real_zslice = zslice; + } + + return &s->base; +} + + +static void +svga_tex_surface_destroy(struct pipe_surface *surf) +{ + struct svga_surface *s = svga_surface(surf); + struct svga_texture *t = svga_texture(surf->texture); + struct svga_screen *ss = svga_screen(surf->texture->screen); + + if(s->handle != t->handle) { + SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle); + svga_screen_surface_destroy(ss, &s->key, &s->handle); + } + + pipe_resource_reference(&surf->texture, NULL); + FREE(surf); +} + + +static INLINE void +svga_mark_surface_dirty(struct pipe_surface *surf) +{ + struct svga_surface *s = svga_surface(surf); + + if(!s->dirty) { + struct svga_texture *tex = svga_texture(surf->texture); + + s->dirty = TRUE; + + if (s->handle == tex->handle) + tex->defined[surf->face][surf->level] = TRUE; + else { + /* this will happen later in svga_propagate_surface */ + } + } +} + + +void svga_mark_surfaces_dirty(struct svga_context *svga) +{ + unsigned i; + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (svga->curr.framebuffer.cbufs[i]) + svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]); + } + if (svga->curr.framebuffer.zsbuf) + svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf); +} + + +/** + * Progagate any changes from surfaces to texture. + * pipe is optional context to inline the blit command in. + */ +void +svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf) +{ + struct svga_surface *s = svga_surface(surf); + struct svga_texture *tex = svga_texture(surf->texture); + struct svga_screen *ss = svga_screen(surf->texture->screen); + + if (!s->dirty) + return; + + s->dirty = FALSE; + ss->texture_timestamp++; + tex->view_age[surf->level] = ++(tex->age); + + if (s->handle != tex->handle) { + SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf); + svga_texture_copy_handle(svga_context(pipe), ss, + s->handle, 0, 0, 0, s->real_level, s->real_face, + tex->handle, 0, 0, surf->zslice, surf->level, surf->face, + u_minify(tex->b.b.width0, surf->level), + u_minify(tex->b.b.height0, surf->level), 1); + tex->defined[surf->face][surf->level] = TRUE; + } +} + +/** + * Check if we should call svga_propagate_surface on the surface. + */ +boolean +svga_surface_needs_propagation(struct pipe_surface *surf) +{ + struct svga_surface *s = svga_surface(surf); + struct svga_texture *tex = svga_texture(surf->texture); + + return s->dirty && s->handle != tex->handle; +} + + + + + + +void +svga_screen_init_surface_functions(struct pipe_screen *screen) +{ + screen->get_tex_surface = svga_get_tex_surface; + screen->tex_surface_destroy = svga_tex_surface_destroy; +} + diff --git a/src/gallium/drivers/svga/svga_surface.h b/src/gallium/drivers/svga/svga_surface.h new file mode 100644 index 00000000000..b50ecdc9942 --- /dev/null +++ b/src/gallium/drivers/svga/svga_surface.h @@ -0,0 +1,97 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * 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 the rights to use, copy, + * modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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. + * + **********************************************************/ + +#ifndef SVGA_SURFACE_H +#define SVGA_SURFACE_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "util/u_inlines.h" +#include "svga_screen_cache.h" + +struct pipe_context; +struct pipe_screen; +struct svga_context; +struct svga_texture; +struct svga_winsys_surface; +enum SVGA3dSurfaceFormat; + + +struct svga_surface +{ + struct pipe_surface base; + + struct svga_host_surface_cache_key key; + struct svga_winsys_surface *handle; + + unsigned real_face; + unsigned real_level; + unsigned real_zslice; + + boolean dirty; +}; + + +extern void +svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf); + +extern boolean +svga_surface_needs_propagation(struct pipe_surface *surf); + +struct svga_winsys_surface * +svga_texture_view_surface(struct pipe_context *pipe, + struct svga_texture *tex, + SVGA3dSurfaceFormat format, + unsigned start_mip, + unsigned num_mip, + int face_pick, + int zslice_pick, + struct svga_host_surface_cache_key *key); /* OUT */ + + +void +svga_texture_copy_handle(struct svga_context *svga, + struct svga_screen *ss, + struct svga_winsys_surface *src_handle, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned src_level, unsigned src_face, + struct svga_winsys_surface *dst_handle, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + unsigned dst_level, unsigned dst_face, + unsigned width, unsigned height, unsigned depth); + + +static INLINE struct svga_surface * +svga_surface(struct pipe_surface *surface) +{ + assert(surface); + return (struct svga_surface *)surface; +} + +void +svga_screen_init_surface_functions(struct pipe_screen *screen); + +#endif diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h index 4882f26b170..096ed410b5b 100644 --- a/src/gallium/drivers/svga/svga_swtnl.h +++ b/src/gallium/drivers/svga/svga_swtnl.h @@ -40,7 +40,7 @@ void svga_destroy_swtnl( struct svga_context *svga ); enum pipe_error svga_swtnl_draw_range_elements(struct svga_context *svga, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index e9d7942fb57..e6498136083 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -79,21 +79,19 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, new_vbuf = TRUE; if (new_vbuf) - pipe_buffer_reference(&svga_render->vbuf, NULL); + pipe_resource_reference(&svga_render->vbuf, NULL); if (new_ibuf) - pipe_buffer_reference(&svga_render->ibuf, NULL); + pipe_resource_reference(&svga_render->ibuf, NULL); if (!svga_render->vbuf) { svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); svga_render->vbuf = pipe_buffer_create(screen, - 16, - PIPE_BUFFER_USAGE_VERTEX, + PIPE_BIND_VERTEX_BUFFER, svga_render->vbuf_size); if(!svga_render->vbuf) { svga_context_flush(svga, NULL); svga_render->vbuf = pipe_buffer_create(screen, - 16, - PIPE_BUFFER_USAGE_VERTEX, + PIPE_BIND_VERTEX_BUFFER, svga_render->vbuf_size); assert(svga_render->vbuf); } @@ -117,14 +115,14 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; - struct pipe_screen *screen = svga->pipe.screen; - char *ptr = (char*)pipe_buffer_map(screen, + char *ptr = (char*)pipe_buffer_map(&svga->pipe, svga_render->vbuf, - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | - PIPE_BUFFER_USAGE_DISCARD | - PIPE_BUFFER_USAGE_UNSYNCHRONIZED); + PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_FLUSH_EXPLICIT | + PIPE_TRANSFER_DISCARD | + PIPE_TRANSFER_UNSYNCHRONIZED, + &svga_render->vbuf_transfer); return ptr + svga_render->vbuf_offset; } @@ -135,14 +133,15 @@ svga_vbuf_render_unmap_vertices( struct vbuf_render *render, { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; - struct pipe_screen *screen = svga->pipe.screen; unsigned offset, length; size_t used = svga_render->vertex_size * ((size_t)max_index + 1); offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index; length = svga_render->vertex_size * (max_index + 1 - min_index); - pipe_buffer_flush_mapped_range(screen, svga_render->vbuf, offset, length); - pipe_buffer_unmap(screen, svga_render->vbuf); + pipe_buffer_flush_mapped_range(&svga->pipe, + svga_render->vbuf_transfer, + offset, length); + pipe_buffer_unmap(&svga->pipe, svga_render->vbuf, svga_render->vbuf_transfer); svga_render->min_index = min_index; svga_render->max_index = max_index; svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used); @@ -255,19 +254,18 @@ svga_vbuf_render_draw( struct vbuf_render *render, assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0); if (svga_render->ibuf_size < svga_render->ibuf_offset + size) - pipe_buffer_reference(&svga_render->ibuf, NULL); + pipe_resource_reference(&svga_render->ibuf, NULL); if (!svga_render->ibuf) { svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); svga_render->ibuf = pipe_buffer_create(screen, - 2, - PIPE_BUFFER_USAGE_VERTEX, + PIPE_BIND_INDEX_BUFFER, svga_render->ibuf_size); svga_render->ibuf_offset = 0; } - pipe_buffer_write_nooverlap(screen, svga_render->ibuf, - svga_render->ibuf_offset, 2 * nr_indices, indices); + pipe_buffer_write_nooverlap(&svga->pipe, svga_render->ibuf, + svga_render->ibuf_offset, 2 * nr_indices, indices); /* off to hardware */ @@ -315,8 +313,8 @@ svga_vbuf_render_destroy( struct vbuf_render *render ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); - pipe_buffer_reference(&svga_render->vbuf, NULL); - pipe_buffer_reference(&svga_render->ibuf, NULL); + pipe_resource_reference(&svga_render->vbuf, NULL); + pipe_resource_reference(&svga_render->ibuf, NULL); FREE(svga_render); } diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index da15be155c8..0037bbd5fe5 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -37,12 +37,15 @@ enum pipe_error svga_swtnl_draw_range_elements(struct svga_context *svga, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, unsigned prim, unsigned start, unsigned count) { + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *ib_transfer; + struct pipe_transfer *cb_transfer; struct draw_context *draw = svga->swtnl.draw; unsigned i; const void *map; @@ -64,17 +67,19 @@ svga_swtnl_draw_range_elements(struct svga_context *svga, * Map vertex buffers */ for (i = 0; i < svga->curr.num_vertex_buffers; i++) { - map = pipe_buffer_map(svga->pipe.screen, + map = pipe_buffer_map(&svga->pipe, svga->curr.vb[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &vb_transfer[i]); draw_set_mapped_vertex_buffer(draw, i, map); } /* Map index buffer, if present */ if (indexBuffer) { - map = pipe_buffer_map(svga->pipe.screen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(&svga->pipe, indexBuffer, + PIPE_TRANSFER_READ, + &ib_transfer); draw_set_mapped_element_buffer_range(draw, indexSize, @@ -84,14 +89,15 @@ svga_swtnl_draw_range_elements(struct svga_context *svga, } if (svga->curr.cb[PIPE_SHADER_VERTEX]) { - map = pipe_buffer_map(svga->pipe.screen, + map = pipe_buffer_map(&svga->pipe, svga->curr.cb[PIPE_SHADER_VERTEX], - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, + &cb_transfer); assert(map); draw_set_mapped_constant_buffer( draw, PIPE_SHADER_VERTEX, 0, map, - svga->curr.cb[PIPE_SHADER_VERTEX]->size); + svga->curr.cb[PIPE_SHADER_VERTEX]->width0); } draw_arrays(svga->swtnl.draw, prim, start, count); @@ -105,18 +111,20 @@ svga_swtnl_draw_range_elements(struct svga_context *svga, * unmap vertex/index buffers */ for (i = 0; i < svga->curr.num_vertex_buffers; i++) { - pipe_buffer_unmap(svga->pipe.screen, svga->curr.vb[i].buffer); + pipe_buffer_unmap(&svga->pipe, svga->curr.vb[i].buffer, + vb_transfer[i]); draw_set_mapped_vertex_buffer(draw, i, NULL); } if (indexBuffer) { - pipe_buffer_unmap(svga->pipe.screen, indexBuffer); + pipe_buffer_unmap(&svga->pipe, indexBuffer, ib_transfer); draw_set_mapped_element_buffer(draw, 0, NULL); } if (svga->curr.cb[PIPE_SHADER_VERTEX]) { - pipe_buffer_unmap(svga->pipe.screen, - svga->curr.cb[PIPE_SHADER_VERTEX]); + pipe_buffer_unmap(&svga->pipe, + svga->curr.cb[PIPE_SHADER_VERTEX], + cb_transfer); } return ret; diff --git a/src/gallium/drivers/svga/svga_swtnl_private.h b/src/gallium/drivers/svga/svga_swtnl_private.h index 9bbb42910f5..8d080708438 100644 --- a/src/gallium/drivers/svga/svga_swtnl_private.h +++ b/src/gallium/drivers/svga/svga_swtnl_private.h @@ -45,8 +45,10 @@ struct svga_vbuf_render { unsigned prim; - struct pipe_buffer *vbuf; - struct pipe_buffer *ibuf; + struct pipe_resource *vbuf; + struct pipe_resource *ibuf; + struct pipe_transfer *vbuf_transfer; + struct pipe_transfer *ibuf_transfer; /* current size of buffer */ size_t vbuf_size; diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index d4bb176f9a8..3892addafd1 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -49,13 +49,18 @@ struct svga_winsys_buffer; struct pipe_screen; struct pipe_context; struct pipe_fence_handle; -struct pipe_texture; +struct pipe_resource; struct svga_region; struct winsys_handle; -#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0) -#define SVGA_BUFFER_USAGE_WRAPPED (PIPE_BUFFER_USAGE_CUSTOM << 1) +#define SVGA_BUFFER_USAGE_PINNED (1 << 0) +#define SVGA_BUFFER_USAGE_WRAPPED (1 << 1) + + +#define SVGA_RELOC_WRITE 0x1 +#define SVGA_RELOC_READ 0x2 + /** Opaque surface handle */ @@ -189,7 +194,7 @@ struct svga_winsys_screen /** * Creates a surface from a winsys handle. - * Used to implement pipe_screen::texture_from_handle. + * Used to implement pipe_screen::resource_from_handle. */ struct svga_winsys_surface * (*surface_from_handle)(struct svga_winsys_screen *sws, @@ -198,7 +203,7 @@ struct svga_winsys_screen /** * Get a winsys_handle from a surface. - * Used to implement pipe_screen::texture_get_handle. + * Used to implement pipe_screen::resource_get_handle. */ boolean (*surface_get_handle)(struct svga_winsys_screen *sws, @@ -225,13 +230,7 @@ struct svga_winsys_screen /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * - * Remember that gallium gets to choose the interface it needs, and the - * window systems must then implement that interface (rather than the - * other way around...). - * - * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This - * usage argument is only an optimization hint, not a guarantee, therefore - * proper behavior must be observed in all circumstances. + * XXX usage seems to be a bitmask of SVGA_BUFFER_USAGE_* flags. * * alignment indicates the client's alignment requirements, eg for * SSE instructions. @@ -245,9 +244,9 @@ struct svga_winsys_screen /** * Map the entire data store of a buffer object into the client's address. * flags is a bitmask of: - * - PIPE_BUFFER_USAGE_CPU_READ/WRITE - * - PIPE_BUFFER_USAGE_DONTBLOCK - * - PIPE_BUFFER_USAGE_UNSYNCHRONIZED + * - PB_USAGE_CPU_READ/WRITE + * - PB_USAGE_DONTBLOCK + * - PB_USAGE_UNSYNCHRONIZED */ void * (*buffer_map)( struct svga_winsys_screen *sws, @@ -298,12 +297,12 @@ svga_screen_create(struct svga_winsys_screen *sws); struct svga_winsys_screen * svga_winsys_screen(struct pipe_screen *screen); -struct pipe_buffer * +struct pipe_resource * svga_screen_buffer_wrap_surface(struct pipe_screen *screen, enum SVGA3dSurfaceFormat format, struct svga_winsys_surface *srf); struct svga_winsys_surface * -svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer); +svga_screen_buffer_get_winsys_surface(struct pipe_resource *buffer); #endif /* SVGA_WINSYS_H_ */ diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile index dd6831c70ab..78f6347dc72 100644 --- a/src/gallium/drivers/trace/Makefile +++ b/src/gallium/drivers/trace/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = trace C_SOURCES = \ - tr_buffer.c \ tr_context.c \ tr_dump.c \ tr_dump_state.c \ diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index c1675d1c165..5f1fb17966a 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -5,7 +5,6 @@ env = env.Clone() trace = env.ConvenienceLibrary( target = 'trace', source = [ - 'tr_buffer.c', 'tr_context.c', 'tr_drm.c', 'tr_dump.c', diff --git a/src/gallium/drivers/trace/tr_buffer.c b/src/gallium/drivers/trace/tr_buffer.c deleted file mode 100644 index fa2ac068ebc..00000000000 --- a/src/gallium/drivers/trace/tr_buffer.c +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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 "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_simple_list.h" - -#include "tr_buffer.h" - -struct pipe_buffer * -trace_buffer_create(struct trace_screen *tr_scr, - struct pipe_buffer *buffer) -{ - struct trace_buffer *tr_buf; - - if(!buffer) - goto error; - - assert(buffer->screen == tr_scr->screen); - - tr_buf = CALLOC_STRUCT(trace_buffer); - if(!tr_buf) - goto error; - - memcpy(&tr_buf->base, buffer, sizeof(struct pipe_buffer)); - - pipe_reference_init(&tr_buf->base.reference, 1); - tr_buf->base.screen = &tr_scr->base; - tr_buf->buffer = buffer; - - trace_screen_add_to_list(tr_scr, buffers, tr_buf); - - return &tr_buf->base; - -error: - pipe_buffer_reference(&buffer, NULL); - return NULL; -} - - -void -trace_buffer_destroy(struct trace_screen *tr_scr, - struct pipe_buffer *buffer) -{ - struct trace_buffer *tr_buf = trace_buffer(buffer); - - trace_screen_remove_from_list(tr_scr, buffers, tr_buf); - - pipe_buffer_reference(&tr_buf->buffer, NULL); - FREE(tr_buf); -} diff --git a/src/gallium/drivers/trace/tr_buffer.h b/src/gallium/drivers/trace/tr_buffer.h deleted file mode 100644 index 1a2d0b9aeae..00000000000 --- a/src/gallium/drivers/trace/tr_buffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * 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 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 TUNGSTEN GRAPHICS AND/OR ITS 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. - * - **************************************************************************/ - -#ifndef TR_BUFFER_H_ -#define TR_BUFFER_H_ - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - -#include "tr_screen.h" - - -struct trace_buffer -{ - struct pipe_buffer base; - - struct pipe_buffer *buffer; - - struct tr_list list; - - void *map; - boolean range_flushed; -}; - - -static INLINE struct trace_buffer * -trace_buffer(struct pipe_buffer *buffer) -{ - if(!buffer) - return NULL; - (void)trace_screen(buffer->screen); - return (struct trace_buffer *)buffer; -} - - -struct pipe_buffer * -trace_buffer_create(struct trace_screen *tr_scr, - struct pipe_buffer *buffer); - -void -trace_buffer_destroy(struct trace_screen *tr_scr, - struct pipe_buffer *buffer); - - -#endif diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 5c24bd1f7df..dd0fd8ed98d 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -36,43 +36,26 @@ #include "tr_dump.h" #include "tr_dump_state.h" #include "tr_state.h" -#include "tr_buffer.h" #include "tr_screen.h" #include "tr_texture.h" -static INLINE struct pipe_buffer * -trace_buffer_unwrap(struct trace_context *tr_ctx, - struct pipe_buffer *buffer) -{ - struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); - struct trace_buffer *tr_buf; - - if(!buffer) - return NULL; - tr_buf = trace_buffer(buffer); - assert(tr_buf->buffer); - assert(tr_buf->buffer->screen == tr_scr->screen); - (void) tr_scr; - return tr_buf->buffer; -} - -static INLINE struct pipe_texture * -trace_texture_unwrap(struct trace_context *tr_ctx, - struct pipe_texture *texture) +static INLINE struct pipe_resource * +trace_resource_unwrap(struct trace_context *tr_ctx, + struct pipe_resource *resource) { - struct trace_texture *tr_tex; + struct trace_resource *tr_tex; - if(!texture) + if(!resource) return NULL; - tr_tex = trace_texture(texture); + tr_tex = trace_resource(resource); - assert(tr_tex->texture); - return tr_tex->texture; + assert(tr_tex->resource); + return tr_tex->resource; } @@ -193,22 +176,20 @@ trace_context_draw_arrays(struct pipe_context *_pipe, static INLINE void trace_context_draw_elements(struct pipe_context *_pipe, - struct pipe_buffer *_indexBuffer, + struct pipe_resource *_indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_buffer *tr_buf = trace_buffer(_indexBuffer); + struct trace_resource *tr_buf = trace_resource(_indexBuffer); struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_buffer *indexBuffer = tr_buf->buffer; + struct pipe_resource *indexBuffer = tr_buf->resource; if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) return; trace_context_draw_block(tr_ctx, 1); - trace_screen_user_buffer_update(_pipe->screen, indexBuffer); - trace_dump_call_begin("pipe_context", "draw_elements"); trace_dump_arg(ptr, pipe); @@ -228,7 +209,7 @@ trace_context_draw_elements(struct pipe_context *_pipe, static INLINE void trace_context_draw_range_elements(struct pipe_context *_pipe, - struct pipe_buffer *_indexBuffer, + struct pipe_resource *_indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, @@ -237,17 +218,15 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_buffer *tr_buf = trace_buffer(_indexBuffer); + struct trace_resource *tr_buf = trace_resource(_indexBuffer); struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_buffer *indexBuffer = tr_buf->buffer; + struct pipe_resource *indexBuffer = tr_buf->resource; if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) return; trace_context_draw_block(tr_ctx, 1); - trace_screen_user_buffer_update(_pipe->screen, indexBuffer); - trace_dump_call_begin("pipe_context", "draw_range_elements"); trace_dump_arg(ptr, pipe); @@ -897,14 +876,13 @@ trace_context_set_clip_state(struct pipe_context *_pipe, static INLINE void trace_context_set_constant_buffer(struct pipe_context *_pipe, uint shader, uint index, - struct pipe_buffer *buffer) + struct pipe_resource *buffer) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; if (buffer) { - trace_screen_user_buffer_update(_pipe->screen, buffer); - buffer = trace_buffer_unwrap(tr_ctx, buffer); + buffer = trace_resource_unwrap(tr_ctx, buffer); } trace_dump_call_begin("pipe_context", "set_constant_buffer"); @@ -933,11 +911,11 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, tr_ctx->curr.nr_cbufs = state->nr_cbufs; for (i = 0; i < state->nr_cbufs; i++) if (state->cbufs[i]) - tr_ctx->curr.cbufs[i] = trace_texture(state->cbufs[i]->texture); + tr_ctx->curr.cbufs[i] = trace_resource(state->cbufs[i]->texture); else tr_ctx->curr.cbufs[i] = NULL; if (state->zsbuf) - tr_ctx->curr.zsbuf = trace_texture(state->zsbuf->texture); + tr_ctx->curr.zsbuf = trace_resource(state->zsbuf->texture); else tr_ctx->curr.zsbuf = NULL; } @@ -1018,13 +996,13 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, static struct pipe_sampler_view * trace_create_sampler_view(struct pipe_context *_pipe, - struct pipe_texture *_texture, + struct pipe_resource *_resource, const struct pipe_sampler_view *templ) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_texture *tr_tex = trace_texture(_texture); + struct trace_resource *tr_tex = trace_resource(_resource); struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_texture *texture = tr_tex->texture; + struct pipe_resource *texture = tr_tex->resource; struct trace_sampler_view *result = CALLOC_STRUCT(trace_sampler_view); trace_dump_call_begin("pipe_context", "create_sampler_view"); @@ -1038,7 +1016,7 @@ trace_create_sampler_view(struct pipe_context *_pipe, result->base = *templ; result->base.reference.count = 1; result->base.texture = NULL; - pipe_texture_reference(&result->base.texture, _texture); + pipe_resource_reference(&result->base.texture, _resource); result->base.context = _pipe; trace_dump_ret(ptr, result); @@ -1067,7 +1045,7 @@ trace_sampler_view_destroy(struct pipe_context *_pipe, trace_dump_call_end(); - pipe_texture_reference(&_view->texture, NULL); + pipe_resource_reference(&_view->texture, NULL); FREE(_view); } @@ -1143,9 +1121,6 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; unsigned i; - for(i = 0; i < num_buffers; ++i) - trace_screen_user_buffer_update(_pipe->screen, buffers[i].buffer); - trace_dump_call_begin("pipe_context", "set_vertex_buffers"); trace_dump_arg(ptr, pipe); @@ -1159,7 +1134,7 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, struct pipe_vertex_buffer *_buffers = malloc(num_buffers * sizeof(*_buffers)); memcpy(_buffers, buffers, num_buffers * sizeof(*_buffers)); for (i = 0; i < num_buffers; i++) - _buffers[i].buffer = trace_buffer_unwrap(tr_ctx, buffers[i].buffer); + _buffers[i].buffer = trace_resource_unwrap(tr_ctx, buffers[i].buffer); pipe->set_vertex_buffers(pipe, num_buffers, _buffers); free(_buffers); } else { @@ -1296,45 +1271,23 @@ trace_context_destroy(struct pipe_context *_pipe) } static unsigned int -trace_is_texture_referenced( struct pipe_context *_pipe, - struct pipe_texture *_texture, - unsigned face, unsigned level) +trace_is_resource_referenced( struct pipe_context *_pipe, + struct pipe_resource *_resource, + unsigned face, unsigned level) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_texture *tr_tex = trace_texture(_texture); + struct trace_resource *tr_tex = trace_resource(_resource); struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_texture *texture = tr_tex->texture; + struct pipe_resource *texture = tr_tex->resource; unsigned int referenced; - trace_dump_call_begin("pipe_context", "is_texture_referenced"); + trace_dump_call_begin("pipe_context", "is_resource_referenced"); trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, texture); trace_dump_arg(uint, face); trace_dump_arg(uint, level); - referenced = pipe->is_texture_referenced(pipe, texture, face, level); - - trace_dump_ret(uint, referenced); - trace_dump_call_end(); - - return referenced; -} - -static unsigned int -trace_is_buffer_referenced( struct pipe_context *_pipe, - struct pipe_buffer *_buf) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_buffer *tr_buf = trace_buffer(_buf); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_buffer *buf = tr_buf->buffer; - unsigned int referenced; - - trace_dump_call_begin("pipe_context", "is_buffer_referenced"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, buf); - - referenced = pipe->is_buffer_referenced(pipe, buf); + referenced = pipe->is_resource_referenced(pipe, texture, face, level); trace_dump_ret(uint, referenced); trace_dump_call_end(); @@ -1349,37 +1302,35 @@ trace_is_buffer_referenced( struct pipe_context *_pipe, static struct pipe_transfer * -trace_context_get_tex_transfer(struct pipe_context *_context, - struct pipe_texture *_texture, - unsigned face, unsigned level, - unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +trace_context_get_transfer(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct trace_context *tr_context = trace_context(_context); - struct trace_texture *tr_tex = trace_texture(_texture); + struct trace_resource *tr_tex = trace_resource(_resource); struct pipe_context *context = tr_context->pipe; - struct pipe_texture *texture = tr_tex->texture; + struct pipe_resource *texture = tr_tex->resource; struct pipe_transfer *result = NULL; assert(texture->screen == context->screen); - trace_dump_call_begin("pipe_context", "get_tex_transfer"); + trace_dump_call_begin("pipe_context", "get_transfer"); trace_dump_arg(ptr, context); trace_dump_arg(ptr, texture); - trace_dump_arg(uint, face); - trace_dump_arg(uint, level); - trace_dump_arg(uint, zslice); + trace_dump_arg(uint, sr.face); + trace_dump_arg(uint, sr.level); trace_dump_arg(uint, usage); + trace_dump_arg(uint, box->x); + trace_dump_arg(uint, box->y); + trace_dump_arg(uint, box->z); + trace_dump_arg(uint, box->width); + trace_dump_arg(uint, box->height); + trace_dump_arg(uint, box->depth); - trace_dump_arg(uint, x); - trace_dump_arg(uint, y); - trace_dump_arg(uint, w); - trace_dump_arg(uint, h); - - result = context->get_tex_transfer(context, texture, face, level, zslice, usage, - x, y, w, h); + result = context->get_transfer(context, texture, sr, usage, box); trace_dump_ret(ptr, result); @@ -1393,7 +1344,7 @@ trace_context_get_tex_transfer(struct pipe_context *_context, static void -trace_context_tex_transfer_destroy(struct pipe_context *_context, +trace_context_transfer_destroy(struct pipe_context *_context, struct pipe_transfer *_transfer) { struct trace_context *tr_context = trace_context(_context); @@ -1401,7 +1352,7 @@ trace_context_tex_transfer_destroy(struct pipe_context *_context, struct pipe_context *context = tr_context->pipe; struct pipe_transfer *transfer = tr_trans->transfer; - trace_dump_call_begin("pipe_context", "tex_transfer_destroy"); + trace_dump_call_begin("pipe_context", "transfer_destroy"); trace_dump_arg(ptr, context); trace_dump_arg(ptr, transfer); @@ -1435,6 +1386,33 @@ trace_context_transfer_map(struct pipe_context *_context, static void +trace_context_transfer_flush_region( struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) +{ + struct trace_context *tr_context = trace_context(_context); + struct trace_transfer *tr_transfer = trace_transfer(_transfer); + struct pipe_context *context = tr_context->pipe; + struct pipe_transfer *transfer = tr_transfer->transfer; + + trace_dump_call_begin("pipe_context", "transfer_flush_region"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, transfer); + trace_dump_arg(uint, box->x); + trace_dump_arg(uint, box->y); + trace_dump_arg(uint, box->z); + trace_dump_arg(uint, box->width); + trace_dump_arg(uint, box->height); + trace_dump_arg(uint, box->depth); + trace_dump_call_end(); + + context->transfer_flush_region(context, + transfer, + box); +} + +static void trace_context_transfer_unmap(struct pipe_context *_context, struct pipe_transfer *_transfer) { @@ -1444,8 +1422,6 @@ trace_context_transfer_unmap(struct pipe_context *_context, struct pipe_transfer *transfer = tr_trans->transfer; if(tr_trans->map) { - size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride; - trace_dump_call_begin("pipe_context", "transfer_write"); trace_dump_arg(ptr, context); @@ -1457,12 +1433,16 @@ trace_context_transfer_unmap(struct pipe_context *_context, trace_dump_arg_end(); trace_dump_arg_begin("data"); - trace_dump_bytes(tr_trans->map, size); + trace_dump_box_bytes(tr_trans->map, + transfer->resource->format, + &transfer->box, + transfer->stride, + transfer->slice_stride); trace_dump_arg_end(); - trace_dump_arg_begin("size"); - trace_dump_uint(size); - trace_dump_arg_end(); +// trace_dump_arg_begin("size"); +// trace_dump_uint(size); +// trace_dump_arg_end(); trace_dump_call_end(); @@ -1472,6 +1452,57 @@ trace_context_transfer_unmap(struct pipe_context *_context, context->transfer_unmap(context, transfer); } + +static void +trace_context_transfer_inline_write(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ + struct trace_context *tr_context = trace_context(_context); + struct trace_resource *tr_tex = trace_resource(_resource); + struct pipe_context *context = tr_context->pipe; + struct pipe_resource *resource = tr_tex->resource; + + assert(resource->screen == context->screen); + + trace_dump_call_begin("pipe_context", "transfer_inline_write"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, sr.face); + trace_dump_arg(uint, sr.level); + trace_dump_arg(uint, usage); + trace_dump_arg(uint, box->x); + trace_dump_arg(uint, box->y); + trace_dump_arg(uint, box->z); + trace_dump_arg(uint, box->width); + trace_dump_arg(uint, box->height); + trace_dump_arg(uint, box->depth); + trace_dump_arg(uint, stride); + trace_dump_arg(uint, slice_stride); + + trace_dump_arg_begin("data"); + trace_dump_box_bytes(data, + resource->format, + box, + stride, + slice_stride); + trace_dump_arg_end(); + + trace_dump_call_end(); + + context->transfer_inline_write(context, resource, + sr, usage, box, data, stride, slice_stride); +} + + + + static const struct debug_named_value rbug_blocker_flags[] = { {"before", 1}, {"after", 2}, @@ -1555,13 +1586,14 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.surface_fill = trace_context_surface_fill; tr_ctx->base.clear = trace_context_clear; tr_ctx->base.flush = trace_context_flush; - tr_ctx->base.is_texture_referenced = trace_is_texture_referenced; - tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced; + tr_ctx->base.is_resource_referenced = trace_is_resource_referenced; - tr_ctx->base.get_tex_transfer = trace_context_get_tex_transfer; - tr_ctx->base.tex_transfer_destroy = trace_context_tex_transfer_destroy; + tr_ctx->base.get_transfer = trace_context_get_transfer; + tr_ctx->base.transfer_destroy = trace_context_transfer_destroy; tr_ctx->base.transfer_map = trace_context_transfer_map; tr_ctx->base.transfer_unmap = trace_context_transfer_unmap; + tr_ctx->base.transfer_flush_region = trace_context_transfer_flush_region; + tr_ctx->base.transfer_inline_write = trace_context_transfer_inline_write; tr_ctx->pipe = pipe; diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index feec9b6bbf3..1b4121d80a9 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -60,8 +60,8 @@ struct trace_context unsigned num_vert_sampler_views; unsigned nr_cbufs; - struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS]; - struct trace_texture *zsbuf; + struct trace_resource *cbufs[PIPE_MAX_COLOR_BUFS]; + struct trace_resource *zsbuf; } curr; struct { @@ -69,7 +69,7 @@ struct trace_context struct trace_shader *vs; struct trace_sampler_view *sampler_view; - struct trace_texture *surf; + struct trace_resource *surf; int blocker; } draw_rule; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 1affafdddc6..19cf0de1d38 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -54,7 +54,6 @@ #include "tr_dump.h" #include "tr_screen.h" #include "tr_texture.h" -#include "tr_buffer.h" static struct os_stream *stream = NULL; @@ -471,6 +470,16 @@ void trace_dump_bytes(const void *data, trace_dump_writes("</bytes>"); } +void trace_dump_box_bytes(const void *data, + unsigned format, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride) +{ + //size_t size = util_format_get_nblocksy(transfer->resource->format, transfer->box.height) * transfer->stride; + +} + void trace_dump_string(const char *str) { if (!dumping) @@ -574,27 +583,15 @@ void trace_dump_ptr(const void *value) trace_dump_null(); } -void trace_dump_buffer_ptr(struct pipe_buffer *_buffer) -{ - if (!dumping) - return; - - if (_buffer) { - struct trace_buffer *tr_buf = trace_buffer(_buffer); - trace_dump_ptr(tr_buf->buffer); - } else { - trace_dump_null(); - } -} -void trace_dump_texture_ptr(struct pipe_texture *_texture) +void trace_dump_resource_ptr(struct pipe_resource *_resource) { if (!dumping) return; - if (_texture) { - struct trace_texture *tr_tex = trace_texture(_texture); - trace_dump_ptr(tr_tex->texture); + if (_resource) { + struct trace_resource *tr_resource = trace_resource(_resource); + trace_dump_ptr(tr_resource->resource); } else { trace_dump_null(); } diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 32592bab12f..9383ccdecb9 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -36,11 +36,11 @@ #include "pipe/p_compiler.h" - struct pipe_buffer; -struct pipe_texture; +struct pipe_resource; struct pipe_surface; struct pipe_transfer; +struct pipe_box; /* * Call before use. @@ -92,6 +92,11 @@ void trace_dump_int(long long int value); void trace_dump_uint(long long unsigned value); void trace_dump_float(double value); void trace_dump_bytes(const void *data, size_t size); +void trace_dump_box_bytes(const void *data, + unsigned format, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride); void trace_dump_string(const char *str); void trace_dump_enum(const char *value); void trace_dump_array_begin(void); @@ -105,8 +110,7 @@ void trace_dump_member_end(void); void trace_dump_null(void); void trace_dump_ptr(const void *value); /* will turn a wrapped object into the real one and dump ptr */ -void trace_dump_buffer_ptr(struct pipe_buffer *_buffer); -void trace_dump_texture_ptr(struct pipe_texture *_texture); +void trace_dump_resource_ptr(struct pipe_resource *_texture); void trace_dump_surface_ptr(struct pipe_surface *_surface); void trace_dump_transfer_ptr(struct pipe_transfer *_transfer); diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index f82dd01c697..1b917ff3fb9 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -44,7 +44,7 @@ void trace_dump_format(enum pipe_format format) } -void trace_dump_template(const struct pipe_texture *templat) +void trace_dump_template(const struct pipe_resource *templat) { if (!trace_dumping_enabled_locked()) return; @@ -54,7 +54,7 @@ void trace_dump_template(const struct pipe_texture *templat) return; } - trace_dump_struct_begin("pipe_texture"); + trace_dump_struct_begin("pipe_resource"); trace_dump_member(int, templat, target); trace_dump_member(format, templat, format); @@ -72,7 +72,9 @@ void trace_dump_template(const struct pipe_texture *templat) trace_dump_member_end(); trace_dump_member(uint, templat, last_level); - trace_dump_member(uint, templat, tex_usage); + trace_dump_member(uint, templat, _usage); + trace_dump_member(uint, templat, bind); + trace_dump_member(uint, templat, flags); trace_dump_struct_end(); } @@ -428,16 +430,16 @@ void trace_dump_transfer(const struct pipe_transfer *state) trace_dump_struct_begin("pipe_transfer"); - trace_dump_member(uint, state, width); - trace_dump_member(uint, state, height); + trace_dump_member(uint, state, box.width); + trace_dump_member(uint, state, box.height); trace_dump_member(uint, state, stride); trace_dump_member(uint, state, usage); - trace_dump_member(ptr, state, texture); - trace_dump_member(uint, state, face); - trace_dump_member(uint, state, level); - trace_dump_member(uint, state, zslice); + trace_dump_member(ptr, state, resource); + trace_dump_member(uint, state, sr.face); + trace_dump_member(uint, state, sr.level); + trace_dump_member(uint, state, box.z); trace_dump_struct_end(); } @@ -458,7 +460,7 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) trace_dump_member(uint, state, stride); trace_dump_member(uint, state, max_index); trace_dump_member(uint, state, buffer_offset); - trace_dump_member(buffer_ptr, state, buffer); + trace_dump_member(resource_ptr, state, buffer); trace_dump_struct_end(); } diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h index 3400367d82a..41f6263935f 100644 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -35,7 +35,7 @@ void trace_dump_format(enum pipe_format format); -void trace_dump_template(const struct pipe_texture *templat); +void trace_dump_template(const struct pipe_resource *templat); void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index 53ab8c686d8..3ce1b85854b 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -29,6 +29,7 @@ #include "os/os_thread.h" #include "util/u_format.h" #include "util/u_string.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_simple_list.h" #include "util/u_network.h" @@ -38,7 +39,6 @@ #include "tr_dump.h" #include "tr_state.h" -#include "tr_buffer.h" #include "tr_texture.h" #include "rbug/rbug.h" @@ -150,7 +150,7 @@ static int trace_rbug_texture_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) { struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_texture *tr_tex = NULL; + struct trace_resource *tr_tex = NULL; struct tr_list *ptr; rbug_texture_t *texs; int i = 0; @@ -158,7 +158,7 @@ trace_rbug_texture_list(struct trace_rbug *tr_rbug, struct rbug_header *header, pipe_mutex_lock(tr_scr->list_mutex); texs = MALLOC(tr_scr->num_textures * sizeof(rbug_texture_t)); foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list)); + tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); texs[i++] = VOID2U64(tr_tex); } pipe_mutex_unlock(tr_scr->list_mutex); @@ -173,14 +173,14 @@ static int trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) { struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_texture *tr_tex = NULL; + struct trace_resource *tr_tex = NULL; struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header; struct tr_list *ptr; - struct pipe_texture *t; + struct pipe_resource *t; pipe_mutex_lock(tr_scr->list_mutex); foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list)); + tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); if (gpti->texture == VOID2U64(tr_tex)) break; tr_tex = NULL; @@ -191,7 +191,7 @@ trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, return -ESRCH; } - t = tr_tex->texture; + t = tr_tex->resource; rbug_send_texture_info_reply(tr_rbug->con, serial, t->target, t->format, &t->width0, 1, @@ -202,7 +202,7 @@ trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, util_format_get_blocksize(t->format), t->last_level, t->nr_samples, - t->tex_usage, + t->bind, NULL); pipe_mutex_unlock(tr_scr->list_mutex); @@ -216,18 +216,18 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header; struct trace_screen *tr_scr = tr_rbug->tr_scr; - struct trace_texture *tr_tex = NULL; + struct trace_resource *tr_tex = NULL; struct tr_list *ptr; struct pipe_context *context = tr_scr->private_context; - struct pipe_texture *tex; + struct pipe_resource *tex; struct pipe_transfer *t; void *map; pipe_mutex_lock(tr_scr->list_mutex); foreach(ptr, &tr_scr->textures) { - tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list)); + tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list)); if (gptr->texture == VOID2U64(tr_tex)) break; tr_tex = NULL; @@ -238,8 +238,8 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, return -ESRCH; } - tex = tr_tex->texture; - t = context->get_tex_transfer(context, tex, + tex = tr_tex->resource; + t = pipe_get_transfer(context, tex, gptr->face, gptr->level, gptr->zslice, PIPE_TRANSFER_READ, gptr->x, gptr->y, gptr->w, gptr->h); @@ -247,17 +247,18 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, map = context->transfer_map(context, t); rbug_send_texture_read_reply(tr_rbug->con, serial, - t->texture->format, - util_format_get_blockwidth(t->texture->format), - util_format_get_blockheight(t->texture->format), - util_format_get_blocksize(t->texture->format), + t->resource->format, + util_format_get_blockwidth(t->resource->format), + util_format_get_blockheight(t->resource->format), + util_format_get_blocksize(t->resource->format), (uint8_t*)map, - t->stride * util_format_get_nblocksy(t->texture->format, t->height), + t->stride * util_format_get_nblocksy(t->resource->format, + t->box.height), t->stride, NULL); context->transfer_unmap(context, t); - context->tex_transfer_destroy(context, t); + context->transfer_destroy(context, t); pipe_mutex_unlock(tr_scr->list_mutex); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 25990bdac7f..dbd10c6f761 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -29,7 +29,6 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" -#include "tr_buffer.h" #include "tr_dump.h" #include "tr_dump_state.h" #include "tr_texture.h" @@ -213,72 +212,73 @@ trace_screen_flush_frontbuffer(struct pipe_screen *_screen, */ -static struct pipe_texture * -trace_screen_texture_create(struct pipe_screen *_screen, - const struct pipe_texture *templat) +static struct pipe_resource * +trace_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - struct pipe_texture *result; + struct pipe_resource *result; - trace_dump_call_begin("pipe_screen", "texture_create"); + trace_dump_call_begin("pipe_screen", "resource_create"); trace_dump_arg(ptr, screen); trace_dump_arg(template, templat); - result = screen->texture_create(screen, templat); + result = screen->resource_create(screen, templat); trace_dump_ret(ptr, result); trace_dump_call_end(); - result = trace_texture_create(tr_scr, result); + result = trace_resource_create(tr_scr, result); return result; } -static struct pipe_texture * -trace_screen_texture_from_handle(struct pipe_screen *_screen, - const struct pipe_texture *templ, +static struct pipe_resource * +trace_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, struct winsys_handle *handle) { struct trace_screen *tr_screen = trace_screen(_screen); struct pipe_screen *screen = tr_screen->screen; - struct pipe_texture *result; + struct pipe_resource *result; /* TODO trace call */ - result = screen->texture_from_handle(screen, templ, handle); + result = screen->resource_from_handle(screen, templ, handle); - result = trace_texture_create(trace_screen(_screen), result); + result = trace_resource_create(trace_screen(_screen), result); return result; } static boolean -trace_screen_texture_get_handle(struct pipe_screen *_screen, - struct pipe_texture *_texture, +trace_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_resource *_texture, struct winsys_handle *handle) { struct trace_screen *tr_screen = trace_screen(_screen); - struct trace_texture *tr_texture = trace_texture(_texture); + struct trace_resource *tr_texture = trace_resource(_texture); struct pipe_screen *screen = tr_screen->screen; - struct pipe_texture *texture = tr_texture->texture; + struct pipe_resource *texture = tr_texture->resource; /* TODO trace call */ - return screen->texture_get_handle(screen, texture, handle); + return screen->resource_get_handle(screen, texture, handle); } static void -trace_screen_texture_destroy(struct pipe_texture *_texture) +trace_screen_resource_destroy(struct pipe_screen *_screen, + struct pipe_resource *_texture) { - struct trace_screen *tr_scr = trace_screen(_texture->screen); - struct trace_texture *tr_tex = trace_texture(_texture); + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_resource *tr_tex = trace_resource(_texture); struct pipe_screen *screen = tr_scr->screen; - struct pipe_texture *texture = tr_tex->texture; + struct pipe_resource *texture = tr_tex->resource; assert(texture->screen == screen); @@ -289,7 +289,7 @@ trace_screen_texture_destroy(struct pipe_texture *_texture) trace_dump_call_end(); - trace_texture_destroy(tr_tex); + trace_resource_destroy(tr_scr, tr_tex); } @@ -300,15 +300,15 @@ trace_screen_texture_destroy(struct pipe_texture *_texture) static struct pipe_surface * trace_screen_get_tex_surface(struct pipe_screen *_screen, - struct pipe_texture *_texture, + struct pipe_resource *_texture, unsigned face, unsigned level, unsigned zslice, unsigned usage) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(_texture); + struct trace_resource *tr_tex = trace_resource(_texture); struct pipe_screen *screen = tr_scr->screen; - struct pipe_texture *texture = tr_tex->texture; + struct pipe_resource *texture = tr_tex->resource; struct pipe_surface *result = NULL; assert(texture->screen == screen); @@ -362,53 +362,15 @@ trace_screen_tex_surface_destroy(struct pipe_surface *_surface) - - -static struct pipe_buffer * -trace_screen_buffer_create(struct pipe_screen *_screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *result; - - trace_dump_call_begin("pipe_screen", "buffer_create"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(uint, alignment); - trace_dump_arg(uint, usage); - trace_dump_arg(uint, size); - - result = screen->buffer_create(screen, alignment, usage, size); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - /* Zero the buffer to avoid dumping uninitialized memory */ - if(result->usage & PIPE_BUFFER_USAGE_CPU_WRITE) { - void *map; - map = pipe_buffer_map(screen, result, PIPE_BUFFER_USAGE_CPU_WRITE); - if(map) { - memset(map, 0, result->size); - screen->buffer_unmap(screen, result); - } - } - - return trace_buffer_create(tr_scr, result); -} - - -static struct pipe_buffer * +static struct pipe_resource * trace_screen_user_buffer_create(struct pipe_screen *_screen, void *data, - unsigned size) + unsigned size, + unsigned usage) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *result; + struct pipe_resource *result; trace_dump_call_begin("pipe_screen", "user_buffer_create"); @@ -417,189 +379,23 @@ trace_screen_user_buffer_create(struct pipe_screen *_screen, trace_dump_bytes(data, size); trace_dump_arg_end(); trace_dump_arg(uint, size); + trace_dump_arg(uint, usage); - result = screen->user_buffer_create(screen, data, size); + result = screen->user_buffer_create(screen, data, size, usage); trace_dump_ret(ptr, result); trace_dump_call_end(); if(result) { - assert(!(result->usage & TRACE_BUFFER_USAGE_USER)); - result->usage |= TRACE_BUFFER_USAGE_USER; - } - - return trace_buffer_create(tr_scr, result); -} - - -/** - * This function is used to track if data has been changed on a user buffer - * without map/unmap being called. - */ -void -trace_screen_user_buffer_update(struct pipe_screen *_screen, - struct pipe_buffer *_buffer) -{ -#if 0 - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - const void *map; - - if(buffer && buffer->usage & TRACE_BUFFER_USAGE_USER) { - map = screen->buffer_map(screen, buffer, PIPE_BUFFER_USAGE_CPU_READ); - if(map) { - trace_dump_call_begin("pipe_winsys", "buffer_write"); - - trace_dump_arg(ptr, screen); - - trace_dump_arg(ptr, buffer); - - trace_dump_arg_begin("data"); - trace_dump_bytes(map, buffer->size); - trace_dump_arg_end(); - - trace_dump_arg_begin("size"); - trace_dump_uint(buffer->size); - trace_dump_arg_end(); - - trace_dump_call_end(); - - screen->buffer_unmap(screen, buffer); - } - } -#endif -} - - -static void * -trace_screen_buffer_map(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned usage) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - void *map; - - assert(screen->buffer_map); - map = screen->buffer_map(screen, buffer, usage); - if(map) { - if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { - tr_buf->map = map; - } - } - - return map; -} - - -static void * -trace_screen_buffer_map_range(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned offset, - unsigned length, - unsigned usage) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - void *map; - - assert(screen->buffer_map_range); - map = screen->buffer_map_range(screen, buffer, offset, length, usage); - if(map) { - if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { - tr_buf->map = map; - } + assert(!(result->flags & TRACE_FLAG_USER_BUFFER)); + result->flags |= TRACE_FLAG_USER_BUFFER; } - return map; -} - - -static void -buffer_write(struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned offset, - const char *map, - unsigned size) -{ - assert(map); - - trace_dump_call_begin("pipe_screen", "buffer_write"); - - trace_dump_arg(ptr, screen); - - trace_dump_arg(ptr, buffer); - - trace_dump_arg(uint, offset); - - trace_dump_arg_begin("data"); - trace_dump_bytes(map + offset, size); - trace_dump_arg_end(); - - trace_dump_arg(uint, size); - - trace_dump_call_end(); - -} - - -static void -trace_screen_buffer_flush_mapped_range(struct pipe_screen *_screen, - struct pipe_buffer *_buffer, - unsigned offset, - unsigned length) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - - assert(tr_buf->map); - buffer_write(screen, buffer, offset, tr_buf->map, length); - tr_buf->range_flushed = TRUE; - screen->buffer_flush_mapped_range(screen, buffer, offset, length); + return trace_resource_create(tr_scr, result); } -static void -trace_screen_buffer_unmap(struct pipe_screen *_screen, - struct pipe_buffer *_buffer) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - - if (tr_buf->map && !tr_buf->range_flushed) - buffer_write(screen, buffer, 0, tr_buf->map, buffer->size); - tr_buf->map = NULL; - tr_buf->range_flushed = FALSE; - screen->buffer_unmap(screen, buffer); -} - - -static void -trace_screen_buffer_destroy(struct pipe_buffer *_buffer) -{ - struct trace_screen *tr_scr = trace_screen(_buffer->screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - - trace_dump_call_begin("pipe_screen", "buffer_destroy"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, buffer); - - trace_dump_call_end(); - - trace_buffer_destroy(tr_scr, _buffer); -} /******************************************************************** @@ -769,23 +565,13 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.is_format_supported = trace_screen_is_format_supported; assert(screen->context_create); tr_scr->base.context_create = trace_screen_context_create; - tr_scr->base.texture_create = trace_screen_texture_create; - tr_scr->base.texture_from_handle = trace_screen_texture_from_handle; - tr_scr->base.texture_get_handle = trace_screen_texture_get_handle; - tr_scr->base.texture_destroy = trace_screen_texture_destroy; + tr_scr->base.resource_create = trace_screen_resource_create; + tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; + tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; + tr_scr->base.resource_destroy = trace_screen_resource_destroy; tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy; - tr_scr->base.buffer_create = trace_screen_buffer_create; tr_scr->base.user_buffer_create = trace_screen_user_buffer_create; - if (screen->buffer_map) - tr_scr->base.buffer_map = trace_screen_buffer_map; - if (screen->buffer_map_range) - tr_scr->base.buffer_map_range = trace_screen_buffer_map_range; - if (screen->buffer_flush_mapped_range) - tr_scr->base.buffer_flush_mapped_range = trace_screen_buffer_flush_mapped_range; - if (screen->buffer_unmap) - tr_scr->base.buffer_unmap = trace_screen_buffer_unmap; - tr_scr->base.buffer_destroy = trace_screen_buffer_destroy; tr_scr->base.fence_reference = trace_screen_fence_reference; tr_scr->base.fence_signalled = trace_screen_fence_signalled; tr_scr->base.fence_finish = trace_screen_fence_finish; diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 9bfbe72e2c0..05ff9ef61f1 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -48,7 +48,7 @@ struct tr_list { * without mapping/unmapping. This flag marks user buffers, so that their * contents can be dumpped before being used by the pipe context. */ -#define TRACE_BUFFER_USAGE_USER (1 << 31) +#define TRACE_FLAG_USER_BUFFER (1 << 31) struct trace_screen @@ -100,10 +100,6 @@ trace_enabled(void); struct trace_screen * trace_screen(struct pipe_screen *screen); -void -trace_screen_user_buffer_update(struct pipe_screen *screen, - struct pipe_buffer *buffer); - #define trace_screen_add_to_list(tr_scr, name, obj) \ do { \ pipe_mutex_lock(tr_scr->list_mutex); \ diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index d818e21bb82..1132dc92724 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -35,51 +35,50 @@ #include "tr_texture.h" -struct pipe_texture * -trace_texture_create(struct trace_screen *tr_scr, - struct pipe_texture *texture) +struct pipe_resource * +trace_resource_create(struct trace_screen *tr_scr, + struct pipe_resource *texture) { - struct trace_texture *tr_tex; + struct trace_resource *tr_tex; if(!texture) goto error; assert(texture->screen == tr_scr->screen); - tr_tex = CALLOC_STRUCT(trace_texture); + tr_tex = CALLOC_STRUCT(trace_resource); if(!tr_tex) goto error; - memcpy(&tr_tex->base, texture, sizeof(struct pipe_texture)); + memcpy(&tr_tex->base, texture, sizeof(struct pipe_resource)); pipe_reference_init(&tr_tex->base.reference, 1); tr_tex->base.screen = &tr_scr->base; - tr_tex->texture = texture; + tr_tex->resource = texture; trace_screen_add_to_list(tr_scr, textures, tr_tex); return &tr_tex->base; error: - pipe_texture_reference(&texture, NULL); + pipe_resource_reference(&texture, NULL); return NULL; } void -trace_texture_destroy(struct trace_texture *tr_tex) +trace_resource_destroy(struct trace_screen *tr_scr, + struct trace_resource *tr_tex) { - struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen); - trace_screen_remove_from_list(tr_scr, textures, tr_tex); - pipe_texture_reference(&tr_tex->texture, NULL); + pipe_resource_reference(&tr_tex->resource, NULL); FREE(tr_tex); } struct pipe_surface * -trace_surface_create(struct trace_texture *tr_tex, +trace_surface_create(struct trace_resource *tr_tex, struct pipe_surface *surface) { struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen); @@ -88,7 +87,7 @@ trace_surface_create(struct trace_texture *tr_tex, if(!surface) goto error; - assert(surface->texture == tr_tex->texture); + assert(surface->texture == tr_tex->resource); tr_surf = CALLOC_STRUCT(trace_surface); if(!tr_surf) @@ -98,7 +97,7 @@ trace_surface_create(struct trace_texture *tr_tex, pipe_reference_init(&tr_surf->base.reference, 1); tr_surf->base.texture = NULL; - pipe_texture_reference(&tr_surf->base.texture, &tr_tex->base); + pipe_resource_reference(&tr_surf->base.texture, &tr_tex->base); tr_surf->surface = surface; trace_screen_add_to_list(tr_scr, surfaces, tr_surf); @@ -118,7 +117,7 @@ trace_surface_destroy(struct trace_surface *tr_surf) trace_screen_remove_from_list(tr_scr, surfaces, tr_surf); - pipe_texture_reference(&tr_surf->base.texture, NULL); + pipe_resource_reference(&tr_surf->base.texture, NULL); pipe_surface_reference(&tr_surf->surface, NULL); FREE(tr_surf); } @@ -126,7 +125,7 @@ trace_surface_destroy(struct trace_surface *tr_surf) struct pipe_transfer * trace_transfer_create(struct trace_context *tr_ctx, - struct trace_texture *tr_tex, + struct trace_resource *tr_tex, struct pipe_transfer *transfer) { struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen); @@ -135,7 +134,7 @@ trace_transfer_create(struct trace_context *tr_ctx, if(!transfer) goto error; - assert(transfer->texture == tr_tex->texture); + assert(transfer->resource == tr_tex->resource); tr_trans = CALLOC_STRUCT(trace_transfer); if(!tr_trans) @@ -143,18 +142,18 @@ trace_transfer_create(struct trace_context *tr_ctx, memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer)); - tr_trans->base.texture = NULL; + tr_trans->base.resource = NULL; tr_trans->transfer = transfer; - pipe_texture_reference(&tr_trans->base.texture, &tr_tex->base); - assert(tr_trans->base.texture == &tr_tex->base); + pipe_resource_reference(&tr_trans->base.resource, &tr_tex->base); + assert(tr_trans->base.resource == &tr_tex->base); trace_screen_add_to_list(tr_scr, transfers, tr_trans); return &tr_trans->base; error: - tr_ctx->pipe->tex_transfer_destroy(tr_ctx->pipe, transfer); + tr_ctx->pipe->transfer_destroy(tr_ctx->pipe, transfer); return NULL; } @@ -169,8 +168,8 @@ trace_transfer_destroy(struct trace_context *tr_context, trace_screen_remove_from_list(tr_scr, transfers, tr_trans); - pipe_texture_reference(&tr_trans->base.texture, NULL); - context->tex_transfer_destroy(context, transfer); + pipe_resource_reference(&tr_trans->base.resource, NULL); + context->transfer_destroy(context, transfer); FREE(tr_trans); } diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h index 66250465e44..6513995d505 100644 --- a/src/gallium/drivers/trace/tr_texture.h +++ b/src/gallium/drivers/trace/tr_texture.h @@ -36,11 +36,11 @@ struct trace_context; -struct trace_texture +struct trace_resource { - struct pipe_texture base; + struct pipe_resource base; - struct pipe_texture *texture; + struct pipe_resource *resource; struct tr_list list; }; @@ -77,13 +77,13 @@ struct trace_transfer }; -static INLINE struct trace_texture * -trace_texture(struct pipe_texture *texture) +static INLINE struct trace_resource * +trace_resource(struct pipe_resource *texture) { if(!texture) return NULL; (void)trace_screen(texture->screen); - return (struct trace_texture *)texture; + return (struct trace_resource *)texture; } @@ -92,7 +92,7 @@ trace_surface(struct pipe_surface *surface) { if(!surface) return NULL; - (void)trace_texture(surface->texture); + (void)trace_resource(surface->texture); return (struct trace_surface *)surface; } @@ -111,20 +111,21 @@ trace_transfer(struct pipe_transfer *transfer) { if(!transfer) return NULL; - (void)trace_texture(transfer->texture); + (void)trace_resource(transfer->resource); return (struct trace_transfer *)transfer; } -struct pipe_texture * -trace_texture_create(struct trace_screen *tr_scr, - struct pipe_texture *texture); +struct pipe_resource * +trace_resource_create(struct trace_screen *tr_scr, + struct pipe_resource *texture); void -trace_texture_destroy(struct trace_texture *tr_tex); +trace_resource_destroy(struct trace_screen *tr_scr, + struct trace_resource *tr_tex); struct pipe_surface * -trace_surface_create(struct trace_texture *tr_tex, +trace_surface_create(struct trace_resource *tr_tex, struct pipe_surface *surface); void @@ -132,7 +133,7 @@ trace_surface_destroy(struct trace_surface *tr_surf); struct pipe_transfer * trace_transfer_create(struct trace_context *tr_ctx, - struct trace_texture *tr_tex, + struct trace_resource *tr_tex, struct pipe_transfer *transfer); void |