diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/r600/Makefile | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/SConscript | 9 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_buffer.c | 173 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_compiler_tgsi.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_context.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_context.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_draw.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_helper.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_resource.c | 68 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_resource.h | 33 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_screen.c | 86 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_screen.h | 37 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 87 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 140 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.h | 19 |
15 files changed, 490 insertions, 232 deletions
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index bc58575c789..aae31a6a6eb 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -13,6 +13,7 @@ C_SOURCES = \ r600_blit.c \ r600_helper.c \ r600_query.c \ + r600_resource.c \ r600_screen.c \ r600_state.c \ r600_texture.c \ diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index a88c5452529..26d95bb766d 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -12,10 +12,19 @@ r600 = env.ConvenienceLibrary( 'r600_buffer.c', 'r600_context.c', 'r600_draw.c', + 'r600_blit.c', + 'r600_helper.c', 'r600_query.c', + 'r600_resource.c', 'r600_screen.c', 'r600_state.c', 'r600_texture.c', + 'r600_shader.c', + 'r600_compiler.c', + 'r600_compiler_tgsi.c', + 'r600_compiler_dump.c', + 'r600_compiler_r600.c', + 'r600_compiler_r700.c' ]) Export('r600') diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index f3a0208b003..634a02b686e 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -29,89 +29,108 @@ #include <util/u_math.h> #include <util/u_inlines.h> #include <util/u_memory.h> +#include "state_tracker/drm_api.h" #include "r600_screen.h" -#include "r600_texture.h" #include "r600_context.h" +extern struct u_resource_vtbl r600_buffer_vtbl; + static u32 r600_domain_from_usage(unsigned usage) { u32 domain = RADEON_GEM_DOMAIN_GTT; - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - domain |= RADEON_GEM_DOMAIN_VRAM; + if (usage & PIPE_BIND_RENDER_TARGET) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BIND_DEPTH_STENCIL) { + domain |= RADEON_GEM_DOMAIN_VRAM; } - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; + if (usage & PIPE_BIND_SAMPLER_VIEW) { + domain |= RADEON_GEM_DOMAIN_VRAM; } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; + /* also need BIND_BLIT_SOURCE/DESTINATION ? */ + if (usage & PIPE_BIND_VERTEX_BUFFER) { + domain |= RADEON_GEM_DOMAIN_GTT; } - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; + if (usage & PIPE_BIND_INDEX_BUFFER) { + domain |= RADEON_GEM_DOMAIN_GTT; } + return domain; } -static struct pipe_buffer *r600_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) +struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *templ) { struct r600_screen *rscreen = r600_screen(screen); - struct r600_pipe_buffer *rbuffer; + struct r600_buffer *rbuffer; struct radeon_bo *bo; struct pb_desc desc; + /* XXX We probably want a different alignment for buffers and textures. */ + unsigned alignment = 4096; - rbuffer = CALLOC_STRUCT(r600_pipe_buffer); + rbuffer = CALLOC_STRUCT(r600_buffer); if (rbuffer == NULL) return NULL; - pipe_reference_init(&rbuffer->base.reference, 1); - rbuffer->base.screen = screen; - rbuffer->base.alignment = alignment; - rbuffer->base.usage = usage; - rbuffer->base.size = size; + pipe_reference_init(&rbuffer->b.b.reference, 1); + rbuffer->b.b = *templ; + rbuffer->b.b.screen = screen; + rbuffer->b.vtbl = &r600_buffer_vtbl; - if (usage & PIPE_BUFFER_USAGE_CONSTANT) { + if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { desc.alignment = alignment; - desc.usage = usage; - rbuffer->pb = pb_malloc_buffer_create(size, &desc); + desc.usage = rbuffer->b.b.bind; + rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0, + &desc); if (rbuffer->pb == NULL) { free(rbuffer); return NULL; } - return &rbuffer->base; + return &rbuffer->b.b; } - rbuffer->domain = r600_domain_from_usage(usage); - bo = radeon_bo(rscreen->rw, 0, size, alignment, NULL); + rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind); + bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL); if (bo == NULL) { FREE(rbuffer); return NULL; } rbuffer->bo = bo; - return &rbuffer->base; + return &rbuffer->b.b; } -static struct pipe_buffer *r600_user_buffer_create(struct pipe_screen *screen, - void *ptr, unsigned bytes) +struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, + void *ptr, unsigned bytes, + unsigned bind) { - struct r600_pipe_buffer *rbuffer; + struct r600_buffer *rbuffer; struct r600_screen *rscreen = r600_screen(screen); - - rbuffer = (struct r600_pipe_buffer*)r600_buffer_create(screen, 0, 0, bytes); + struct pipe_resource templ; + + memset(&templ, 0, sizeof(struct pipe_resource)); + templ.target = PIPE_BUFFER; + templ.format = PIPE_FORMAT_R8_UNORM; + templ.usage = PIPE_USAGE_IMMUTABLE; + templ.bind = bind; + templ.width0 = bytes; + templ.height0 = 1; + templ.depth0 = 1; + + rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ); if (rbuffer == NULL) { return NULL; } radeon_bo_map(rscreen->rw, rbuffer->bo); memcpy(rbuffer->bo->data, ptr, bytes); radeon_bo_unmap(rscreen->rw, rbuffer->bo); - return &rbuffer->base; + return &rbuffer->b.b; } -static void r600_buffer_destroy(struct pipe_buffer *buffer) +static void r600_buffer_destroy(struct pipe_screen *screen, + struct pipe_resource *buf) { - struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer; - struct r600_screen *rscreen = r600_screen(buffer->screen); + struct r600_buffer *rbuffer = (struct r600_buffer*)buf; + struct r600_screen *rscreen = r600_screen(screen); if (rbuffer->pb) { pipe_reference_init(&rbuffer->pb->base.reference, 0); @@ -124,34 +143,33 @@ static void r600_buffer_destroy(struct pipe_buffer *buffer) FREE(rbuffer); } -static void *r600_buffer_map_range(struct pipe_screen *screen, - struct pipe_buffer *buffer, - unsigned offset, unsigned length, - unsigned usage) +static void *r600_buffer_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) { - struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer; - struct r600_screen *rscreen = r600_screen(buffer->screen); + struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_screen *rscreen = r600_screen(pipe->screen); int write = 0; if (rbuffer->pb) { - return pb_map(rbuffer->pb, usage); + return pb_map(rbuffer->pb, transfer->usage) + transfer->box.x; } - if (usage & PIPE_BUFFER_USAGE_DONTBLOCK) { + if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { /* FIXME */ } - if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) { + if (transfer->usage & PIPE_TRANSFER_WRITE) { write = 1; } if (radeon_bo_map(rscreen->rw, rbuffer->bo)) { return NULL; } - return rbuffer->bo->data; + return rbuffer->bo->data + transfer->box.x; } -static void r600_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *buffer) +static void r600_buffer_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) { - struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer; - struct r600_screen *rscreen = r600_screen(buffer->screen); + struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_screen *rscreen = r600_screen(pipe->screen); if (rbuffer->pb) { pb_unmap(rbuffer->pb); @@ -160,18 +178,55 @@ static void r600_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *b } } -static void r600_buffer_flush_mapped_range(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned offset, unsigned length) +static void r600_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) { } -void r600_screen_init_buffer_functions(struct pipe_screen *screen) +unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, + struct pipe_resource *buf, + unsigned face, unsigned level) { - screen->buffer_create = r600_buffer_create; - screen->user_buffer_create = r600_user_buffer_create; - screen->buffer_map_range = r600_buffer_map_range; - screen->buffer_flush_mapped_range = r600_buffer_flush_mapped_range; - screen->buffer_unmap = r600_buffer_unmap; - screen->buffer_destroy = r600_buffer_destroy; + /* XXX */ + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} + +struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, + struct winsys_handle *whandle) +{ + struct radeon *rw = (struct radeon*)screen->winsys; + struct r600_buffer *rbuffer; + struct radeon_bo *bo = NULL; + + bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); + if (bo == NULL) { + return NULL; + } + + rbuffer = CALLOC_STRUCT(r600_buffer); + if (rbuffer == NULL) { + radeon_bo_decref(rw, bo); + return NULL; + } + + pipe_reference_init(&rbuffer->b.b.reference, 1); + rbuffer->b.b.target = PIPE_BUFFER; + rbuffer->b.b.screen = screen; + rbuffer->b.vtbl = &r600_buffer_vtbl; + rbuffer->bo = bo; + return &rbuffer->b.b; } + +struct u_resource_vtbl r600_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + r600_buffer_destroy, /* resource_destroy */ + r600_buffer_is_referenced_by_cs, /* is_buffer_referenced */ + u_default_get_transfer, /* get_transfer */ + u_default_transfer_destroy, /* transfer_destroy */ + r600_buffer_transfer_map, /* transfer_map */ + r600_buffer_transfer_flush_region, /* transfer_flush_region */ + r600_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c index 745f92272f8..563ca063afe 100644 --- a/src/gallium/drivers/r600/r600_compiler_tgsi.c +++ b/src/gallium/drivers/r600/r600_compiler_tgsi.c @@ -270,8 +270,6 @@ static unsigned tgsi_file_to_c_file(unsigned file) return C_FILE_ADDRESS; case TGSI_FILE_IMMEDIATE: return C_FILE_IMMEDIATE; - case TGSI_FILE_LOOP: - return C_FILE_LOOP; case TGSI_FILE_PREDICATE: return C_FILE_PREDICATE; case TGSI_FILE_SYSTEM_VALUE: @@ -533,24 +531,12 @@ static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode) case TGSI_OPCODE_IF: *copcode = C_OPCODE_IF; return 0; - case TGSI_OPCODE_BGNFOR: - *copcode = C_OPCODE_BGNFOR; - return 0; - case TGSI_OPCODE_REP: - *copcode = C_OPCODE_REP; - return 0; case TGSI_OPCODE_ELSE: *copcode = C_OPCODE_ELSE; return 0; case TGSI_OPCODE_ENDIF: *copcode = C_OPCODE_ENDIF; return 0; - case TGSI_OPCODE_ENDFOR: - *copcode = C_OPCODE_ENDFOR; - return 0; - case TGSI_OPCODE_ENDREP: - *copcode = C_OPCODE_ENDREP; - return 0; case TGSI_OPCODE_PUSHA: *copcode = C_OPCODE_PUSHA; return 0; diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index faefdb4378e..e2760f9ecd1 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -29,6 +29,7 @@ #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_blitter.h> +#include "r600_resource.h" #include "r600_screen.h" #include "r600_texture.h" #include "r600_context.h" @@ -40,21 +41,6 @@ static void r600_destroy_context(struct pipe_context *context) FREE(rctx); } -static unsigned int r600_is_texture_referenced(struct pipe_context *context, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - struct pipe_buffer *buffer = NULL; - - r600_get_texture_buffer(context->screen, texture, &buffer, NULL); - return context->is_buffer_referenced(context, buffer); -} - -static unsigned int r600_is_buffer_referenced(struct pipe_context *context, struct pipe_buffer *buffer) -{ - return 0; -} - static void r600_flush(struct pipe_context *ctx, unsigned flags, struct pipe_fence_handle **fence) { @@ -90,11 +76,10 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) rctx->context.draw_arrays = r600_draw_arrays; rctx->context.draw_elements = r600_draw_elements; rctx->context.draw_range_elements = r600_draw_range_elements; - rctx->context.is_texture_referenced = r600_is_texture_referenced; - rctx->context.is_buffer_referenced = r600_is_buffer_referenced; rctx->context.flush = r600_flush; r600_init_query_functions(rctx); r600_init_state_functions(rctx); + r600_init_context_resource_functions(rctx); #if 0 rctx->blitter = util_blitter_create(&rctx->context); if (rctx->blitter == NULL) { diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 4646df3b56f..afe544819c8 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -76,12 +76,12 @@ void r600_draw_arrays(struct pipe_context *ctx, unsigned mode, unsigned start, unsigned count); void r600_draw_elements(struct pipe_context *ctx, struct pipe_buffer *index_buffer, - unsigned index_size, unsigned mode, + unsigned index_size, unsigned index_bias, unsigned mode, unsigned start, unsigned count); void r600_draw_range_elements(struct pipe_context *ctx, struct pipe_buffer *index_buffer, - unsigned indexSize, unsigned minIndex, - unsigned maxIndex, unsigned mode, + unsigned index_size, unsigned index_bias, unsigned min_index, + unsigned max_index, unsigned mode, unsigned start, unsigned count); void r600_state_destroy_common(struct r600_state *state); diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c index b9037963117..aa254faf159 100644 --- a/src/gallium/drivers/r600/r600_draw.c +++ b/src/gallium/drivers/r600/r600_draw.c @@ -51,7 +51,7 @@ static int r600_draw_common(struct r600_draw *draw) struct r600_context *rctx = (struct r600_context*)draw->ctx; struct r600_screen *rscreen = (struct r600_screen*)draw->ctx->screen; struct radeon_state *vs_resource; - struct r600_pipe_buffer *rbuffer; + struct r600_buffer *rbuffer; unsigned i, j, offset, format, prim; u32 vgt_dma_index_type, vgt_draw_initiator; int r; @@ -101,7 +101,7 @@ static int r600_draw_common(struct r600_draw *draw) for (i = 0 ; i < rctx->nvertex_element; i++) { j = rctx->vertex_element[i].vertex_buffer_index; - rbuffer = (struct r600_pipe_buffer*)rctx->vertex_buffer[j].buffer; + rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer; offset = rctx->vertex_element[i].src_offset + rctx->vertex_buffer[j].buffer_offset; r = r600_conv_pipe_format(rctx->vertex_element[i].src_format, &format); if (r) @@ -132,7 +132,7 @@ static int r600_draw_common(struct r600_draw *draw) draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count; draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator; if (draw->index_buffer) { - rbuffer = (struct r600_pipe_buffer*)draw->index_buffer; + rbuffer = (struct r600_buffer*)draw->index_buffer; draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT; draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT; @@ -168,11 +168,12 @@ static int r600_draw_common(struct r600_draw *draw) void r600_draw_range_elements(struct pipe_context *ctx, struct pipe_buffer *index_buffer, - unsigned index_size, unsigned min_index, + unsigned index_size, unsigned index_bias, unsigned min_index, unsigned max_index, unsigned mode, unsigned start, unsigned count) { struct r600_draw draw; + assert(index_bias == 0); draw.ctx = ctx; draw.mode = mode; @@ -186,10 +187,11 @@ printf("index_size %d min %d max %d start %d count %d\n", index_size, min_inde void r600_draw_elements(struct pipe_context *ctx, struct pipe_buffer *index_buffer, - unsigned index_size, unsigned mode, + unsigned index_size, unsigned index_bias, unsigned mode, unsigned start, unsigned count) { struct r600_draw draw; + assert(index_bias == 0); draw.ctx = ctx; draw.mode = mode; diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c index 7757452104e..c1b69cae305 100644 --- a/src/gallium/drivers/r600/r600_helper.c +++ b/src/gallium/drivers/r600/r600_helper.c @@ -47,34 +47,17 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format) case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8A8_USCALED: - case PIPE_FORMAT_R8G8B8X8_USCALED: case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8X8_SNORM: - case PIPE_FORMAT_A8B8G8R8_SNORM: - case PIPE_FORMAT_X8B8G8R8_SNORM: case PIPE_FORMAT_R8G8B8A8_SSCALED: - case PIPE_FORMAT_R8G8B8X8_SSCALED: *format = V_0280A0_COLOR_8_8_8_8; return 0; - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A2B10G10R10_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_A8L8_UNORM: case PIPE_FORMAT_L16_UNORM: - case PIPE_FORMAT_YCBCR: - case PIPE_FORMAT_YCBCR_REV: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_S8_UNORM: case PIPE_FORMAT_R64_FLOAT: case PIPE_FORMAT_R64G64_FLOAT: case PIPE_FORMAT_R64G64B64_FLOAT: @@ -122,7 +105,6 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format) case PIPE_FORMAT_R8_SNORM: case PIPE_FORMAT_R8G8_SNORM: case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_B6G5R5_SNORM: case PIPE_FORMAT_R8_SSCALED: case PIPE_FORMAT_R8G8_SSCALED: case PIPE_FORMAT_R8G8B8_SSCALED: diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c new file mode 100644 index 00000000000..d9aa1df04f0 --- /dev/null +++ b/src/gallium/drivers/r600/r600_resource.c @@ -0,0 +1,68 @@ +/* + * Copyright 2010 Marek Olšák <[email protected] + * + * 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. + */ + +#include "r600_context.h" +#include "r600_resource.h" +#include "r600_screen.h" +#include "r600_texture.h" + +static struct pipe_resource * +r600_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templ) +{ + if (templ->target == PIPE_BUFFER) + return r600_buffer_create(screen, templ); + else + return r600_texture_create(screen, templ); +} + +static struct pipe_resource * +r600_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *templ, + struct winsys_handle *whandle) +{ + if (templ->target == PIPE_BUFFER) + return NULL; + else + return r600_texture_from_handle(screen, templ, whandle); +} + +void r600_init_context_resource_functions(struct r600_context *r600) +{ + r600->context.get_transfer = u_get_transfer_vtbl; + r600->context.transfer_map = u_transfer_map_vtbl; + r600->context.transfer_flush_region = u_transfer_flush_region_vtbl; + r600->context.transfer_unmap = u_transfer_unmap_vtbl; + r600->context.transfer_destroy = u_transfer_destroy_vtbl; + r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; + r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; +} + +void r600_init_screen_resource_functions(struct r600_screen *r600screen) +{ + r600screen->screen.resource_create = r600_resource_create; + r600screen->screen.resource_from_handle = r600_resource_from_handle; + r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl; + r600screen->screen.resource_destroy = u_resource_destroy_vtbl; + r600screen->screen.user_buffer_create = r600_user_buffer_create; +} diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h new file mode 100644 index 00000000000..95084a371bd --- /dev/null +++ b/src/gallium/drivers/r600/r600_resource.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010 Marek Olšák <[email protected] + * + * 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. + */ + +#ifndef R600_RESOURCE_H +#define R600_RESOURCE_H + +struct r600_context; +struct r600_screen; + +void r600_init_context_resource_functions(struct r600_context *r600); +void r600_init_screen_resource_functions(struct r600_screen *r600screen); + +#endif diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c index db17b88e9ac..9cc45761515 100644 --- a/src/gallium/drivers/r600/r600_screen.c +++ b/src/gallium/drivers/r600/r600_screen.c @@ -27,6 +27,7 @@ #include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_memory.h> +#include "r600_resource.h" #include "r600_screen.h" #include "r600_texture.h" #include "r600_context.h" @@ -130,9 +131,9 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, return FALSE; } switch (format) { - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8R8G8B8_SRGB: @@ -141,21 +142,21 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: - case PIPE_FORMAT_YCBCR: + case PIPE_FORMAT_UYVY: case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_A8L8_SRGB: - case PIPE_FORMAT_A8L8_UNORM: + case PIPE_FORMAT_L8A8_SRGB: + case PIPE_FORMAT_L8A8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24X8_UNORM: return TRUE; default: /* Unknown format... */ @@ -164,13 +165,11 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, return FALSE; } -static struct pipe_transfer* r600_get_tex_transfer(struct pipe_screen *screen, - 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* r600_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct r600_texture *rtex = (struct r600_texture*)texture; struct r600_transfer *trans; @@ -178,31 +177,50 @@ static struct pipe_transfer* r600_get_tex_transfer(struct pipe_screen *screen, trans = CALLOC_STRUCT(r600_transfer); if (trans == NULL) return NULL; - pipe_texture_reference(&trans->transfer.texture, texture); - trans->transfer.x = x; - trans->transfer.y = y; - trans->transfer.width = w; - trans->transfer.height = h; - trans->transfer.stride = rtex->stride[level]; + pipe_resource_reference(&trans->transfer.resource, texture); + trans->transfer.sr = sr; trans->transfer.usage = usage; - trans->transfer.zslice = zslice; - trans->transfer.face = face; - trans->offset = r600_texture_get_offset(rtex, level, zslice, face); + trans->transfer.box = *box; + trans->transfer.stride = rtex->stride[sr.level]; + trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); return &trans->transfer; } -static void r600_tex_transfer_destroy(struct pipe_transfer *trans) +void r600_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans) { + pipe_resource_reference(&trans->resource, NULL); + FREE(trans); } -static void* r600_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer) +void* r600_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer* transfer) { - /* FIXME implement */ - return NULL; + struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; + struct r600_texture *rtex = (struct r600_texture*)transfer->resource; + char *map; + enum pipe_format format = rtex->b.b.format; + + map = pipe_buffer_map(ctx, rtex->buffer, + transfer->usage, + &rtransfer->buffer_transfer); + + if (!map) { + return NULL; + } + + return map + rtransfer->offset + + 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 r600_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer) +void r600_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer* transfer) { + struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; + struct r600_texture *rtex = (struct r600_texture*)transfer->resource; + + pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer); } static void r600_destroy_screen(struct pipe_screen* pscreen) @@ -231,11 +249,7 @@ struct pipe_screen *radeon_create_screen(struct radeon *rw) rscreen->screen.get_paramf = r600_get_paramf; rscreen->screen.is_format_supported = r600_is_format_supported; rscreen->screen.context_create = r600_create_context; - rscreen->screen.get_tex_transfer = r600_get_tex_transfer; - rscreen->screen.tex_transfer_destroy = r600_tex_transfer_destroy; - rscreen->screen.transfer_map = r600_transfer_map; - rscreen->screen.transfer_unmap = r600_transfer_unmap; - r600_screen_init_buffer_functions(&rscreen->screen); r600_init_screen_texture_functions(&rscreen->screen); + r600_init_screen_resource_functions(rscreen); return &rscreen->screen; } diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h index 97d57c027ed..4748021d079 100644 --- a/src/gallium/drivers/r600/r600_screen.h +++ b/src/gallium/drivers/r600/r600_screen.h @@ -29,16 +29,21 @@ #include <xf86drm.h> #include <radeon_drm.h> #include "radeon.h" +#include "util/u_transfer.h" #define r600_screen(s) ((struct r600_screen*)s) +/* Texture transfer. */ struct r600_transfer { + /* Base class. */ struct pipe_transfer transfer; + /* Buffer transfer. */ + struct pipe_transfer *buffer_transfer; unsigned offset; }; -struct r600_pipe_buffer { - struct pipe_buffer base; +struct r600_buffer { + struct u_resource b; struct radeon_bo *bo; u32 domain; u32 flink; @@ -50,7 +55,33 @@ struct r600_screen { struct radeon *rw; }; -void r600_screen_init_buffer_functions(struct pipe_screen *screen); +/* Buffer functions. */ +struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, + const struct pipe_resource *templ); +struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, + void *ptr, unsigned bytes, + unsigned bind); +unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, + struct pipe_resource *buf, + unsigned face, unsigned level); +struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, + struct winsys_handle *whandle); + +/* Texture transfer functions. */ +struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box); +void r600_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans); +void* r600_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer* transfer); +void r600_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer* transfer); + + +/* Blit functions. */ void r600_clear(struct pipe_context *ctx, unsigned buffers, const float *rgba, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 96d45807e09..ac986af9f5d 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -91,7 +91,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, struct r600_screen *rscreen = (struct r600_screen*)ctx->screen; struct r600_context *rctx = (struct r600_context*)ctx; struct r600_texture *rtex; - struct r600_pipe_buffer *rbuffer; + struct r600_buffer *rbuffer; struct radeon_state *rstate; unsigned level = state->cbufs[0]->level; unsigned pitch, slice; @@ -100,7 +100,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, if (rstate == NULL) return; rtex = (struct r600_texture*)state->cbufs[0]->texture; - rbuffer = (struct r600_pipe_buffer*)rtex->buffer; + rbuffer = (struct r600_buffer*)rtex->buffer; rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -217,9 +217,31 @@ static void r600_bind_sampler_states(struct pipe_context *ctx, { } -static void r600_set_sampler_textures(struct pipe_context *ctx, - unsigned count, - struct pipe_texture **texture) +static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *templ) +{ + struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + + *view = *templ; + return view; +} + +static void r600_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *view) +{ + FREE(view); +} + +static void r600_set_fragment_sampler_views(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) +{ +} + +static void r600_set_vertex_sampler_views(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) { } @@ -298,14 +320,37 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx, rctx->nvertex_buffer = count; } -static void r600_set_vertex_elements(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_element *elements) +/* XXX move this to a more appropriate place */ +struct r600_vertex_elements_state +{ + unsigned count; + struct pipe_vertex_element elements[32]; +}; + +static void *r600_create_vertex_elements_state(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *elements) +{ + struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state); + + assert(count < 32); + v->count = count; + memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); + return v; +} + +static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state) { struct r600_context *rctx = (struct r600_context*)ctx; + struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state; - memcpy(rctx->vertex_element, elements, sizeof(struct pipe_vertex_element) * count); - rctx->nvertex_element = count; + memcpy(rctx->vertex_element, v->elements, v->count * sizeof(struct pipe_vertex_element)); + rctx->nvertex_element = v->count; +} + +static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state) +{ + FREE(state); } static void *r600_create_dsa_state(struct pipe_context *ctx, @@ -347,13 +392,14 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state) } static void r600_set_constant_buffer(struct pipe_context *ctx, - uint shader, uint index, - struct pipe_buffer *buffer) + uint shader, uint index, + struct pipe_resource *buffer) { struct r600_screen *rscreen = (struct r600_screen*)ctx->screen; struct r600_context *rctx = (struct r600_context*)ctx; unsigned nconstant = 0, i, type, id; struct radeon_state *rstate; + struct pipe_transfer *transfer; u32 *ptr; switch (shader) { @@ -369,9 +415,9 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader); return; } - if (buffer && buffer->size > 0) { - nconstant = buffer->size / 16; - ptr = pipe_buffer_map(ctx->screen, buffer, PIPE_BUFFER_USAGE_CPU_READ); + if (buffer && buffer->width0 > 0) { + nconstant = buffer->width0 / 16; + ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer); if (ptr == NULL) return; for (i = 0; i < nconstant; i++) { @@ -387,7 +433,7 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, if (radeon_draw_set_new(rctx->draw, rstate)) return; } - pipe_buffer_unmap(ctx->screen, buffer); + pipe_buffer_unmap(ctx, buffer, transfer); } } @@ -421,11 +467,16 @@ void r600_init_state_functions(struct r600_context *rctx) rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states; rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states; rctx->context.delete_sampler_state = r600_delete_state; - rctx->context.set_fragment_sampler_textures = r600_set_sampler_textures; + rctx->context.create_sampler_view = r600_create_sampler_view; + rctx->context.sampler_view_destroy = r600_sampler_view_destroy; + rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views; + rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views; rctx->context.set_scissor_state = r600_set_scissor_state; rctx->context.set_viewport_state = r600_set_viewport_state; rctx->context.set_vertex_buffers = r600_set_vertex_buffers; - rctx->context.set_vertex_elements = r600_set_vertex_elements; + rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state; + rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state; + rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state; rctx->context.create_vs_state = r600_create_vs_state; rctx->context.bind_vs_state = r600_bind_vs_state; rctx->context.delete_vs_state = r600_delete_state; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 708f9effa32..b41d7a3b00b 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -29,14 +29,17 @@ #include <util/u_math.h> #include <util/u_inlines.h> #include <util/u_memory.h> +#include "state_tracker/drm_api.h" #include "r600_screen.h" #include "r600_texture.h" +extern struct u_resource_vtbl r600_texture_vtbl; + unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face) { unsigned long offset = rtex->offset[level]; - switch (rtex->tex.target) { + switch (rtex->b.b.target) { case PIPE_TEXTURE_3D: assert(face == 0); return offset + zslice * rtex->layer_size[level]; @@ -51,7 +54,7 @@ unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex) { - struct pipe_texture *ptex = &rtex->tex; + struct pipe_resource *ptex = &rtex->b.b; unsigned long w, h, stride, size, layer_size, i, offset; for (i = 0, offset = 0; i <= ptex->last_level; i++) { @@ -72,36 +75,50 @@ static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture rtex->size = offset; } -static struct pipe_texture *r600_texture_create(struct pipe_screen *screen, const struct pipe_texture *template) +struct pipe_resource *r600_texture_create(struct pipe_screen *screen, + const struct pipe_resource *templ) { struct r600_texture *rtex = CALLOC_STRUCT(r600_texture); struct r600_screen *rscreen = r600_screen(screen); + struct pipe_resource templ_buf; if (!rtex) { return NULL; } - rtex->tex = *template; - pipe_reference_init(&rtex->tex.reference, 1); - rtex->tex.screen = screen; + rtex->b.b = *templ; + rtex->b.vtbl = &r600_texture_vtbl; + pipe_reference_init(&rtex->b.b.reference, 1); + rtex->b.b.screen = screen; r600_setup_miptree(rscreen, rtex); - rtex->buffer = screen->buffer_create(screen, 4096, PIPE_BUFFER_USAGE_PIXEL, rtex->size); + + memset(&templ_buf, 0, sizeof(struct pipe_resource)); + templ_buf.target = PIPE_BUFFER; + templ_buf.format = PIPE_FORMAT_R8_UNORM; + templ_buf.usage = templ->usage; + templ_buf.bind = templ->bind; + templ_buf.width0 = rtex->size; + templ_buf.height0 = 1; + templ_buf.depth0 = 1; + + rtex->buffer = screen->resource_create(screen, &templ_buf); if (!rtex->buffer) { FREE(rtex); return NULL; } - return (struct pipe_texture*)&rtex->tex; + return &rtex->b.b; } -static void r600_texture_destroy(struct pipe_texture *ptex) +static void r600_texture_destroy(struct pipe_screen *screen, + struct pipe_resource *ptex) { struct r600_texture *rtex = (struct r600_texture*)ptex; - pipe_buffer_reference(&rtex->buffer, NULL); + pipe_resource_reference((struct pipe_resource**)&rtex, NULL); FREE(rtex); } static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *texture, + struct pipe_resource *texture, unsigned face, unsigned level, unsigned zslice, unsigned flags) { @@ -113,7 +130,7 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, return NULL; offset = r600_texture_get_offset(rtex, level, zslice, face); 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); @@ -128,71 +145,88 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, static void r600_tex_surface_destroy(struct pipe_surface *surface) { - pipe_texture_reference(&surface->texture, NULL); + pipe_resource_reference(&surface->texture, NULL); FREE(surface); } -static struct pipe_texture *r600_texture_blanket(struct pipe_screen *screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) +struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *base, + struct winsys_handle *whandle) { + struct pipe_resource *buffer; struct r600_texture *rtex; + buffer = r600_buffer_from_handle(screen, whandle); + if (buffer == NULL) { + return NULL; + } + /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0) return NULL; + rtex = CALLOC_STRUCT(r600_texture); if (rtex == NULL) return NULL; - rtex->tex = *base; - pipe_reference_init(&rtex->tex.reference, 1); - rtex->tex.screen = screen; - rtex->stride_override = *stride; - rtex->pitch[0] = *stride / util_format_get_blocksize(base->format); - rtex->stride[0] = *stride; + + /* one ref already taken */ + rtex->buffer = buffer; + + rtex->b.b = *base; + rtex->b.vtbl = &r600_texture_vtbl; + pipe_reference_init(&rtex->b.b.reference, 1); + rtex->b.b.screen = screen; + rtex->stride_override = whandle->stride; + rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format); + rtex->stride[0] = whandle->stride; rtex->offset[0] = 0; rtex->size = align(rtex->stride[0] * base->height0, 32); - pipe_buffer_reference(&rtex->buffer, buffer); - return &rtex->tex; + + return &rtex->b.b; } -static struct pipe_video_surface *r600_video_surface_create(struct pipe_screen *screen, - enum pipe_video_chroma_format chroma_format, - unsigned width, unsigned height) +static boolean r600_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) { - return NULL; + struct r600_screen *rscreen = r600_screen(screen); + struct r600_texture* rtex = (struct r600_texture*)texture; + + if (!rtex) { + return FALSE; + } + + whandle->stride = rtex->stride[0]; + + r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle); + + return TRUE; } -static void r600_video_surface_destroy(struct pipe_video_surface *vsfc) +static unsigned int r600_texture_is_referenced(struct pipe_context *context, + struct pipe_resource *texture, + unsigned face, unsigned level) { - FREE(vsfc); + struct r600_texture *rtex = (struct r600_texture*)texture; + + return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level); } +struct u_resource_vtbl r600_texture_vtbl = +{ + r600_texture_get_handle, /* get_handle */ + r600_texture_destroy, /* resource_destroy */ + r600_texture_is_referenced, /* is_resource_referenced */ + r600_texture_get_transfer, /* get_transfer */ + r600_texture_transfer_destroy, /* transfer_destroy */ + r600_texture_transfer_map, /* transfer_map */ + u_default_transfer_flush_region,/* transfer_flush_region */ + r600_texture_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + void r600_init_screen_texture_functions(struct pipe_screen *screen) { - screen->texture_create = r600_texture_create; - screen->texture_destroy = r600_texture_destroy; screen->get_tex_surface = r600_get_tex_surface; screen->tex_surface_destroy = r600_tex_surface_destroy; - screen->texture_blanket = r600_texture_blanket; - screen->video_surface_create = r600_video_surface_create; - screen->video_surface_destroy= r600_video_surface_destroy; -} - -boolean r600_get_texture_buffer(struct pipe_screen *screen, - struct pipe_texture *texture, - struct pipe_buffer **buffer, - unsigned *stride) -{ - struct r600_texture *rtex = (struct r600_texture*)texture; - - if (rtex == NULL) { - return FALSE; - } - pipe_buffer_reference(buffer, rtex->buffer); - if (stride) { - *stride = rtex->stride[0]; - } - return TRUE; } diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h index a4424161ebc..9bc08d6b040 100644 --- a/src/gallium/drivers/r600/r600_texture.h +++ b/src/gallium/drivers/r600/r600_texture.h @@ -26,21 +26,28 @@ #include <pipe/p_state.h> struct r600_texture { - struct pipe_texture tex; + struct u_resource b; unsigned long offset[PIPE_MAX_TEXTURE_LEVELS]; unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS]; unsigned long stride_override; unsigned long size; - struct pipe_buffer *buffer; + struct pipe_resource *buffer; }; +struct pipe_resource *r600_texture_create(struct pipe_screen *screen, + const struct pipe_resource *templ); unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face); +struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *base, + struct winsys_handle *whandle); void r600_init_screen_texture_functions(struct pipe_screen *screen); -boolean r600_get_texture_buffer(struct pipe_screen *screen, - struct pipe_texture *texture, - struct pipe_buffer **buffer, - unsigned *stride); + +/* This should be implemented by winsys. */ +boolean r600_buffer_get_handle(struct radeon *rw, + struct pipe_resource *buf, + struct winsys_handle *whandle); + #endif |