freedreno/a3xx: 3d/array textures
authorRob Clark <robclark@freedesktop.org>
Sat, 13 Sep 2014 12:25:51 +0000 (08:25 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 13 Sep 2014 19:31:58 +0000 (15:31 -0400)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_texture.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.c

index b0e5efb..8a5140f 100644 (file)
@@ -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;
 }
index 2c9c3a8..c59390a 100644 (file)
@@ -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
 
index 034e4b4..1b39c33 100644 (file)
@@ -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)
index 33a737b..5d96187 100644 (file)
@@ -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;