From 3f13b5da1510bff8ceaf6718e4b21936d3180376 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 8 Jul 2012 16:02:41 +0200 Subject: [PATCH] gallium/u_blit: don't do two copies for non-2D textures Because u_blit couldn't sample a 1D, 3D, CUBE and ARRAY texture, we created a 2D texture holding a copy of one slice of the source texture (even for 1D). Let's just do it right. Reviewed-by: Alex Deucher --- src/gallium/auxiliary/util/u_blit.c | 72 ++++++++++++++++------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 9bd2ef52d2b..9a3ff7a24f6 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -66,8 +66,8 @@ struct blit_state enum pipe_texture_target internal_target; void *vs; - void *fs[TGSI_WRITEMASK_XYZW + 1]; - void *fs_depth; + void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1]; + void *fs_depth[PIPE_MAX_TEXTURE_TYPES]; struct pipe_resource *vbuf; /**< quad vertices */ unsigned vbuf_slot; @@ -153,17 +153,23 @@ void util_destroy_blit(struct blit_state *ctx) { struct pipe_context *pipe = ctx->pipe; - unsigned i; + unsigned i, j; if (ctx->vs) pipe->delete_vs_state(pipe, ctx->vs); - for (i = 0; i < Elements(ctx->fs); i++) - if (ctx->fs[i]) - pipe->delete_fs_state(pipe, ctx->fs[i]); + for (i = 0; i < Elements(ctx->fs); i++) { + for (j = 0; j < Elements(ctx->fs[i]); j++) { + if (ctx->fs[i][j]) + pipe->delete_fs_state(pipe, ctx->fs[i][j]); + } + } - if (ctx->fs_depth) - pipe->delete_fs_state(pipe, ctx->fs_depth); + for (i = 0; i < Elements(ctx->fs_depth); i++) { + if (ctx->fs_depth[i]) { + pipe->delete_fs_state(pipe, ctx->fs_depth[i]); + } + } pipe_resource_reference(&ctx->vbuf, NULL); @@ -175,15 +181,19 @@ util_destroy_blit(struct blit_state *ctx) * Helper function to set the fragment shaders. */ static INLINE void -set_fragment_shader(struct blit_state *ctx, uint writemask) +set_fragment_shader(struct blit_state *ctx, uint writemask, + enum pipe_texture_target pipe_tex) { - if (!ctx->fs[writemask]) - ctx->fs[writemask] = - util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D, + if (!ctx->fs[pipe_tex][writemask]) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + + ctx->fs[pipe_tex][writemask] = + util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR, writemask); + } - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]); } @@ -191,14 +201,18 @@ set_fragment_shader(struct blit_state *ctx, uint writemask) * Helper function to set the depthwrite shader. */ static INLINE void -set_depth_fragment_shader(struct blit_state *ctx) +set_depth_fragment_shader(struct blit_state *ctx, + enum pipe_texture_target pipe_tex) { - if (!ctx->fs_depth) - ctx->fs_depth = - util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D, + if (!ctx->fs_depth[pipe_tex]) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + + ctx->fs_depth[pipe_tex] = + util_make_fragment_tex_shader_writedepth(ctx->pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR); + } - cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[pipe_tex]); } @@ -430,20 +444,11 @@ util_blit_pixels_writemask(struct blit_state *ctx, dst_surface = pipe->create_surface(pipe, dst->texture, &templ); } - /* Create a temporary texture when src and dest alias or when src - * is anything other than a 2d texture. - * XXX should just use appropriate shader to access 1d / 3d slice / cube face, - * much like the u_blitter code does (should be pretty trivial). - * - * This can still be improved upon. + /* Create a temporary texture when src and dest alias. */ - if ((src_tex == dst_surface->texture && + if (src_tex == dst_surface->texture && dst_surface->u.tex.level == src_level && - dst_surface->u.tex.first_layer == srcZ0) || - (src_tex->target != PIPE_TEXTURE_2D && - src_tex->target != PIPE_TEXTURE_2D && - src_tex->target != PIPE_TEXTURE_RECT)) - { + dst_surface->u.tex.first_layer == srcZ0) { /* Make a temporary texture which contains a copy of the source pixels. * Then we'll sample from the temporary texture. */ @@ -598,9 +603,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* shaders */ if (dst_is_depth) { - set_depth_fragment_shader(ctx); + set_depth_fragment_shader(ctx, sampler_view->texture->target); } else { - set_fragment_shader(ctx, writemask); + set_fragment_shader(ctx, writemask, sampler_view->texture->target); } set_vertex_shader(ctx); cso_set_geometry_shader_handle(ctx->cso, NULL); @@ -775,7 +780,8 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); /* shaders */ - set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW); + set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW, + src_sampler_view->texture->target); set_vertex_shader(ctx); cso_set_geometry_shader_handle(ctx->cso, NULL); -- 2.30.2