diff options
Diffstat (limited to 'src/gallium/drivers/r300')
22 files changed, 651 insertions, 537 deletions
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, |