From: Marek Olšák <marek.ol...@amd.com> so that we can use TXF.
The cubemap blit pixel shader code size: 148 -> 92 bytes --- src/gallium/auxiliary/util/u_blitter.c | 52 ++++++++++++++++++++++------------ src/gallium/auxiliary/util/u_blitter.h | 3 +- src/gallium/drivers/r300/r300_blit.c | 2 +- src/gallium/drivers/r600/r600_blit.c | 2 +- src/gallium/drivers/radeonsi/si_blit.c | 2 +- 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index b4f393e..c38534d 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -131,20 +131,21 @@ struct blitter_context_priv unsigned dst_height; boolean has_geometry_shader; boolean has_tessellation; boolean has_layered; boolean has_stream_out; boolean has_stencil_export; boolean has_texture_multisample; boolean has_tex_lz; boolean has_txf; + boolean cube_as_2darray; boolean cached_all_shaders; /* The Draw module overrides these functions. * Always create the blitter before Draw. */ void (*bind_fs_state)(struct pipe_context *, void *); void (*delete_fs_state)(struct pipe_context *, void *); }; static struct pipe_surface * util_blitter_get_next_surface_layer(struct pipe_context *pipe, @@ -200,20 +201,22 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT); ctx->has_texture_multisample = pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE); ctx->has_tex_lz = pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_TEX_TXF_LZ); ctx->has_txf = pipe->screen->get_param(pipe->screen, PIPE_CAP_GLSL_FEATURE_LEVEL) > 130; + ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen, + PIPE_CAP_SAMPLER_VIEW_TARGET); /* blend state objects */ memset(&blend, 0, sizeof(blend)); for (i = 0; i <= PIPE_MASK_RGBA; i++) { for (j = 0; j < 2; j++) { memset(&blend.rt[0], 0, sizeof(blend.rt[0])); blend.rt[0].colormask = i; if (j) { blend.rt[0].blend_enable = 1; @@ -762,25 +765,24 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx, ctx->vertices[i][1][3] = 0; } } } static void get_texcoords(struct pipe_sampler_view *src, unsigned src_width0, unsigned src_height0, int x1, int y1, int x2, int y2, bool uses_txf, float out[4]) { - struct pipe_resource *tex = src->texture; unsigned level = src->u.tex.first_level; boolean normalized = !uses_txf && - tex->target != PIPE_TEXTURE_RECT && - tex->nr_samples <= 1; + src->target != PIPE_TEXTURE_RECT && + src->texture->nr_samples <= 1; if (normalized) { out[0] = x1 / (float)u_minify(src_width0, level); out[1] = y1 / (float)u_minify(src_height0, level); out[2] = x2 / (float)u_minify(src_width0, level); out[3] = y2 / (float)u_minify(src_height0, level); } else { out[0] = (float) x1; out[1] = (float) y1; out[2] = (float) x2; @@ -811,34 +813,34 @@ static void blitter_set_texcoords(struct blitter_context_priv *ctx, int x1, int y1, int x2, int y2, bool uses_txf) { unsigned i; float coord[4]; float face_coord[4][2]; get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, uses_txf, coord); - if (src->texture->target == PIPE_TEXTURE_CUBE || - src->texture->target == PIPE_TEXTURE_CUBE_ARRAY) { + if (src->target == PIPE_TEXTURE_CUBE || + src->target == PIPE_TEXTURE_CUBE_ARRAY) { set_texcoords_in_vertices(coord, &face_coord[0][0], 2); util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, /* pointer, stride in floats */ &face_coord[0][0], 2, &ctx->vertices[0][1][0], 8, FALSE); } else { set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8); } /* Set the layer. */ - switch (src->texture->target) { + switch (src->target) { case PIPE_TEXTURE_3D: { float r = layer; if (!uses_txf) r /= u_minify(src->texture->depth0, src->u.tex.first_level); for (i = 0; i < 4; i++) ctx->vertices[i][1][2] = r; /*r*/ } @@ -1451,26 +1453,36 @@ util_blitter_get_next_surface_layer(struct pipe_context *pipe, memset(&dst_templ, 0, sizeof(dst_templ)); dst_templ.format = surf->format; dst_templ.u.tex.level = surf->u.tex.level; dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1; dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1; return pipe->create_surface(pipe, surf->texture, &dst_templ); } -void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, +void util_blitter_default_src_texture(struct blitter_context *blitter, + struct pipe_sampler_view *src_templ, struct pipe_resource *src, unsigned srclevel) { + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + memset(src_templ, 0, sizeof(*src_templ)); - src_templ->target = src->target; + + if (ctx->cube_as_2darray && + (src->target == PIPE_TEXTURE_CUBE || + src->target == PIPE_TEXTURE_CUBE_ARRAY)) + src_templ->target = PIPE_TEXTURE_2D_ARRAY; + else + src_templ->target = src->target; + src_templ->format = util_format_linear(src->format); src_templ->u.tex.first_level = srclevel; src_templ->u.tex.last_level = srclevel; src_templ->u.tex.first_layer = 0; src_templ->u.tex.last_layer = src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1 : src->array_size - 1; src_templ->swizzle_r = PIPE_SWIZZLE_X; src_templ->swizzle_g = PIPE_SWIZZLE_Y; src_templ->swizzle_b = PIPE_SWIZZLE_Z; @@ -1575,21 +1587,21 @@ void util_blitter_copy_texture(struct blitter_context *blitter, assert(src->target < PIPE_MAX_TEXTURE_TYPES); u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height), abs(srcbox->depth), &dstbox); /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); dst_view = pipe->create_surface(pipe, dst, &dst_templ); /* Initialize the sampler view. */ - util_blitter_default_src_texture(&src_templ, src, src_level); + util_blitter_default_src_texture(blitter, &src_templ, src, src_level); src_view = pipe->create_sampler_view(pipe, src, &src_templ); /* Copy. */ util_blitter_blit_generic(blitter, dst_view, &dstbox, src_view, srcbox, src->width0, src->height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, FALSE); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1601,21 +1613,21 @@ static void do_blits(struct blitter_context_priv *ctx, struct pipe_sampler_view *src, unsigned src_width0, unsigned src_height0, const struct pipe_box *srcbox, bool is_zsbuf, bool uses_txf) { struct pipe_context *pipe = ctx->base.pipe; unsigned src_samples = src->texture->nr_samples; unsigned dst_samples = dst->texture->nr_samples; - enum pipe_texture_target src_target = src->texture->target; + enum pipe_texture_target src_target = src->target; struct pipe_framebuffer_state fb_state = {0}; /* Initialize framebuffer state. */ fb_state.width = dst->width; fb_state.height = dst->height; fb_state.nr_cbufs = is_zsbuf ? 0 : 1; blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height); if ((src_target == PIPE_TEXTURE_1D || @@ -1731,21 +1743,21 @@ void util_blitter_blit_generic(struct blitter_context *blitter, const struct pipe_box *dstbox, struct pipe_sampler_view *src, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask, unsigned filter, const struct pipe_scissor_state *scissor, boolean alpha_blend) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; - enum pipe_texture_target src_target = src->texture->target; + enum pipe_texture_target src_target = src->target; unsigned src_samples = src->texture->nr_samples; unsigned dst_samples = dst->texture->nr_samples; boolean has_depth, has_stencil, has_color; boolean blit_stencil, blit_depth, blit_color; void *sampler_state; const struct util_format_description *src_desc = util_format_description(src->format); const struct util_format_description *dst_desc = util_format_description(dst->format); @@ -1935,21 +1947,21 @@ util_blitter_blit(struct blitter_context *blitter, struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level, info->dst.box.z); dst_templ.format = info->dst.format; dst_view = pipe->create_surface(pipe, dst, &dst_templ); /* Initialize the sampler view. */ - util_blitter_default_src_texture(&src_templ, src, info->src.level); + util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level); src_templ.format = info->src.format; src_view = pipe->create_sampler_view(pipe, src, &src_templ); /* Copy. */ util_blitter_blit_generic(blitter, dst_view, &info->dst.box, src_view, &info->src.box, src->width0, src->height0, info->mask, info->filter, info->scissor_enable ? &info->scissor : NULL, info->alpha_blend); @@ -1965,87 +1977,91 @@ void util_blitter_generate_mipmap(struct blitter_context *blitter, { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; struct pipe_surface dst_templ, *dst_view; struct pipe_sampler_view src_templ, *src_view; boolean is_depth; void *sampler_state; const struct util_format_description *desc = util_format_description(format); unsigned src_level; + unsigned target = tex->target; + + if (ctx->cube_as_2darray && + (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)) + target = PIPE_TEXTURE_2D_ARRAY; assert(tex->nr_samples <= 1); assert(!util_format_has_stencil(desc)); is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS; /* Check whether the states are properly saved. */ util_blitter_set_running_flag(blitter); blitter_check_saved_vertex_states(ctx); blitter_check_saved_fragment_states(ctx); blitter_check_saved_textures(ctx); blitter_check_saved_fb_state(ctx); blitter_disable_render_cond(ctx); /* Set states. */ if (is_depth) { pipe->bind_blend_state(pipe, ctx->blend[0][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_depth(ctx, tex->target, 1, - false)); + blitter_get_fs_texfetch_depth(ctx, target, 1, false)); } else { pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, tex->target, + blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target, 1, 1, PIPE_TEX_FILTER_LINEAR, false)); } - if (tex->target == PIPE_TEXTURE_RECT) { + if (target == PIPE_TEXTURE_RECT) { sampler_state = ctx->sampler_state_rect_linear; } else { sampler_state = ctx->sampler_state_linear; } pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &sampler_state); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); for (src_level = base_level; src_level < last_level; src_level++) { struct pipe_box dstbox = {0}, srcbox = {0}; unsigned dst_level = src_level + 1; dstbox.width = u_minify(tex->width0, dst_level); dstbox.height = u_minify(tex->height0, dst_level); srcbox.width = u_minify(tex->width0, src_level); srcbox.height = u_minify(tex->height0, src_level); - if (tex->target == PIPE_TEXTURE_3D) { + if (target == PIPE_TEXTURE_3D) { dstbox.depth = util_max_layer(tex, dst_level) + 1; srcbox.depth = util_max_layer(tex, src_level) + 1; } else { dstbox.z = srcbox.z = first_layer; dstbox.depth = srcbox.depth = last_layer - first_layer + 1; } /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, tex, dst_level, first_layer); dst_templ.format = format; dst_view = pipe->create_surface(pipe, tex, &dst_templ); /* Initialize the sampler view. */ - util_blitter_default_src_texture(&src_templ, tex, src_level); + util_blitter_default_src_texture(blitter, &src_templ, tex, src_level); src_templ.format = format; src_view = pipe->create_sampler_view(pipe, tex, &src_templ); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src_view); do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0, &srcbox, is_depth, false); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index fd4fe7a..912af83 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -261,21 +261,22 @@ void util_blitter_generate_mipmap(struct blitter_context *blitter, */ void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, struct pipe_resource *dst, unsigned dstlevel, unsigned dstz); /** * Helper function to initialize a view for copy_texture_view. * The parameters must match copy_texture_view. */ -void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, +void util_blitter_default_src_texture(struct blitter_context *blitter, + struct pipe_sampler_view *src_templ, struct pipe_resource *src, unsigned srclevel); /** * Copy data from one buffer to another using the Stream Output functionality. * 4-byte alignment is required, otherwise software fallback is used. */ void util_blitter_copy_buffer(struct blitter_context *blitter, struct pipe_resource *dst, unsigned dstx, diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 434cf38..8fda727 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -560,21 +560,21 @@ static void r300_resource_copy_region(struct pipe_context *pipe, /* Can't read MSAA textures. */ if (src->nr_samples > 1 || dst->nr_samples > 1) { return; } /* The code below changes the texture format so that the copy can be done * on hardware. E.g. depth-stencil surfaces are copied as RGBA * colorbuffers. */ util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); - util_blitter_default_src_texture(&src_templ, src, src_level); + util_blitter_default_src_texture(r300->blitter, &src_templ, src, src_level); layout = util_format_description(dst_templ.format)->layout; /* Handle non-renderable plain formats. */ if (layout == UTIL_FORMAT_LAYOUT_PLAIN && (!screen->is_format_supported(screen, src_templ.format, src->target, src->nr_samples, PIPE_BIND_SAMPLER_VIEW) || !screen->is_format_supported(screen, dst_templ.format, dst->target, dst->nr_samples, diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index c52492e..80aa9c0 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -640,21 +640,21 @@ void r600_resource_copy_region(struct pipe_context *ctx, } dst_width = u_minify(dst->width0, dst_level); dst_height = u_minify(dst->height0, dst_level); src_width0 = src->width0; src_height0 = src->height0; src_widthFL = u_minify(src->width0, src_level); src_heightFL = u_minify(src->height0, src_level); util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); - util_blitter_default_src_texture(&src_templ, src, src_level); + util_blitter_default_src_texture(rctx->blitter, &src_templ, src, src_level); if (util_format_is_compressed(src->format) || util_format_is_compressed(dst->format)) { unsigned blocksize = util_format_get_blocksize(src->format); if (blocksize == 8) src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */ else src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */ dst_templ.format = src_templ.format; diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 998288d..f5d9048 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -868,21 +868,21 @@ void si_resource_copy_region(struct pipe_context *ctx, src_box->z, src_box->z + src_box->depth - 1); dst_width = u_minify(dst->width0, dst_level); dst_height = u_minify(dst->height0, dst_level); dst_width0 = dst->width0; dst_height0 = dst->height0; src_width0 = src->width0; src_height0 = src->height0; util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); - util_blitter_default_src_texture(&src_templ, src, src_level); + util_blitter_default_src_texture(sctx->blitter, &src_templ, src, src_level); if (util_format_is_compressed(src->format) || util_format_is_compressed(dst->format)) { unsigned blocksize = rsrc->surface.bpe; if (blocksize == 8) src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */ else src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */ dst_templ.format = src_templ.format; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev