From 70e656b4ebdd3cd2962ce66544ae9af349ecd59a Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 29 Jan 2011 13:49:41 +0100 Subject: r600g: fix vertex format fallback This fixes: - piglit/draw-vertices - piglit/draw-vertices-half-float --- src/gallium/drivers/r600/r600_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index b9ec9592e35..b487182e3aa 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -53,7 +53,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op if (rctx->states[R600_PIPE_STATE_CLIP]) { util_blitter_save_clip(rctx->blitter, &rctx->clip); } - util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer, rctx->vertex_buffer); + util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffers, rctx->vertex_buffer); rctx->vertex_elements = NULL; -- cgit v1.2.3 From 71f610e26ea7d71043b1a8ceeb8af7d11d75d6ab Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 30 Jan 2011 18:07:10 +1000 Subject: r600g: fixes a segfault in the piglit fbo-genmipmap-formats test. should be no need to unset this ptr here and if we don't end up using the blitter we've just broken the state. --- src/gallium/drivers/r600/r600_blit.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index b487182e3aa..71a504cb9a2 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -55,8 +55,6 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op } util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffers, rctx->vertex_buffer); - rctx->vertex_elements = NULL; - if (op & (R600_CLEAR_SURFACE | R600_COPY)) util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer); -- cgit v1.2.3 From 38b54158b68479e1f97c8452ba0d67f50dce7582 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sun, 30 Jan 2011 18:57:39 +0100 Subject: r600g: Update the flushed depth texture after drawing to the corresponding texture. I know Jerome will probably rewrite the way depth textures work sometime soon. For the time being this should at least make common depth texture usage for shadowing work properly though. --- src/gallium/drivers/r600/r600_blit.c | 28 ++++++++++++++++++++++++++++ src/gallium/drivers/r600/r600_pipe.h | 2 ++ src/gallium/drivers/r600/r600_resource.h | 1 + src/gallium/drivers/r600/r600_state_common.c | 8 ++++++++ src/gallium/drivers/r600/r600_texture.c | 7 +++---- 5 files changed, 42 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 71a504cb9a2..83c02e55802 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -36,6 +36,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + rctx->blit = true; r600_context_queries_suspend(&rctx->ctx); util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]); @@ -74,6 +75,7 @@ static void r600_blitter_end(struct pipe_context *ctx) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; r600_context_queries_resume(&rctx->ctx); + rctx->blit = false; } void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture) @@ -82,6 +84,9 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t struct pipe_surface *zsurf, *cbsurf, surf_tmpl; int level = 0; float depth = 1.0f; + + if (texture->flushed) return; + surf_tmpl.format = texture->resource.base.b.format; surf_tmpl.u.tex.level = level; surf_tmpl.u.tex.first_layer = 0; @@ -102,11 +107,34 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t r600_blitter_begin(ctx, R600_CLEAR_SURFACE); util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, rctx->custom_dsa_flush, depth); r600_blitter_end(ctx); + texture->flushed = true; pipe_surface_reference(&zsurf, NULL); pipe_surface_reference(&cbsurf, NULL); } +void r600_flush_depth_textures(struct r600_pipe_context *rctx) +{ + unsigned int i; + + if (rctx->blit) return; + + /* FIXME: This handles fragment shader textures only. */ + + for (i = 0; i < rctx->ps_samplers.n_views; ++i) { + struct r600_pipe_sampler_view *view; + struct r600_resource_texture *tex; + + view = rctx->ps_samplers.views[i]; + if (!view) continue; + + tex = (struct r600_resource_texture *)view->base.texture; + if (!tex->depth) continue; + + r600_blit_uncompress_depth(&rctx->context, tex); + } +} + static void r600_clear(struct pipe_context *ctx, unsigned buffers, const float *rgba, double depth, unsigned stencil) { diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index cf4211cb8d3..beb4db12b08 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -171,6 +171,7 @@ struct r600_pipe_context { unsigned vb_max_index; struct r600_translate_context tran; struct u_upload_mgr *upload_const; + bool blit; }; struct r600_drawl { @@ -197,6 +198,7 @@ void evergreen_pipe_add_vertex_attrib(struct r600_pipe_context *rctx, /* r600_blit.c */ void r600_init_blit_functions(struct r600_pipe_context *rctx); void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); +void r600_flush_depth_textures(struct r600_pipe_context *rctx); /* r600_buffer.c */ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 6e302444712..5b5df5a5bac 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -63,6 +63,7 @@ struct r600_resource_texture { unsigned depth; unsigned dirty; struct r600_resource_texture *flushed_depth_texture; + bool flushed; }; #define R600_BUFFER_MAGIC 0xabcd1600 diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 2df8188f0a2..e086e272c8e 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -496,6 +496,8 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) struct r600_drawl draw = {}; unsigned prim; + r600_flush_depth_textures(rctx); + if (rctx->vertex_elements->incompatible_layout) { r600_begin_vertex_translate(rctx, info->min_index, info->max_index); } @@ -597,6 +599,12 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_context_draw(&rctx->ctx, &rdraw); } + if (rctx->framebuffer.zsbuf) + { + struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; + ((struct r600_resource_texture *)tex)->flushed = false; + } + pipe_resource_reference(&draw.index_buffer, NULL); /* delete previous translated vertex elements */ diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 51560bd19e6..91076269ec7 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -302,6 +302,9 @@ r600_texture_create_object(struct pipe_screen *screen, resource->bo = bo; rtex->pitch_override = pitch_in_bytes_override; + if (util_format_is_depth_or_stencil(base->format)) + rtex->depth = 1; + if (array_mode) rtex->tiled = 1; r600_setup_miptree(screen, rtex, array_mode); @@ -632,7 +635,6 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; if (rtransfer->staging_texture) { if (transfer->usage & PIPE_TRANSFER_WRITE) { @@ -640,9 +642,6 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, } pipe_resource_reference(&rtransfer->staging_texture, NULL); } - if (rtex->flushed_depth_texture) { - pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); - } pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } -- cgit v1.2.3 From aee5f1e40ca27149a6226187e855125821d96971 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 Feb 2011 13:00:56 +1000 Subject: r600: only decompress depth when its tile type is wrong. If the tile type for the buffer is 1 then its been bound to the DB at some point, we need to decompress it, otherwise its only been bound as texture/cb so don't do anything. This fixes 5 piglit tests here on r600g. --- src/gallium/drivers/r600/r600_blit.c | 6 +++++- src/gallium/drivers/r600/r600_state.c | 2 +- src/gallium/drivers/r600/r600_texture.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 83c02e55802..a8e85df3c48 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -129,7 +129,11 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) if (!view) continue; tex = (struct r600_resource_texture *)view->base.texture; - if (!tex->depth) continue; + if (!tex->depth) + continue; + + if (tex->tile_type == 0) + continue; r600_blit_uncompress_depth(&rctx->context, tex); } diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index d23f242e567..acaa5c05ae8 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -429,7 +429,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c R600_ERR("unknow format %d\n", state->format); } tmp = (struct r600_resource_texture *)texture; - if (tmp->depth) { + if (tmp->depth && tmp->tile_type == 1) { r600_texture_depth_flush(ctx, texture); tmp = tmp->flushed_depth_texture; } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index e45f4a517e0..dd280491984 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -574,7 +574,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.level = level; trans->transfer.usage = usage; trans->transfer.box = *box; - if (rtex->depth) { + if (rtex->depth && rtex->tile_type == 1) { /* XXX: only readback the rectangle which is being mapped? */ /* XXX: when discard is true, no need to read back from depth texture -- cgit v1.2.3 From b13b7b86b2e1165b24a2df20cb67f9f3baa17b13 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 3 Feb 2011 13:12:35 +1000 Subject: r600g: rework dirty / depth texture tracking. this adds a flag to keep track of whether the depth texture structure is the flushed texture or not, so we can avoid doing flushes when we do a hw rendering from one to the other. it also renames flushed to dirty_db which tracks if the DB copy has been dirtied by being bound to the hw. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 9 ++++----- src/gallium/drivers/r600/r600_resource.h | 4 ++-- src/gallium/drivers/r600/r600_state.c | 4 +--- src/gallium/drivers/r600/r600_state_common.c | 2 +- src/gallium/drivers/r600/r600_texture.c | 3 ++- 5 files changed, 10 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index a8e85df3c48..ca032811048 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -85,7 +85,8 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t int level = 0; float depth = 1.0f; - if (texture->flushed) return; + if (!texture->dirty_db) + return; surf_tmpl.format = texture->resource.base.b.format; surf_tmpl.u.tex.level = level; @@ -107,10 +108,11 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t r600_blitter_begin(ctx, R600_CLEAR_SURFACE); util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, rctx->custom_dsa_flush, depth); r600_blitter_end(ctx); - texture->flushed = true; pipe_surface_reference(&zsurf, NULL); pipe_surface_reference(&cbsurf, NULL); + + texture->dirty_db = FALSE; } void r600_flush_depth_textures(struct r600_pipe_context *rctx) @@ -132,9 +134,6 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) if (!tex->depth) continue; - if (tex->tile_type == 0) - continue; - r600_blit_uncompress_depth(&rctx->context, tex); } } diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 5b5df5a5bac..8d34b864f82 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -61,9 +61,9 @@ struct r600_resource_texture { unsigned tiled; unsigned tile_type; unsigned depth; - unsigned dirty; + unsigned dirty_db; struct r600_resource_texture *flushed_depth_texture; - bool flushed; + boolean is_flushing_texture; }; #define R600_BUFFER_MAGIC 0xabcd1600 diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 6adbbd9eabe..354d38ec234 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -429,7 +429,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c R600_ERR("unknow format %d\n", state->format); } tmp = (struct r600_resource_texture *)texture; - if (tmp->depth && tmp->tile_type == 1) { + if (tmp->depth && !tmp->is_flushing_texture) { r600_texture_depth_flush(ctx, texture); tmp = tmp->flushed_depth_texture; } @@ -760,8 +760,6 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta surf = (struct r600_surface *)state->zsbuf; rtex = (struct r600_resource_texture*)state->zsbuf->texture; - rtex->tile_type = 1; - rbuffer = &rtex->resource; /* XXX quite sure for dx10+ hw don't need any offset hacks */ diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index d82985e1b1f..3b037f8c8c2 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -602,7 +602,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) if (rctx->framebuffer.zsbuf) { struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; - ((struct r600_resource_texture *)tex)->flushed = false; + ((struct r600_resource_texture *)tex)->dirty_db = TRUE; } pipe_resource_reference(&draw.index_buffer, NULL); diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 14422bbfe41..7b38337eda5 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -513,6 +513,7 @@ int r600_texture_depth_flush(struct pipe_context *ctx, return -ENOMEM; } + ((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE; out: /* XXX: only do this if the depth texture has actually changed: */ @@ -574,7 +575,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.level = level; trans->transfer.usage = usage; trans->transfer.box = *box; - if (rtex->depth && rtex->tile_type == 1) { + if (rtex->depth) { /* XXX: only readback the rectangle which is being mapped? */ /* XXX: when discard is true, no need to read back from depth texture -- cgit v1.2.3 From 417cfa60b2fec89423be6ce51ab8b1f3063abb2a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 Feb 2011 17:20:53 +1000 Subject: r600g: fix depth hw resource copies. With the previous fixes we can now enabled hw depth copies Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 11 ++--------- src/gallium/drivers/r600/r600_texture.c | 9 --------- 2 files changed, 2 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index ca032811048..c200dd7305b 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -208,15 +208,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx, unsigned src_level, const struct pipe_box *src_box) { - boolean is_depth; - /* there is something wrong with depth resource copies at the moment so avoid them for now */ - is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; - if (is_depth) - util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); - else - r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); + r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); } void r600_init_blit_functions(struct r600_pipe_context *rctx) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 1d0e482253e..c773c4b84a6 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -291,15 +291,6 @@ static boolean permit_hardware_blit(struct pipe_screen *screen, else bind = PIPE_BIND_RENDER_TARGET; - /* See r600_resource_copy_region: there is something wrong - * with depth resource copies at the moment so avoid them for - * now. - */ - if (util_format_get_component_bits(res->format, - UTIL_FORMAT_COLORSPACE_ZS, - 0) != 0) - return FALSE; - if (!screen->is_format_supported(screen, res->format, res->target, -- cgit v1.2.3 From aa31a5cbc7b52eb1d03c6eab414479249830eabf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 3 Feb 2011 13:43:37 +1000 Subject: r600g: flush differences back to DB copy. --- src/gallium/drivers/r600/r600_blit.c | 20 ++++++++++++++++++++ src/gallium/drivers/r600/r600_pipe.h | 1 + src/gallium/drivers/r600/r600_texture.c | 8 ++++++++ 3 files changed, 29 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index c200dd7305b..bf21ab432ef 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -219,3 +219,23 @@ void r600_init_blit_functions(struct r600_pipe_context *rctx) rctx->context.clear_depth_stencil = r600_clear_depth_stencil; rctx->context.resource_copy_region = r600_resource_copy_region; } + +void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct pipe_surface *zsurf, *cbsurf, surf_tmpl; + int level = 0; + float depth = 1.0f; + struct pipe_box sbox; + + sbox.x = sbox.y = sbox.z = 0; + sbox.width = texture->resource.base.b.width0; + sbox.height = texture->resource.base.b.height0; + /* XXX that might be wrong */ + sbox.depth = 1; + + r600_hw_copy_region(ctx, (struct pipe_resource *)texture, 0, + 0, 0, 0, + (struct pipe_resource *)texture->flushed_depth_texture, 0, + &sbox); +} diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index beb4db12b08..0d31780e47e 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -198,6 +198,7 @@ void evergreen_pipe_add_vertex_attrib(struct r600_pipe_context *rctx, /* r600_blit.c */ void r600_init_blit_functions(struct r600_pipe_context *rctx); void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); +void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); void r600_flush_depth_textures(struct r600_pipe_context *rctx); /* r600_buffer.c */ diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index c773c4b84a6..eac40965243 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -630,6 +630,8 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; + struct pipe_resource *texture = transfer->resource; + struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; if (rtransfer->staging_texture) { if (transfer->usage & PIPE_TRANSFER_WRITE) { @@ -637,6 +639,12 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, } pipe_resource_reference(&rtransfer->staging_texture, NULL); } + + if (rtex->depth && !rtex->is_flushing_texture) { + if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture) + r600_blit_push_depth(ctx, rtex); + } + pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } -- cgit v1.2.3 From 4b49fcbb9a26680e9a4ef441668e0dd817529d47 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 3 Feb 2011 14:45:40 +1000 Subject: r600g: flush depth texture before a blit from it. If we are going to blit from a depth texture we need to flush it before we blit from it. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index bf21ab432ef..c11268ccca3 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -208,8 +208,14 @@ static void r600_resource_copy_region(struct pipe_context *ctx, unsigned src_level, const struct pipe_box *src_box) { + struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; + + if (rsrc->depth && !rsrc->is_flushing_texture) + r600_texture_depth_flush(ctx, src); + r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); + } void r600_init_blit_functions(struct r600_pipe_context *rctx) -- cgit v1.2.3 From 446bc12c1760fe5d402cdd519a7f0e42d89b9696 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Feb 2011 09:06:02 +1000 Subject: r600g: also check CB bindings for textures to depth flush. This checks the color buffer bindings to make sure there is something to flush. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index c11268ccca3..1a1908031f0 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -136,6 +136,17 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) r600_blit_uncompress_depth(&rctx->context, tex); } + + /* also check CB here */ + for (i = 0; i < rctx->framebuffer.nr_cbufs; i++) { + struct r600_resource_texture *tex; + tex = (struct r600_resource_texture *)rctx->framebuffer.cbufs[i]->texture; + + if (!tex->depth) + continue; + + r600_blit_uncompress_depth(&rctx->context, tex); + } } static void r600_clear(struct pipe_context *ctx, unsigned buffers, -- cgit v1.2.3 From 3e9bc43fbafdd497d475eaffe0deec81b446d122 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Feb 2011 09:07:08 +1000 Subject: r600g: add a flag to just create flushed texture without flushing. This just adds a flag to create the texture without doing any flushing to it. Flushing occurs in the draw function. This avoids unnecessary flushes when we end up rebinding a CB/DB/texture due to the blitter just restoring state. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/evergreen_state.c | 2 +- src/gallium/drivers/r600/r600_blit.c | 2 +- src/gallium/drivers/r600/r600_resource.h | 2 +- src/gallium/drivers/r600/r600_state.c | 8 +++++++- src/gallium/drivers/r600/r600_texture.c | 7 +++++-- 5 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index c64b93bd4fc..00d5d007ddf 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -382,7 +382,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte } tmp = (struct r600_resource_texture *)texture; if (tmp->depth && tmp->tile_type == 1) { - r600_texture_depth_flush(ctx, texture); + r600_texture_depth_flush(ctx, texture, TRUE); tmp = tmp->flushed_depth_texture; } rbuffer = &tmp->resource; diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 1a1908031f0..2c6d217abe7 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -222,7 +222,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx, struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; if (rsrc->depth && !rsrc->is_flushing_texture) - r600_texture_depth_flush(ctx, src); + r600_texture_depth_flush(ctx, src, FALSE); r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 8d34b864f82..8afe866c91e 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -103,7 +103,7 @@ static INLINE boolean r600_is_user_buffer(struct pipe_resource *buffer) return r600_buffer(buffer)->user_buffer ? TRUE : FALSE; } -int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture); +int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture, boolean just_create); /* r600_texture.c texture transfer functions. */ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 354d38ec234..19bfa81b99a 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -430,7 +430,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c } tmp = (struct r600_resource_texture *)texture; if (tmp->depth && !tmp->is_flushing_texture) { - r600_texture_depth_flush(ctx, texture); + r600_texture_depth_flush(ctx, texture, TRUE); tmp = tmp->flushed_depth_texture; } rbuffer = &tmp->resource; @@ -692,6 +692,12 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta surf = (struct r600_surface *)state->cbufs[cb]; rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; + + if (rtex->depth && !rtex->is_flushing_texture) { + r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE); + rtex = rtex->flushed_depth_texture; + } + rbuffer = &rtex->resource; bo[0] = rbuffer->bo; bo[1] = rbuffer->bo; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index c32e541eb50..bc18eef6cfe 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -488,7 +488,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, } int r600_texture_depth_flush(struct pipe_context *ctx, - struct pipe_resource *texture) + struct pipe_resource *texture, boolean just_create) { struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; struct pipe_resource resource; @@ -517,6 +517,9 @@ int r600_texture_depth_flush(struct pipe_context *ctx, ((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE; out: + if (just_create) + return 0; + /* XXX: only do this if the depth texture has actually changed: */ r600_blit_uncompress_depth(ctx, rtex); @@ -582,7 +585,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, */ /* XXX: when discard is true, no need to read back from depth texture */ - r = r600_texture_depth_flush(ctx, texture); + r = r600_texture_depth_flush(ctx, texture, FALSE); if (r < 0) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); pipe_resource_reference(&trans->transfer.resource, NULL); -- cgit v1.2.3 From cd6864c07976fad5f9008206d558dc6c8c599c11 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Feb 2011 09:08:18 +1000 Subject: r600g: remove unused variables --- src/gallium/drivers/r600/r600_blit.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 2c6d217abe7..de54da8714f 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -239,10 +239,6 @@ void r600_init_blit_functions(struct r600_pipe_context *rctx) void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture) { - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct pipe_surface *zsurf, *cbsurf, surf_tmpl; - int level = 0; - float depth = 1.0f; struct pipe_box sbox; sbox.x = sbox.y = sbox.z = 0; -- cgit v1.2.3 From 812c314e5161d2b5f91c86ba45b79d4b34046bee Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Feb 2011 09:36:02 +1000 Subject: r600g: avoid trying to flush the flushing texture. Since these textures still have the depth bit set. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index de54da8714f..af471d0d917 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -134,6 +134,9 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) if (!tex->depth) continue; + if (tex->is_flushing_texture) + continue; + r600_blit_uncompress_depth(&rctx->context, tex); } @@ -145,6 +148,9 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) if (!tex->depth) continue; + if (tex->is_flushing_texture) + continue; + r600_blit_uncompress_depth(&rctx->context, tex); } } -- cgit v1.2.3 From aa8a2224a3df111a1613f0baefebc00883e1b70b Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 7 Feb 2011 02:00:56 +0100 Subject: r600g: use the new vertex buffer manager --- src/gallium/drivers/r600/r600_asm.c | 6 +- src/gallium/drivers/r600/r600_blit.c | 12 +- src/gallium/drivers/r600/r600_buffer.c | 115 +++++++----------- src/gallium/drivers/r600/r600_pipe.c | 26 ++--- src/gallium/drivers/r600/r600_pipe.h | 34 +----- src/gallium/drivers/r600/r600_resource.h | 10 +- src/gallium/drivers/r600/r600_state_common.c | 128 ++++---------------- src/gallium/drivers/r600/r600_texture.c | 20 ++-- src/gallium/drivers/r600/r600_translate.c | 169 +-------------------------- 9 files changed, 101 insertions(+), 419 deletions(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 35a7bc79e04..46d7fc391c6 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -2052,10 +2052,10 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru for (i = 0; i < ve->count; i++) { unsigned vbuffer_index; - r600_vertex_data_type(ve->hw_format[i], &format, &num_format, &format_comp); - desc = util_format_description(ve->hw_format[i]); + r600_vertex_data_type(ve->elements[i].src_format, &format, &num_format, &format_comp); + desc = util_format_description(ve->elements[i].src_format); if (desc == NULL) { - R600_ERR("unknown format %d\n", ve->hw_format[i]); + R600_ERR("unknown format %d\n", ve->elements[i].src_format); r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL); return -EINVAL; } diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index af471d0d917..fbade99fc54 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -54,7 +54,9 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op if (rctx->states[R600_PIPE_STATE_CLIP]) { util_blitter_save_clip(rctx->blitter, &rctx->clip); } - util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffers, rctx->vertex_buffer); + util_blitter_save_vertex_buffers(rctx->blitter, + rctx->vbuf_mgr->nr_vertex_buffers, + rctx->vbuf_mgr->vertex_buffer); if (op & (R600_CLEAR_SURFACE | R600_COPY)) util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer); @@ -88,13 +90,13 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t if (!texture->dirty_db) return; - surf_tmpl.format = texture->resource.base.b.format; + surf_tmpl.format = texture->resource.b.b.b.format; surf_tmpl.u.tex.level = level; surf_tmpl.u.tex.first_layer = 0; surf_tmpl.u.tex.last_layer = 0; surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL; - zsurf = ctx->create_surface(ctx, &texture->resource.base.b, &surf_tmpl); + zsurf = ctx->create_surface(ctx, &texture->resource.b.b.b, &surf_tmpl); surf_tmpl.format = ((struct pipe_resource*)texture->flushed_depth_texture)->format; surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; @@ -248,8 +250,8 @@ void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture struct pipe_box sbox; sbox.x = sbox.y = sbox.z = 0; - sbox.width = texture->resource.base.b.width0; - sbox.height = texture->resource.base.b.height0; + sbox.width = texture->resource.b.b.b.width0; + sbox.height = texture->resource.b.b.b.height0; /* XXX that might be wrong */ sbox.depth = 1; diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index c3bc6eadda4..0a0e3db854a 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -66,8 +66,8 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, int write = 0; uint8_t *data; - if (rbuffer->user_buffer) - return (uint8_t*)rbuffer->user_buffer + transfer->box.x; + if (rbuffer->r.b.user_ptr) + return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x; if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { /* FIXME */ @@ -87,7 +87,7 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe, { struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); - if (rbuffer->user_buffer) + if (rbuffer->r.b.user_ptr) return; if (rbuffer->r.bo) @@ -126,20 +126,25 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, return NULL; rbuffer->magic = R600_BUFFER_MAGIC; - rbuffer->user_buffer = NULL; - rbuffer->r.base.b = *templ; - pipe_reference_init(&rbuffer->r.base.b.reference, 1); - rbuffer->r.base.b.screen = screen; - rbuffer->r.base.vtbl = &r600_buffer_vtbl; - rbuffer->r.size = rbuffer->r.base.b.width0; + rbuffer->r.b.b.b = *templ; + pipe_reference_init(&rbuffer->r.b.b.b.reference, 1); + rbuffer->r.b.b.b.screen = screen; + rbuffer->r.b.b.vtbl = &r600_buffer_vtbl; + rbuffer->r.b.user_ptr = NULL; + rbuffer->r.size = rbuffer->r.b.b.b.width0; rbuffer->r.bo_size = rbuffer->r.size; - bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); + + bo = r600_bo((struct radeon*)screen->winsys, + rbuffer->r.b.b.b.width0, + alignment, rbuffer->r.b.b.b.bind, + rbuffer->r.b.b.b.usage); + if (bo == NULL) { FREE(rbuffer); return NULL; } rbuffer->r.bo = bo; - return &rbuffer->r.base.b; + return &rbuffer->r.b.b.b; } struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, @@ -153,22 +158,22 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, return NULL; rbuffer->magic = R600_BUFFER_MAGIC; - pipe_reference_init(&rbuffer->r.base.b.reference, 1); - rbuffer->r.base.vtbl = &r600_buffer_vtbl; - rbuffer->r.base.b.screen = screen; - rbuffer->r.base.b.target = PIPE_BUFFER; - rbuffer->r.base.b.format = PIPE_FORMAT_R8_UNORM; - rbuffer->r.base.b.usage = PIPE_USAGE_IMMUTABLE; - rbuffer->r.base.b.bind = bind; - rbuffer->r.base.b.width0 = bytes; - rbuffer->r.base.b.height0 = 1; - rbuffer->r.base.b.depth0 = 1; - rbuffer->r.base.b.array_size = 1; - rbuffer->r.base.b.flags = 0; + pipe_reference_init(&rbuffer->r.b.b.b.reference, 1); + rbuffer->r.b.b.vtbl = &r600_buffer_vtbl; + rbuffer->r.b.b.b.screen = screen; + rbuffer->r.b.b.b.target = PIPE_BUFFER; + rbuffer->r.b.b.b.format = PIPE_FORMAT_R8_UNORM; + rbuffer->r.b.b.b.usage = PIPE_USAGE_IMMUTABLE; + rbuffer->r.b.b.b.bind = bind; + rbuffer->r.b.b.b.width0 = bytes; + rbuffer->r.b.b.b.height0 = 1; + rbuffer->r.b.b.b.depth0 = 1; + rbuffer->r.b.b.b.array_size = 1; + rbuffer->r.b.b.b.flags = 0; + rbuffer->r.b.user_ptr = ptr; rbuffer->r.bo = NULL; rbuffer->r.bo_size = 0; - rbuffer->user_buffer = ptr; - return &rbuffer->r.base.b; + return &rbuffer->r.b.b.b; } struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, @@ -189,12 +194,12 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, return NULL; } - pipe_reference_init(&rbuffer->base.b.reference, 1); - rbuffer->base.b.target = PIPE_BUFFER; - rbuffer->base.b.screen = screen; - rbuffer->base.vtbl = &r600_buffer_vtbl; + pipe_reference_init(&rbuffer->b.b.b.reference, 1); + rbuffer->b.b.b.target = PIPE_BUFFER; + rbuffer->b.b.b.screen = screen; + rbuffer->b.b.vtbl = &r600_buffer_vtbl; rbuffer->bo = bo; - return &rbuffer->base.b; + return &rbuffer->b.b.b; } void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw) @@ -202,59 +207,19 @@ void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer); boolean flushed; - u_upload_data(rctx->upload_vb, 0, + u_upload_data(rctx->upload_ib, 0, draw->info.count * draw->index_size, - rbuffer->user_buffer, + rbuffer->r.b.user_ptr, &draw->index_buffer_offset, &draw->index_buffer, &flushed); } -void r600_upload_user_buffers(struct r600_pipe_context *rctx, - int min_index, int max_index) -{ - int i, nr = rctx->vertex_elements->count; - unsigned count = max_index + 1 - min_index; - boolean flushed; - boolean uploaded[32] = {0}; - - for (i = 0; i < nr; i++) { - unsigned index = rctx->vertex_elements->elements[i].vertex_buffer_index; - struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[index]; - struct r600_resource_buffer *userbuf = r600_buffer(vb->buffer); - - if (userbuf && userbuf->user_buffer && !uploaded[index]) { - unsigned first, size; - - if (vb->stride) { - first = vb->stride * min_index; - size = vb->stride * count; - } else { - first = 0; - size = rctx->vertex_elements->hw_format_size[i]; - } - - u_upload_data(rctx->upload_vb, first, size, - (uint8_t*)userbuf->user_buffer + first, - &vb->buffer_offset, - &rctx->real_vertex_buffer[index], - &flushed); - - vb->buffer_offset -= first; - - /* vertex_arrays_dirty = TRUE; */ - uploaded[index] = TRUE; - } else { - assert(rctx->real_vertex_buffer[index]); - } - } -} - void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer, uint32_t *const_offset) { - if ((*rbuffer)->user_buffer) { - uint8_t *ptr = (*rbuffer)->user_buffer; - unsigned size = (*rbuffer)->r.base.b.width0; + if ((*rbuffer)->r.b.user_ptr) { + uint8_t *ptr = (*rbuffer)->r.b.user_ptr; + unsigned size = (*rbuffer)->r.b.b.b.width0; boolean flushed; *rbuffer = NULL; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 1c903a0b4e1..85ad0ee968b 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -76,8 +76,6 @@ static void r600_destroy_context(struct pipe_context *context) rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); - r600_end_vertex_translate(rctx); - r600_context_fini(&rctx->ctx); util_blitter_destroy(rctx->blitter); @@ -86,11 +84,9 @@ static void r600_destroy_context(struct pipe_context *context) free(rctx->states[i]); } - u_upload_destroy(rctx->upload_vb); + u_upload_destroy(rctx->upload_ib); u_upload_destroy(rctx->upload_const); - - if (rctx->tran.translate_cache) - translate_cache_destroy(rctx->tran.translate_cache); + u_vbuf_mgr_destroy(rctx->vbuf_mgr); FREE(rctx->ps_resource); FREE(rctx->vs_resource); @@ -164,10 +160,16 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void return NULL; } - rctx->upload_vb = u_upload_create(&rctx->context, 1024 * 1024, 16, - PIPE_BIND_VERTEX_BUFFER | + rctx->vbuf_mgr = u_vbuf_mgr_create(&rctx->context, 1024 * 1024, 16, + U_VERTEX_FETCH_BYTE_ALIGNED); + if (!rctx->vbuf_mgr) { + r600_destroy_context(&rctx->context); + return NULL; + } + + rctx->upload_ib = u_upload_create(&rctx->context, 128 * 1024, 16, PIPE_BIND_INDEX_BUFFER); - if (rctx->upload_vb == NULL) { + if (rctx->upload_ib == NULL) { r600_destroy_context(&rctx->context); return NULL; } @@ -185,12 +187,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void return NULL; } - rctx->tran.translate_cache = translate_cache_create(); - if (rctx->tran.translate_cache == NULL) { - FREE(rctx); - return NULL; - } - rctx->vs_resource = CALLOC(R600_RESOURCE_ARRAY_SIZE, sizeof(struct r600_pipe_state)); if (!rctx->vs_resource) { FREE(rctx); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d376a777852..e9820a23911 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -30,7 +30,7 @@ #include #include #include -#include "translate/translate_cache.h" +#include "util/u_vbuf_mgr.h" #include "r600.h" #include "r600_public.h" #include "r600_shader.h" @@ -86,9 +86,7 @@ struct r600_vertex_element { unsigned count; struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS]; - enum pipe_format hw_format[PIPE_MAX_ATTRIBS]; - unsigned hw_format_size[PIPE_MAX_ATTRIBS]; - boolean incompatible_layout; + struct u_vbuf_mgr_elements *vmgr_elements; struct r600_bo *fetch_shader; unsigned fs_size; struct r600_pipe_state rstate; @@ -117,18 +115,6 @@ struct r600_textures_info { unsigned n_samplers; }; -/* vertex buffer translation context, used to translate vertex input that - * hw doesn't natively support, so far only FLOAT64 is unsupported. - */ -struct r600_translate_context { - /* Translate cache for incompatible vertex offset/stride/format fallback. */ - struct translate_cache *translate_cache; - /* The vertex buffer slot containing the translated buffer. */ - unsigned vb_slot; - void *saved_velems; - void *new_velems; -}; - #define R600_CONSTANT_ARRAY_SIZE 256 #define R600_RESOURCE_ARRAY_SIZE 160 @@ -144,10 +130,6 @@ struct r600_pipe_context { struct r600_vertex_element *vertex_elements; struct pipe_framebuffer_state framebuffer; struct pipe_index_buffer index_buffer; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - struct pipe_resource *real_vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned nvertex_buffers; - unsigned nreal_vertex_buffers; /* with the translated vertex buffer */ unsigned cb_target_mask; /* for saving when using blitter */ struct pipe_stencil_ref stencil_ref; @@ -165,11 +147,10 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; - struct u_upload_mgr *upload_vb; - unsigned any_user_vbs; struct r600_textures_info ps_samplers; - unsigned vb_max_index; - struct r600_translate_context tran; + + struct u_vbuf_mgr *vbuf_mgr; + struct u_upload_mgr *upload_ib; struct u_upload_mgr *upload_const; bool blit; }; @@ -210,8 +191,6 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, struct winsys_handle *whandle); void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw); -void r600_upload_user_buffers(struct r600_pipe_context *rctx, - int min_index, int max_index); /* r600_query.c */ void r600_init_query_functions(struct r600_pipe_context *rctx); @@ -250,9 +229,6 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, unsigned level, unsigned layer); /* r600_translate.c */ -void r600_begin_vertex_translate(struct r600_pipe_context *rctx, - int min_index, int max_index); -void r600_end_vertex_translate(struct r600_pipe_context *rctx); void r600_translate_index_buffer(struct r600_pipe_context *r600, struct pipe_resource **index_buffer, unsigned *index_size, diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 8afe866c91e..2e7a28cc94f 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -24,6 +24,7 @@ #define R600_RESOURCE_H #include "util/u_transfer.h" +#include "util/u_vbuf_mgr.h" /* flag to indicate a resource is to be used as a transfer so should not be tiled */ #define R600_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV @@ -43,7 +44,7 @@ struct r600_transfer { * underlying implementations. */ struct r600_resource { - struct u_resource base; + struct u_vbuf_resource b; struct r600_bo *bo; u32 size; unsigned bo_size; @@ -68,10 +69,10 @@ struct r600_resource_texture { #define R600_BUFFER_MAGIC 0xabcd1600 +/* XXX this could be removed */ struct r600_resource_buffer { struct r600_resource r; uint32_t magic; - void *user_buffer; }; struct r600_surface { @@ -98,11 +99,6 @@ static INLINE struct r600_resource_buffer *r600_buffer(struct pipe_resource *buf return NULL; } -static INLINE boolean r600_is_user_buffer(struct pipe_resource *buffer) -{ - return r600_buffer(buffer)->user_buffer ? TRUE : FALSE; -} - int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture, boolean just_create); /* r600_texture.c texture transfer functions. */ diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 3b037f8c8c2..3a959465715 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -123,6 +123,9 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) rctx->vertex_elements = v; if (v) { + u_vbuf_mgr_bind_vertex_elements(rctx->vbuf_mgr, state, + v->vmgr_elements); + rctx->states[v->rstate.id] = &v->rstate; r600_context_pipe_state_set(&rctx->ctx, &v->rstate); } @@ -140,6 +143,7 @@ void r600_delete_vertex_element(struct pipe_context *ctx, void *state) rctx->vertex_elements = NULL; r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL); + u_vbuf_mgr_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements); FREE(state); } @@ -164,52 +168,19 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_buffer *buffers) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct pipe_vertex_buffer *vbo; - unsigned max_index = ~0; int i; + /* Zero states. */ for (i = 0; i < count; i++) { - vbo = (struct pipe_vertex_buffer*)&buffers[i]; - - pipe_resource_reference(&rctx->vertex_buffer[i].buffer, vbo->buffer); - pipe_resource_reference(&rctx->real_vertex_buffer[i], NULL); - - if (!vbo->buffer) { - /* Zero states. */ + if (!buffers[i].buffer) { if (rctx->family >= CHIP_CEDAR) { evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); } else { r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); } - continue; - } - - if (r600_is_user_buffer(vbo->buffer)) { - rctx->any_user_vbs = TRUE; - continue; - } - - pipe_resource_reference(&rctx->real_vertex_buffer[i], vbo->buffer); - - /* The stride of zero means we will be fetching only the first - * vertex, so don't care about max_index. */ - if (!vbo->stride) { - continue; - } - - /* Update the maximum index. */ - { - unsigned vbo_max_index = - (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; - max_index = MIN2(max_index, vbo_max_index); } } - - for (; i < rctx->nreal_vertex_buffers; i++) { - pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL); - pipe_resource_reference(&rctx->real_vertex_buffer[i], NULL); - - /* Zero states. */ + for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) { if (rctx->family >= CHIP_CEDAR) { evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); } else { @@ -217,72 +188,24 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, } } - memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); - - rctx->nvertex_buffers = count; - rctx->nreal_vertex_buffers = count; - rctx->vb_max_index = max_index; + u_vbuf_mgr_set_vertex_buffers(rctx->vbuf_mgr, count, buffers); } - -#define FORMAT_REPLACE(what, withwhat) \ - case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break - void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_element *elements) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); - enum pipe_format *format; - int i; assert(count < 32); if (!v) return NULL; v->count = count; - memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); - - for (i = 0; i < count; i++) { - v->hw_format[i] = v->elements[i].src_format; - format = &v->hw_format[i]; - - switch (*format) { - FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); - FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); - FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); - FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); - - /* r600 doesn't seem to support 32_*SCALED, these formats - * aren't in D3D10 either. */ - FORMAT_REPLACE(R32_UNORM, R32_FLOAT); - FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); - - FORMAT_REPLACE(R32_USCALED, R32_FLOAT); - FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); - - FORMAT_REPLACE(R32_SNORM, R32_FLOAT); - FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); - - FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); - FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); - default:; - } - v->incompatible_layout = - v->incompatible_layout || - v->elements[i].src_format != v->hw_format[i]; - - v->hw_format_size[i] = align(util_format_get_blocksize(v->hw_format[i]), 4); - } + v->vmgr_elements = + u_vbuf_mgr_create_vertex_elements(rctx->vbuf_mgr, count, + elements, v->elements); if (r600_vertex_elements_build_fetch_shader(rctx, v)) { FREE(v); @@ -433,7 +356,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, return; } - if (buffer != &rbuffer->r.base.b) + if (buffer != &rbuffer->r.b.b.b) pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL); } @@ -449,7 +372,7 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) rctx->nvs_resource = rctx->vertex_elements->count; } else { /* bind vertex buffer once */ - rctx->nvs_resource = rctx->nreal_vertex_buffers; + rctx->nvs_resource = rctx->vbuf_mgr->nr_real_vertex_buffers; } for (i = 0 ; i < rctx->nvs_resource; i++) { @@ -461,13 +384,13 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) /* one resource per vertex elements */ unsigned vbuffer_index; vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index; - vertex_buffer = &rctx->vertex_buffer[vbuffer_index]; - rbuffer = (struct r600_resource*)rctx->real_vertex_buffer[vbuffer_index]; + vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[vbuffer_index]; + rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[vbuffer_index]; offset = rctx->vertex_elements->vbuffer_offset[i]; } else { /* bind vertex buffer once */ - vertex_buffer = &rctx->vertex_buffer[i]; - rbuffer = (struct r600_resource*)rctx->real_vertex_buffer[i]; + vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[i]; + rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[i]; offset = 0; } if (vertex_buffer == NULL || rbuffer == NULL) @@ -497,15 +420,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) unsigned prim; r600_flush_depth_textures(rctx); - - if (rctx->vertex_elements->incompatible_layout) { - r600_begin_vertex_translate(rctx, info->min_index, info->max_index); - } - - if (rctx->any_user_vbs) { - r600_upload_user_buffers(rctx, info->min_index, info->max_index); - } - + u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL); r600_vertex_buffer_update(rctx); draw.info = *info; @@ -523,7 +438,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) draw.index_buffer_offset = draw.info.start * draw.index_size; draw.info.start = 0; - if (r600_is_user_buffer(draw.index_buffer)) { + if (u_vbuf_resource(draw.index_buffer)->user_ptr) { r600_upload_index_buffer(rctx, &draw); } } else { @@ -607,8 +522,5 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) pipe_resource_reference(&draw.index_buffer, NULL); - /* delete previous translated vertex elements */ - if (rctx->tran.new_velems) { - r600_end_vertex_translate(rctx); - } + u_vbuf_mgr_draw_end(rctx->vbuf_mgr); } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 14a289444df..b7bfdd8c166 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -75,7 +75,7 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, { unsigned offset = rtex->offset[level]; - switch (rtex->resource.base.b.target) { + switch (rtex->resource.b.b.b.target) { case PIPE_TEXTURE_3D: case PIPE_TEXTURE_CUBE: return offset + layer * rtex->layer_size[level]; @@ -167,7 +167,7 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned level) { - struct pipe_resource *ptex = &rtex->resource.base.b; + struct pipe_resource *ptex = &rtex->resource.b.b.b; unsigned width, stride, tile_width; if (rtex->pitch_override) @@ -188,7 +188,7 @@ static unsigned r600_texture_get_nblocksy(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned level) { - struct pipe_resource *ptex = &rtex->resource.base.b; + struct pipe_resource *ptex = &rtex->resource.b.b.b; unsigned height, tile_height; height = mip_minify(ptex->height0, level); @@ -211,7 +211,7 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned level, unsigned array_mode) { - struct pipe_resource *ptex = &rtex->resource.base.b; + struct pipe_resource *ptex = &rtex->resource.b.b.b; switch (array_mode) { case V_0280A0_ARRAY_LINEAR_GENERAL: @@ -242,7 +242,7 @@ static void r600_setup_miptree(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned array_mode) { - struct pipe_resource *ptex = &rtex->resource.base.b; + struct pipe_resource *ptex = &rtex->resource.b.b.b; struct radeon *radeon = (struct radeon *)screen->winsys; enum chip_class chipc = r600_get_family_class(radeon); unsigned pitch, size, layer_size, i, offset; @@ -372,10 +372,10 @@ r600_texture_create_object(struct pipe_screen *screen, return NULL; resource = &rtex->resource; - resource->base.b = *base; - resource->base.vtbl = &r600_texture_vtbl; - pipe_reference_init(&resource->base.b.reference, 1); - resource->base.b.screen = screen; + resource->b.b.b = *base; + resource->b.b.vtbl = &r600_texture_vtbl; + pipe_reference_init(&resource->b.b.b.reference, 1); + resource->b.b.b.screen = screen; resource->bo = bo; rtex->pitch_override = pitch_in_bytes_override; /* only mark depth textures the HW can hit as depth textures */ @@ -389,7 +389,7 @@ r600_texture_create_object(struct pipe_screen *screen, resource->size = rtex->size; if (!resource->bo) { - struct pipe_resource *ptex = &rtex->resource.base.b; + struct pipe_resource *ptex = &rtex->resource.b.b.b; int base_align = r600_get_base_alignment(screen, ptex->format, array_mode); resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage); diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c index 68429b99d01..a980eac95e0 100644 --- a/src/gallium/drivers/r600/r600_translate.c +++ b/src/gallium/drivers/r600/r600_translate.c @@ -23,176 +23,11 @@ * Authors: Dave Airlie */ -#include "translate/translate_cache.h" -#include "translate/translate.h" -#include #include +#include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "r600_pipe.h" -void r600_begin_vertex_translate(struct r600_pipe_context *rctx, - int min_index, int max_index) -{ - struct pipe_context *pipe = &rctx->context; - struct translate_key key = {0}; - struct translate_element *te; - unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0}; - struct translate *tr; - struct r600_vertex_element *ve = rctx->vertex_elements; - boolean vb_translated[PIPE_MAX_ATTRIBS] = {0}; - uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map; - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; - struct pipe_resource *out_buffer = NULL; - unsigned i, num_verts, out_offset; - struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS]; - boolean flushed; - - /* Initialize the translate key, i.e. the recipe how vertices should be - * translated. */ - for (i = 0; i < ve->count; i++) { - enum pipe_format output_format = ve->hw_format[i]; - unsigned output_format_size = ve->hw_format_size[i]; - - /* Check for support. */ - if (ve->elements[i].src_format == ve->hw_format[i]) { - continue; - } - - /* Workaround for translate: output floats instead of halfs. */ - switch (output_format) { - case PIPE_FORMAT_R16_FLOAT: - output_format = PIPE_FORMAT_R32_FLOAT; - output_format_size = 4; - break; - case PIPE_FORMAT_R16G16_FLOAT: - output_format = PIPE_FORMAT_R32G32_FLOAT; - output_format_size = 8; - break; - case PIPE_FORMAT_R16G16B16_FLOAT: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - output_format_size = 12; - break; - case PIPE_FORMAT_R16G16B16A16_FLOAT: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - output_format_size = 16; - break; - default:; - } - - /* Add this vertex element. */ - te = &key.element[key.nr_elements]; - /*te->type; - te->instance_divisor;*/ - te->input_buffer = ve->elements[i].vertex_buffer_index; - te->input_format = ve->elements[i].src_format; - te->input_offset = ve->elements[i].src_offset; - te->output_format = output_format; - te->output_offset = key.output_stride; - - key.output_stride += output_format_size; - vb_translated[ve->elements[i].vertex_buffer_index] = TRUE; - tr_elem_index[i] = key.nr_elements; - key.nr_elements++; - } - - /* Get a translate object. */ - tr = translate_cache_find(rctx->tran.translate_cache, &key); - - /* Map buffers we want to translate. */ - for (i = 0; i < rctx->nvertex_buffers; i++) { - if (vb_translated[i]) { - struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i]; - - vb_map[i] = pipe_buffer_map(pipe, vb->buffer, - PIPE_TRANSFER_READ, &vb_transfer[i]); - - tr->set_buffer(tr, i, - vb_map[i] + vb->buffer_offset + vb->stride * min_index, - vb->stride, ~0); - } - } - - /* Create and map the output buffer. */ - num_verts = max_index + 1 - min_index; - - u_upload_alloc(rctx->upload_vb, - key.output_stride * min_index, - key.output_stride * num_verts, - &out_offset, &out_buffer, &flushed, - (void**)&out_map); - - out_offset -= key.output_stride * min_index; - - /* Translate. */ - tr->run(tr, 0, num_verts, 0, out_map); - - /* Unmap all buffers. */ - for (i = 0; i < rctx->nvertex_buffers; i++) { - if (vb_translated[i]) { - pipe_buffer_unmap(pipe, vb_transfer[i]); - } - } - - /* Find the first free slot. */ - rctx->tran.vb_slot = ~0; - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (!rctx->vertex_buffer[i].buffer) { - rctx->tran.vb_slot = i; - - if (i >= rctx->nvertex_buffers) { - rctx->nreal_vertex_buffers = i+1; - } - break; - } - } - - if (rctx->tran.vb_slot != ~0) { - /* Setup the new vertex buffer. */ - pipe_resource_reference(&rctx->real_vertex_buffer[rctx->tran.vb_slot], out_buffer); - rctx->vertex_buffer[rctx->tran.vb_slot].buffer_offset = out_offset; - rctx->vertex_buffer[rctx->tran.vb_slot].stride = key.output_stride; - - /* Setup new vertex elements. */ - for (i = 0; i < ve->count; i++) { - if (vb_translated[ve->elements[i].vertex_buffer_index]) { - te = &key.element[tr_elem_index[i]]; - new_velems[i].instance_divisor = ve->elements[i].instance_divisor; - new_velems[i].src_format = te->output_format; - new_velems[i].src_offset = te->output_offset; - new_velems[i].vertex_buffer_index = rctx->tran.vb_slot; - } else { - memcpy(&new_velems[i], &ve->elements[i], - sizeof(struct pipe_vertex_element)); - } - } - - rctx->tran.saved_velems = rctx->vertex_elements; - rctx->tran.new_velems = - pipe->create_vertex_elements_state(pipe, ve->count, new_velems); - pipe->bind_vertex_elements_state(pipe, rctx->tran.new_velems); - } - - pipe_resource_reference(&out_buffer, NULL); -} - -void r600_end_vertex_translate(struct r600_pipe_context *rctx) -{ - struct pipe_context *pipe = &rctx->context; - - if (rctx->tran.new_velems == NULL) { - return; - } - - /* Restore vertex elements. */ - pipe->bind_vertex_elements_state(pipe, rctx->tran.saved_velems); - rctx->tran.saved_velems = NULL; - pipe->delete_vertex_elements_state(pipe, rctx->tran.new_velems); - rctx->tran.new_velems = NULL; - - /* Delete the now-unused VBO. */ - pipe_resource_reference(&rctx->real_vertex_buffer[rctx->tran.vb_slot], NULL); - rctx->nreal_vertex_buffers = rctx->nvertex_buffers; -} void r600_translate_index_buffer(struct r600_pipe_context *r600, struct pipe_resource **index_buffer, @@ -206,7 +41,7 @@ void r600_translate_index_buffer(struct r600_pipe_context *r600, switch (*index_size) { case 1: - u_upload_alloc(r600->upload_vb, 0, count * 2, + u_upload_alloc(r600->upload_ib, 0, count * 2, &out_offset, &out_buffer, &flushed, &ptr); util_shorten_ubyte_elts_to_userptr( -- cgit v1.2.3 From 8e0437914bb786d0b05be8f95e4ff37bf5a19f44 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 Feb 2011 13:42:52 +1000 Subject: r600g: add support for s3tc formats. On r600, s3tc formats require a 1D tiled texture format, so we have to do uploads using a blit, via the 64-bit and 128-bit formats Based on the r600c code we use a 64 and 128-bit type to do the blits. Still requires R600_ENABLE_S3TC until the kernel fixes are in, this has only been tested on evergreen where the kernel doesn't yet get in the way. --- src/gallium/drivers/r600/r600_blit.c | 60 +++++++++++++++++++++++++++++++++ src/gallium/drivers/r600/r600_pipe.c | 2 ++ src/gallium/drivers/r600/r600_texture.c | 13 +++++++ 3 files changed, 75 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index fbade99fc54..6687d09e0fd 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -219,6 +219,47 @@ static void r600_hw_copy_region(struct pipe_context *ctx, r600_blitter_end(ctx); } +struct texture_orig_info { + unsigned format; + unsigned width0; + unsigned height0; +}; + +static void r600_s3tc_to_blittable(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) +{ + unsigned pixsize = util_format_get_blocksize(tex->format); + int new_format; + int new_height, new_width; + + orig->format = tex->format; + orig->width0 = tex->width0; + orig->height0 = tex->height0; + + if (pixsize == 8) + new_format = PIPE_FORMAT_R16G16B16A16_UNORM; /* 64-bit block */ + else + new_format = PIPE_FORMAT_R32G32B32A32_UNORM; /* 128-bit block */ + + new_width = util_format_get_nblocksx(tex->format, orig->width0); + new_height = util_format_get_nblocksy(tex->format, orig->height0); + + tex->width0 = new_width; + tex->height0 = new_height; + tex->format = new_format; + +} + +static void r600_reset_blittable_to_s3tc(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) +{ + tex->format = orig->format; + tex->width0 = orig->width0; + tex->height0 = orig->height0; +} + static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, @@ -228,13 +269,32 @@ static void r600_resource_copy_region(struct pipe_context *ctx, const struct pipe_box *src_box) { struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; + struct texture_orig_info orig_info[2]; + boolean restore_orig[2]; if (rsrc->depth && !rsrc->is_flushing_texture) r600_texture_depth_flush(ctx, src, FALSE); + restore_orig[0] = restore_orig[1] = FALSE; + + if (util_format_is_s3tc(src->format)) { + r600_s3tc_to_blittable(src, src_level, &orig_info[0]); + restore_orig[0] = TRUE; + } + + if (util_format_is_s3tc(dst->format)) { + r600_s3tc_to_blittable(dst, dst_level, &orig_info[1]); + restore_orig[1] = TRUE; + } + r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); + if (restore_orig[0]) + r600_reset_blittable_to_s3tc(src, src_level, &orig_info[0]); + + if (restore_orig[1]) + r600_reset_blittable_to_s3tc(dst, dst_level, &orig_info[1]); } void r600_init_blit_functions(struct r600_pipe_context *rctx) diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index f9e8e76d241..9d6c9bd5429 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -502,6 +503,7 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon) r600_init_screen_resource_functions(&rscreen->screen); rscreen->tiling_info = r600_get_tiling_info(radeon); + util_format_s3tc_init(); util_slab_create(&rscreen->pool_buffers, sizeof(struct r600_resource_buffer), 64, diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index db39383e306..dd14143c2c1 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -289,6 +290,10 @@ static boolean permit_hardware_blit(struct pipe_screen *screen, else bind = PIPE_BIND_RENDER_TARGET; + /* hackaround for S3TC */ + if (util_format_is_s3tc(res->format)) + return TRUE; + if (!screen->is_format_supported(screen, res->format, res->target, @@ -417,6 +422,10 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, } } + if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && + util_format_is_s3tc(templ->format)) + array_mode = V_038000_ARRAY_1D_TILED_THIN1; + return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, 0, 0, NULL); @@ -869,6 +878,10 @@ uint32_t r600_translate_texformat(enum pipe_format format, if (!r600_enable_s3tc) goto out_unknown; + if (!util_format_s3tc_enabled) { + goto out_unknown; + } + switch (format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: -- cgit v1.2.3 From 0863eaf91cbbfb39f9b91b0d1217090a18e10082 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 16 Feb 2011 15:56:11 +1000 Subject: r600g: fix s3tc-texsubimage we need to translate the destination box as well. fixes piglit's s3tc-texsubimage test. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_blit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 6687d09e0fd..06375f72d19 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -285,6 +285,9 @@ static void r600_resource_copy_region(struct pipe_context *ctx, if (util_format_is_s3tc(dst->format)) { r600_s3tc_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; + /* translate the dst box as well */ + dstx = util_format_get_nblocksx(orig_info[1].format, dstx); + dsty = util_format_get_nblocksx(orig_info[1].format, dsty); } r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, -- cgit v1.2.3 From f53436d821a5173075b2a4a8db8cd23d9669f6e2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 16 Feb 2011 16:51:41 +1000 Subject: r600g: fix typo in previous s3tc commit pointed out by Marek on irc. --- src/gallium/drivers/r600/r600_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 06375f72d19..31d5e3f73b6 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -287,7 +287,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx, restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); - dsty = util_format_get_nblocksx(orig_info[1].format, dsty); + dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, -- cgit v1.2.3 From 231bf886dae9c7df0ae3e16acee904024a08824f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 17 Feb 2011 10:25:57 +1000 Subject: r600g: get s3tc working on cards with crappy 64/128 bit types. Some cards don't appear to work correctly with the UNORM type, so switch to the integer type, however since gallium has no integer types yet from what I can see we need to do a hack to workaround it for the blitter. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/evergreen_state.c | 11 +++++++++++ src/gallium/drivers/r600/r600_blit.c | 5 +++++ src/gallium/drivers/r600/r600_resource.h | 4 ++++ src/gallium/drivers/r600/r600_state.c | 10 ++++++++++ 4 files changed, 30 insertions(+) (limited to 'src/gallium/drivers/r600/r600_blit.c') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 261dd8d6ab8..3efdbaba0c3 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -385,6 +385,12 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte r600_texture_depth_flush(ctx, texture, TRUE); tmp = tmp->flushed_depth_texture; } + + if (tmp->force_int_type) { + word4 &= C_030010_NUM_FORMAT_ALL; + word4 |= S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_INT); + } + rbuffer = &tmp->resource; bo[0] = rbuffer->bo; bo[1] = rbuffer->bo; @@ -673,6 +679,11 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state format = r600_translate_colorformat(surf->base.format); swap = r600_translate_colorswap(surf->base.format); + + /* disable when gallium grows int textures */ + if ((format == FMT_32_32_32_32 || format == FMT_16_16_16_16) && rtex->force_int_type) + ntype = 4; + color_info = S_028C70_FORMAT(format) | S_028C70_COMP_SWAP(swap) | S_028C70_ARRAY_MODE(rtex->array_mode[level]) | diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 31d5e3f73b6..9865ea17ae5 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -229,6 +229,7 @@ static void r600_s3tc_to_blittable(struct pipe_resource *tex, unsigned level, struct texture_orig_info *orig) { + struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; unsigned pixsize = util_format_get_blocksize(tex->format); int new_format; int new_height, new_width; @@ -245,6 +246,7 @@ static void r600_s3tc_to_blittable(struct pipe_resource *tex, new_width = util_format_get_nblocksx(tex->format, orig->width0); new_height = util_format_get_nblocksy(tex->format, orig->height0); + rtex->force_int_type = true; tex->width0 = new_width; tex->height0 = new_height; tex->format = new_format; @@ -255,6 +257,9 @@ static void r600_reset_blittable_to_s3tc(struct pipe_resource *tex, unsigned level, struct texture_orig_info *orig) { + struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; + rtex->force_int_type = false; + tex->format = orig->format; tex->width0 = orig->width0; tex->height0 = orig->height0; diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index fdcfcd50a10..836e7491f1f 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -64,6 +64,10 @@ struct r600_resource_texture { unsigned dirty_db; struct r600_resource_texture *flushed_depth_texture; boolean is_flushing_texture; + + /* on some cards we have to use integer 64/128-bit types + for s3tc blits, do this until gallium grows int formats */ + boolean force_int_type; }; #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_038000_ARRAY_LINEAR_ALIGNED) diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 5e6821004df..a1f83ac4271 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -434,6 +434,11 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c r600_texture_depth_flush(ctx, texture, TRUE); tmp = tmp->flushed_depth_texture; } + + if (tmp->force_int_type) { + word4 &= C_038010_NUM_FORMAT_ALL; + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + } rbuffer = &tmp->resource; bo[0] = rbuffer->bo; bo[1] = rbuffer->bo; @@ -724,6 +729,11 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta format = r600_translate_colorformat(surf->base.format); swap = r600_translate_colorswap(surf->base.format); + + /* disable when gallium grows int textures */ + if ((format == FMT_32_32_32_32 || format == FMT_16_16_16_16) && rtex->force_int_type) + ntype = 4; + color_info = S_0280A0_FORMAT(format) | S_0280A0_COMP_SWAP(swap) | S_0280A0_ARRAY_MODE(rtex->array_mode[level]) | -- cgit v1.2.3