From ca29c4c3b0e779909467c0739fc176c64a829142 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 13 Sep 2014 08:25:51 -0400 Subject: [PATCH] freedreno/a3xx: 3d/array textures Signed-off-by: Rob Clark --- .../drivers/freedreno/a3xx/fd3_texture.c | 19 +++++++- .../drivers/freedreno/freedreno_context.h | 2 +- .../drivers/freedreno/freedreno_resource.c | 41 +++++++++++++++- .../drivers/freedreno/ir3/ir3_compiler.c | 47 +++++++++++++++++-- 4 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c index b0e5efb10a4..8a5140f36f9 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c @@ -175,7 +175,24 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */ so->texconst2 = A3XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp); - so->texconst3 = 0x00000000; /* ??? */ + switch (prsc->target) { + case PIPE_TEXTURE_1D_ARRAY: + case PIPE_TEXTURE_2D_ARRAY: + so->texconst3 = + A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->array_size, lvl)) | + A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) | + A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0); + break; + case PIPE_TEXTURE_3D: + so->texconst3 = + A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) | + A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) | + A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0); + break; + default: + so->texconst3 = 0x00000000; + break; + } return &so->base; } diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 2c9c3a8545c..c59390a2939 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -226,7 +226,7 @@ struct fd_context { * tiling commands, we need to make sure we need to leave enough * room at the end to append the tiling commands when we flush. * 0x7000 dwords should be a couple times more than we ever need - * so should be a nice concervative threshold. + * so should be a nice conservative threshold. */ #define FD_TILING_COMMANDS_DWORDS 0x7000 diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 034e4b4f5ac..1b39c3363e5 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -215,6 +215,36 @@ setup_slices(struct fd_resource *rsc) return size; } +/* 2d array and 3d textures seem to want their layers aligned to + * page boundaries + */ +static uint32_t +setup_slices_array(struct fd_resource *rsc) +{ + struct pipe_resource *prsc = &rsc->base.b; + uint32_t level, size = 0; + uint32_t width = prsc->width0; + uint32_t height = prsc->height0; + uint32_t depth = prsc->depth0; + + for (level = 0; level <= prsc->last_level; level++) { + struct fd_resource_slice *slice = fd_resource_slice(rsc, level); + uint32_t aligned_width = align(width, 32); + + slice->pitch = aligned_width; + slice->offset = size; + slice->size0 = align(slice->pitch * height * rsc->cpp, 4096); + + size += slice->size0 * depth * prsc->array_size; + + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); + } + + return size; +} + /** * Create a new texture object, using the given template info. */ @@ -246,7 +276,16 @@ fd_resource_create(struct pipe_screen *pscreen, assert(rsc->cpp); - size = setup_slices(rsc); + switch (tmpl->target) { + case PIPE_TEXTURE_3D: + case PIPE_TEXTURE_1D_ARRAY: + case PIPE_TEXTURE_2D_ARRAY: + size = setup_slices_array(rsc); + break; + default: + size = setup_slices(rsc); + break; + } realloc_bo(rsc, size); if (!rsc->bo) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c index 33a737b44ce..5d96187b986 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c @@ -1094,6 +1094,11 @@ get_tex_info(struct ir3_compile_context *ctx, .src_wrmask = TGSI_WRITEMASK_XYZ, .flags = IR3_INSTR_S, }; + static const struct tex_info tex1da = { + .order = { 0, -1, 2, -1 }, /* coord.xz */ + .src_wrmask = TGSI_WRITEMASK_XYZ, + .flags = IR3_INSTR_A, + }; static const struct tex_info tex2d = { .order = { 0, 1, -1, -1 }, /* coord.xy */ .src_wrmask = TGSI_WRITEMASK_XY, @@ -1104,6 +1109,11 @@ get_tex_info(struct ir3_compile_context *ctx, .src_wrmask = TGSI_WRITEMASK_XYZ, .flags = IR3_INSTR_S, }; + static const struct tex_info tex2da = { + .order = { 0, 1, 2, -1 }, /* coord.xyz */ + .src_wrmask = TGSI_WRITEMASK_XYZ, + .flags = IR3_INSTR_A, + }; static const struct tex_info tex3d = { .order = { 0, 1, 2, -1 }, /* coord.xyz */ .src_wrmask = TGSI_WRITEMASK_XYZ, @@ -1124,6 +1134,11 @@ get_tex_info(struct ir3_compile_context *ctx, .src_wrmask = TGSI_WRITEMASK_XYZW, .flags = IR3_INSTR_P | IR3_INSTR_S, }; + static const struct tex_info txp1da = { + .order = { 0, -1, 2, 3 }, /* coord.xzw */ + .src_wrmask = TGSI_WRITEMASK_XYZW, + .flags = IR3_INSTR_P | IR3_INSTR_A, + }; static const struct tex_info txp2d = { .order = { 0, 1, 3, -1 }, /* coord.xyw */ .src_wrmask = TGSI_WRITEMASK_XYZ, @@ -1134,6 +1149,11 @@ get_tex_info(struct ir3_compile_context *ctx, .src_wrmask = TGSI_WRITEMASK_XYZW, .flags = IR3_INSTR_P | IR3_INSTR_S, }; + static const struct tex_info txp2da = { + .order = { 0, 1, 2, 3 }, /* coord.xyzw */ + .src_wrmask = TGSI_WRITEMASK_XYZW, + .flags = IR3_INSTR_P | IR3_INSTR_A, + }; static const struct tex_info txp3d = { .order = { 0, 1, 2, 3 }, /* coord.xyzw */ .src_wrmask = TGSI_WRITEMASK_XYZW, @@ -1151,12 +1171,16 @@ get_tex_info(struct ir3_compile_context *ctx, return &tex1d; case TGSI_TEXTURE_SHADOW1D: return &tex1ds; + case TGSI_TEXTURE_1D_ARRAY: + return &tex1da; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: return &tex2d; case TGSI_TEXTURE_SHADOW2D: case TGSI_TEXTURE_SHADOWRECT: return &tex2ds; + case TGSI_TEXTURE_2D_ARRAY: + return &tex2da; case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: return &tex3d; @@ -1174,12 +1198,16 @@ get_tex_info(struct ir3_compile_context *ctx, return &txp1d; case TGSI_TEXTURE_SHADOW1D: return &txp1ds; + case TGSI_TEXTURE_1D_ARRAY: + return &txp1da; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: return &txp2d; case TGSI_TEXTURE_SHADOW2D: case TGSI_TEXTURE_SHADOWRECT: return &txp2ds; + case TGSI_TEXTURE_2D_ARRAY: + return &txp2da; case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: return &txp3d; @@ -1203,6 +1231,18 @@ static bool check_swiz(struct tgsi_src_register *src, const int8_t order[4]) return true; } +static bool is_1d(unsigned tex) +{ + switch (tex) { + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_SHADOW1D: + case TGSI_TEXTURE_1D_ARRAY: + return true; + default: + return false; + } +} + static struct tgsi_src_register * get_tex_coord(struct ir3_compile_context *ctx, struct tgsi_full_instruction *inst, @@ -1217,8 +1257,8 @@ get_tex_coord(struct ir3_compile_context *ctx, if (is_rel_or_const(coord)) needs_mov = true; - /* 1D textures we fix up w/ 0.0 as 2nd coord: */ - if ((tex == TGSI_TEXTURE_1D) || (tex == TGSI_TEXTURE_SHADOW1D)) + /* 1D textures we fix up w/ 0.5 as 2nd coord: */ + if (is_1d(tex)) needs_mov = true; /* The texture sample instructions need to coord in successive @@ -1252,8 +1292,7 @@ get_tex_coord(struct ir3_compile_context *ctx, } /* fix up .y coord: */ - if ((tex == TGSI_TEXTURE_1D) || - (tex == TGSI_TEXTURE_SHADOW1D)) { + if (is_1d(tex)) { instr = instr_create(ctx, 1, 0); /* mov */ instr->cat1.src_type = type_mov; instr->cat1.dst_type = type_mov; -- 2.30.2