summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2014-09-13 08:25:51 -0400
committerRob Clark <robclark@freedesktop.org>2014-09-13 15:31:58 -0400
commitca29c4c3b0e779909467c0739fc176c64a829142 (patch)
treee55cd3fe0ec2e91081b288f528fd250e2f5cf1fc
parenteea1cdf687d7089b2dc24e1dd7da59b3acf3dd3b (diff)
freedreno/a3xx: 3d/array textures
Signed-off-by: Rob Clark <robclark@freedesktop.org>
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_texture.c19
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c41
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler.c47
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;