freedreno: multi-slice resources (cubemap, mipmap, etc)
authorRob Clark <robclark@freedesktop.org>
Sat, 31 Aug 2013 13:14:27 +0000 (09:14 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 14 Sep 2013 17:31:58 +0000 (13:31 -0400)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
15 files changed:
src/gallium/drivers/freedreno/a2xx/a2xx.xml.h
src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
src/gallium/drivers/freedreno/a2xx/fd2_texture.c
src/gallium/drivers/freedreno/a3xx/a3xx.xml.h
src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
src/gallium/drivers/freedreno/a3xx/fd3_texture.c
src/gallium/drivers/freedreno/a3xx/fd3_texture.h
src/gallium/drivers/freedreno/adreno_common.xml.h
src/gallium/drivers/freedreno/adreno_pm4.xml.h
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_resource.h
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_util.h

index 35463864b959962e362175e75796582c2fc6d1b3..140d3f4ae5f59f5c0c27a2accdbe4b16e744bad6 100644 (file)
@@ -4,16 +4,16 @@
 /* Autogenerated file, DO NOT EDIT manually!
 
 This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://0x04.net/cgit/index.cgi/rules-ng-ng
-git clone git://0x04.net/rules-ng-ng
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
 - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
 - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9759 bytes, from 2013-09-06 12:50:15)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51536 bytes, from 2013-09-08 13:18:17)
 
 Copyright (C) 2013 by the following authors:
 - Rob Clark <robdclark@gmail.com> (robclark)
index 89f5a4d5259c2c8a4439b431d2c58ec2bbe9e769..2c34b8af28ae5e32ced7c924877415c11814d3b7 100644 (file)
@@ -71,7 +71,7 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base,
        OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
        OUT_RING(ring, 0x00000000);             /* RB_COPY_CONTROL */
        OUT_RELOCW(ring, rsc->bo, 0, 0, 0);     /* RB_COPY_DEST_BASE */
-       OUT_RING(ring, rsc->pitch >> 5);        /* RB_COPY_DEST_PITCH */
+       OUT_RING(ring, rsc->slices[0].pitch >> 5); /* RB_COPY_DEST_PITCH */
        OUT_RING(ring,                          /* RB_COPY_DEST_INFO */
                        A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) |
                        A2XX_RB_COPY_DEST_INFO_LINEAR |
@@ -197,7 +197,7 @@ emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
        OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
                        A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
                        A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
-                       A2XX_SQ_TEX_0_PITCH(rsc->pitch));
+                       A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch));
        OUT_RELOC(ring, rsc->bo, 0,
                        fd2_pipe2surface(psurf->format) | 0x800, 0);
        OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
index c800a869868c27959d9a57288a2f1281037f85c4..870694c2a1579f880bd13b40da51663e93c57dbc 100644 (file)
@@ -120,7 +120,7 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->tex_resource =  rsc;
        so->fmt = fd2_pipe2surface(cso->format);
 
-       so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch);
+       so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch);
        so->tex2 =
                A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
                A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
index d183516067b4a08856c0e8d41b687906e734b364..834361b837dfc06a35426d9d49525271a730d0cb 100644 (file)
@@ -4,16 +4,16 @@
 /* Autogenerated file, DO NOT EDIT manually!
 
 This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://0x04.net/cgit/index.cgi/rules-ng-ng
-git clone git://0x04.net/rules-ng-ng
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
 - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
 - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9759 bytes, from 2013-09-06 12:50:15)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51536 bytes, from 2013-09-08 13:18:17)
 
 Copyright (C) 2013 by the following authors:
 - Rob Clark <robdclark@gmail.com> (robclark)
@@ -2074,6 +2074,7 @@ static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_op
 #define REG_A3XX_TP_PERFCOUNTER5_SELECT                                0x00000f09
 
 #define REG_A3XX_TEX_SAMP_0                                    0x00000000
+#define A3XX_TEX_SAMP_0_MIPFILTER_LINEAR                       0x00000002
 #define A3XX_TEX_SAMP_0_XY_MAG__MASK                           0x0000000c
 #define A3XX_TEX_SAMP_0_XY_MAG__SHIFT                          2
 static inline uint32_t A3XX_TEX_SAMP_0_XY_MAG(enum a3xx_tex_filter val)
@@ -2134,6 +2135,12 @@ static inline uint32_t A3XX_TEX_CONST_0_SWIZ_W(enum a3xx_tex_swiz val)
 {
        return ((val) << A3XX_TEX_CONST_0_SWIZ_W__SHIFT) & A3XX_TEX_CONST_0_SWIZ_W__MASK;
 }
+#define A3XX_TEX_CONST_0_MIPLVLS__MASK                         0x000f0000
+#define A3XX_TEX_CONST_0_MIPLVLS__SHIFT                                16
+static inline uint32_t A3XX_TEX_CONST_0_MIPLVLS(uint32_t val)
+{
+       return ((val) << A3XX_TEX_CONST_0_MIPLVLS__SHIFT) & A3XX_TEX_CONST_0_MIPLVLS__MASK;
+}
 #define A3XX_TEX_CONST_0_FMT__MASK                             0x1fc00000
 #define A3XX_TEX_CONST_0_FMT__SHIFT                            22
 static inline uint32_t A3XX_TEX_CONST_0_FMT(enum a3xx_tex_fmt val)
index 51154113de6de9435cfd67cec4dde1a2104dbe41..994f71c0d2cf1212c0f5995afc8279acc0b9d2ed 100644 (file)
@@ -824,8 +824,10 @@ trans_samp(const struct instr_translater *t,
                break;
        }
 
-       if (tex == TGSI_TEXTURE_3D)
+       if ((tex == TGSI_TEXTURE_3D) || (tex == TGSI_TEXTURE_CUBE)) {
+               ir3_instr_create(ctx->ir, 0, OPC_NOP)->repeat = 2; // XXX ???
                flags |= IR3_INSTR_3D;
+       }
 
        /* The texture sample instructions need to coord in successive
         * registers/components (ie. src.xy but not src.yx).  And TXP
index 5e586185ad9201302165b6b8dc7615650ac19dd3..66dc4a8d0bfd38b70f4a7b234e6f93bf52ff240d 100644 (file)
@@ -146,7 +146,7 @@ emit_constants(struct fd_ringbuffer *ring,
 
 #define VERT_TEX_OFF    0
 #define FRAG_TEX_OFF    16
-#define BASETABLE_SZ    14
+#define BASETABLE_SZ    A3XX_MAX_MIP_LEVELS
 
 static void
 emit_textures(struct fd_ringbuffer *ring,
@@ -212,12 +212,15 @@ emit_textures(struct fd_ringbuffer *ring,
        for (i = 0; i < tex->num_textures; i++) {
                struct fd3_pipe_sampler_view *view =
                                fd3_pipe_sampler_view(tex->textures[i]);
-               OUT_RELOC(ring, view->tex_resource->bo, 0, 0, 0);
-               /* I think each entry is a ptr to mipmap level.. for now, just
-                * pad w/ null's until I get around to actually implementing
-                * mipmap support..
-                */
-               for (j = 1; j < BASETABLE_SZ; j++) {
+               struct fd_resource *rsc = view->tex_resource;
+
+               for (j = 0; j < view->mipaddrs; j++) {
+                       struct fd_resource_slice *slice = fd_resource_slice(rsc, j);
+                       OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
+               }
+
+               /* pad the remaining entries w/ null: */
+               for (; j < BASETABLE_SZ; j++) {
                        OUT_RING(ring, 0x00000000);
                }
        }
@@ -284,7 +287,7 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
        OUT_RING(ring, A3XX_TEX_CONST_1_FETCHSIZE(TFETCH_DISABLE) |
                        A3XX_TEX_CONST_1_WIDTH(psurf->width) |
                        A3XX_TEX_CONST_1_HEIGHT(psurf->height));
-       OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(rsc->pitch * rsc->cpp) |
+       OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp) |
                        A3XX_TEX_CONST_2_INDX(0));
        OUT_RING(ring, 0x00000000);
 
index 8d2df47c72a5c34ef805483fc0dae9dd8b2b061c..cdc880ed562f7b0755be9cee06966bbc0ed0da99 100644 (file)
@@ -59,25 +59,27 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
        for (i = 0; i < 4; i++) {
                enum a3xx_color_fmt format = 0;
                enum a3xx_color_swap swap = WZYX;
-               struct fd_resource *res = NULL;
+               struct fd_resource *rsc = NULL;
+               struct fd_resource_slice *slice = NULL;
                uint32_t stride = 0;
                uint32_t base = 0;
 
                if (i < nr_bufs) {
                        struct pipe_surface *psurf = bufs[i];
 
-                       res = fd_resource(psurf->texture);
+                       rsc = fd_resource(psurf->texture);
+                       slice = &rsc->slices[psurf->u.tex.level];
                        format = fd3_pipe2color(psurf->format);
                        swap = fd3_pipe2swap(psurf->format);
 
                        if (bin_w) {
-                               stride = bin_w * res->cpp;
+                               stride = bin_w * rsc->cpp;
 
                                if (bases) {
-                                       base = bases[i] * res->cpp;
+                                       base = bases[i] * rsc->cpp;
                                }
                        } else {
-                               stride = res->pitch * res->cpp;
+                               stride = slice->pitch * rsc->cpp;
                        }
                }
 
@@ -89,7 +91,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
                if (bin_w || (i >= nr_bufs)) {
                        OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base));
                } else {
-                       OUT_RELOCW(ring, res->bo, 0, 0, -1);
+                       OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1);
                }
 
                OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1);
@@ -111,13 +113,14 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring,
                uint32_t base, struct pipe_surface *psurf)
 {
        struct fd_resource *rsc = fd_resource(psurf->texture);
+       struct fd_resource_slice *slice = &rsc->slices[psurf->u.tex.level];
 
        OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
        OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
                        A3XX_RB_COPY_CONTROL_MODE(mode) |
                        A3XX_RB_COPY_CONTROL_GMEM_BASE(base));
-       OUT_RELOCW(ring, rsc->bo, 0, 0, -1);    /* RB_COPY_DEST_BASE */
-       OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(rsc->pitch * rsc->cpp));
+       OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1);    /* RB_COPY_DEST_BASE */
+       OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(slice->pitch * rsc->cpp));
        OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
                        A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) |
                        A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
@@ -418,7 +421,7 @@ fd3_emit_sysmem_prep(struct fd_context *ctx)
        uint32_t pitch = 0;
 
        if (pfb->cbufs[0])
-               pitch = fd_resource(pfb->cbufs[0]->texture)->pitch;
+               pitch = fd_resource(pfb->cbufs[0]->texture)->slices[0].pitch;
 
        fd3_emit_restore(ctx);
 
index e56325ba1f1b87e576f1a25fbc341dfdd7c87533..a44ac46beb1a3bb4f601fa883c24f77e2024e23a 100644 (file)
@@ -80,20 +80,34 @@ fd3_sampler_state_create(struct pipe_context *pctx,
                const struct pipe_sampler_state *cso)
 {
        struct fd3_sampler_stateobj *so = CALLOC_STRUCT(fd3_sampler_stateobj);
+       bool miplinear = false;
 
        if (!so)
                return NULL;
 
+       if (cso->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST)
+               miplinear = true;
+
        so->base = *cso;
 
        so->texsamp0 =
                        COND(!cso->normalized_coords, A3XX_TEX_SAMP_0_UNNORM_COORDS) |
+                       COND(miplinear, A3XX_TEX_SAMP_0_MIPFILTER_LINEAR) |
                        A3XX_TEX_SAMP_0_XY_MAG(tex_filter(cso->mag_img_filter)) |
                        A3XX_TEX_SAMP_0_XY_MIN(tex_filter(cso->min_img_filter)) |
                        A3XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s)) |
                        A3XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t)) |
                        A3XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r));
-       so->texsamp1 = 0x00000000;  /* ??? */
+
+       /* when mip-map is not disabled, this gets set.. I guess possibly
+        * it is the LOD related params, but I think I need GLES3 blob driver
+        * to be able to tell..
+        */
+       if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
+               so->texsamp1 = 0x003ff000;
+       } else {
+               so->texsamp1 = 0x00000000;
+       }
 
        return so;
 }
@@ -126,6 +140,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd3_pipe_sampler_view *so = CALLOC_STRUCT(fd3_pipe_sampler_view);
        struct fd_resource *rsc = fd_resource(prsc);
+       unsigned miplevels = cso->u.tex.last_level - cso->u.tex.first_level;
 
        if (!so)
                return NULL;
@@ -137,10 +152,12 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->base.context = pctx;
 
        so->tex_resource =  rsc;
+       so->mipaddrs = 1 + miplevels;
 
        so->texconst0 =
                        A3XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
                        A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(cso->format)) |
+                       A3XX_TEX_CONST_0_MIPLVLS(miplevels) |
                        fd3_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
                                                cso->swizzle_b, cso->swizzle_a);
        so->texconst1 =
@@ -149,7 +166,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
                        A3XX_TEX_CONST_1_HEIGHT(prsc->height0);
        /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */
        so->texconst2 =
-                       A3XX_TEX_CONST_2_PITCH(rsc->pitch * rsc->cpp);
+                       A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp);
        so->texconst3 = 0x00000000;  /* ??? */
 
        return &so->base;
index a83f527366b1dca0bfc4b770b47da684d38a3dac..f7e5f0e650fab6bd6041a4d0f5ced9abfe3f9091 100644 (file)
@@ -51,6 +51,7 @@ fd3_sampler_stateobj(struct pipe_sampler_state *samp)
 struct fd3_pipe_sampler_view {
        struct pipe_sampler_view base;
        struct fd_resource *tex_resource;
+       uint32_t mipaddrs;
        uint32_t texconst0, texconst1, texconst2, texconst3;
 };
 
index 61979d458ac0850d4bc54839c0e1d9ee0bfd3c84..b38537be505f6eea8200a8051b68c3cf81afc1b6 100644 (file)
@@ -4,16 +4,16 @@
 /* Autogenerated file, DO NOT EDIT manually!
 
 This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://0x04.net/cgit/index.cgi/rules-ng-ng
-git clone git://0x04.net/rules-ng-ng
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
 - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
 - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9759 bytes, from 2013-09-06 12:50:15)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51536 bytes, from 2013-09-08 13:18:17)
 
 Copyright (C) 2013 by the following authors:
 - Rob Clark <robdclark@gmail.com> (robclark)
index 94c13f418e758de1a58b1e008404e73ab2788942..84339b13723bdd1ebe4fd3960760c51c668ba65b 100644 (file)
@@ -4,16 +4,16 @@
 /* Autogenerated file, DO NOT EDIT manually!
 
 This file was generated by the rules-ng-ng headergen tool in this git repository:
-http://0x04.net/cgit/index.cgi/rules-ng-ng
-git clone git://0x04.net/rules-ng-ng
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
 - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
 - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
 - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
 - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
-- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9759 bytes, from 2013-09-06 12:50:15)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51536 bytes, from 2013-09-08 13:18:17)
 
 Copyright (C) 2013 by the following authors:
 - Rob Clark <robdclark@gmail.com> (robclark)
index 3e051ea9882cfedc5f678ebab2e7b46cbc358cf8..3982ecd0f9002a0bff2305eb193126968ac54105 100644 (file)
@@ -75,11 +75,13 @@ fd_resource_transfer_map(struct pipe_context *pctx,
 {
        struct fd_context *ctx = fd_context(pctx);
        struct fd_resource *rsc = fd_resource(prsc);
-       struct pipe_transfer *ptrans = util_slab_alloc(&ctx->transfer_pool);
+       struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
+       struct pipe_transfer *ptrans;
        enum pipe_format format = prsc->format;
        uint32_t op = 0;
        char *buf;
 
+       ptrans = util_slab_alloc(&ctx->transfer_pool);
        if (!ptrans)
                return NULL;
 
@@ -90,7 +92,7 @@ fd_resource_transfer_map(struct pipe_context *pctx,
        ptrans->level = level;
        ptrans->usage = usage;
        ptrans->box = *box;
-       ptrans->stride = rsc->pitch * rsc->cpp;
+       ptrans->stride = slice->pitch * rsc->cpp;
        ptrans->layer_stride = ptrans->stride;
 
        /* some state trackers (at least XA) don't do this.. */
@@ -114,9 +116,10 @@ fd_resource_transfer_map(struct pipe_context *pctx,
 
        *pptrans = ptrans;
 
-       return buf +
+       return buf + slice->offset +
                box->y / util_format_get_blockheight(format) * ptrans->stride +
-               box->x / util_format_get_blockwidth(format) * rsc->cpp;
+               box->x / util_format_get_blockwidth(format) * rsc->cpp +
+               box->z * slice->size0;
 }
 
 static void
@@ -136,7 +139,7 @@ fd_resource_get_handle(struct pipe_screen *pscreen,
        struct fd_resource *rsc = fd_resource(prsc);
 
        return fd_screen_bo_get_handle(pscreen, rsc->bo,
-                       rsc->pitch * rsc->cpp, handle);
+                       rsc->slices[0].pitch * rsc->cpp, handle);
 }
 
 
@@ -149,6 +152,33 @@ static const struct u_resource_vtbl fd_resource_vtbl = {
                .transfer_inline_write    = u_default_transfer_inline_write,
 };
 
+static uint32_t
+setup_slices(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 = slice->pitch * height * rsc->cpp;
+
+               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.
  */
@@ -161,7 +191,7 @@ fd_resource_create(struct pipe_screen *pscreen,
        struct pipe_resource *prsc = &rsc->base.b;
        uint32_t flags, size;
 
-       DBG("target=%d, format=%s, %ux%u@%u, array_size=%u, last_level=%u, "
+       DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
                        "nr_samples=%u, usage=%u, bind=%x, flags=%x",
                        tmpl->target, util_format_name(tmpl->format),
                        tmpl->width0, tmpl->height0, tmpl->depth0,
@@ -177,12 +207,12 @@ fd_resource_create(struct pipe_screen *pscreen,
        prsc->screen = pscreen;
 
        rsc->base.vtbl = &fd_resource_vtbl;
-       rsc->pitch = align(tmpl->width0, 32);
        rsc->cpp = util_format_get_blocksize(tmpl->format);
 
        assert(rsc->cpp);
 
-       size = rsc->pitch * tmpl->height0 * rsc->cpp;
+       size = setup_slices(rsc);
+
        flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
                        DRM_FREEDRENO_GEM_TYPE_KMEM; /* TODO */
 
@@ -202,9 +232,10 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
                struct winsys_handle *handle)
 {
        struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
+       struct fd_resource_slice *slice = &rsc->slices[0];
        struct pipe_resource *prsc = &rsc->base.b;
 
-       DBG("target=%d, format=%s, %ux%u@%u, array_size=%u, last_level=%u, "
+       DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
                        "nr_samples=%u, usage=%u, bind=%x, flags=%x",
                        tmpl->target, util_format_name(tmpl->format),
                        tmpl->width0, tmpl->height0, tmpl->depth0,
@@ -219,11 +250,11 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
        pipe_reference_init(&prsc->reference, 1);
        prsc->screen = pscreen;
 
-       rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &rsc->pitch);
+       rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch);
 
        rsc->base.vtbl = &fd_resource_vtbl;
        rsc->cpp = util_format_get_blocksize(tmpl->format);
-       rsc->pitch /= rsc->cpp;
+       slice->pitch /= rsc->cpp;
 
        assert(rsc->cpp);
 
index 575a143309f12f924aa18b5fcab007fe8c321451..7e10d7a6416419ffa8f5b0af148a303079db9e98 100644 (file)
 
 #include "util/u_transfer.h"
 
+#include "freedreno_util.h"
+
+/* for mipmap, cubemap, etc, each level is represented by a slice.
+ * Currently all slices are part of same bo (just different offsets),
+ * this is at least how it needs to be for cubemaps, although mipmap
+ * can be different bo's (although, not sure if there is a strong
+ * advantage to doing that)
+ */
+struct fd_resource_slice {
+       uint32_t offset;         /* offset of first layer in slice */
+       uint32_t pitch;
+       uint32_t size0;          /* size of first layer in slice */
+};
+
 struct fd_resource {
        struct u_resource base;
        struct fd_bo *bo;
-       uint32_t pitch, cpp;
+       uint32_t cpp;
+       struct fd_resource_slice slices[MAX_MIP_LEVELS];
        uint32_t timestamp;
        bool dirty;
 };
@@ -45,6 +60,13 @@ fd_resource(struct pipe_resource *ptex)
        return (struct fd_resource *)ptex;
 }
 
+static INLINE struct fd_resource_slice *
+fd_resource_slice(struct fd_resource *rsc, unsigned level)
+{
+       assert(level <= rsc->base.b.last_level);
+       return &rsc->slices[level];
+}
+
 void fd_resource_screen_init(struct pipe_screen *pscreen);
 void fd_resource_context_init(struct pipe_context *pctx);
 
index 36ef8b0bc53155257c14391f59fd221663def2bc..7412e3dca96b41c3e084abcc9aece423773dadf9 100644 (file)
@@ -206,7 +206,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-               return 14;
+               return MAX_MIP_LEVELS;
        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
                return 9192;
        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
index 7bbbe8016b5bce829b6d2a5b470fbcd58a061d86..76f557d4835e1edf21f2d596878c4549d31ab2cc 100644 (file)
@@ -48,6 +48,9 @@ enum adreno_rb_blend_opcode fd_blend_func(unsigned func);
 enum adreno_pa_su_sc_draw fd_polygon_mode(unsigned mode);
 enum adreno_stencil_op fd_stencil_op(unsigned op);
 
+#define A3XX_MAX_MIP_LEVELS 14
+/* TBD if it is same on a2xx, but for now: */
+#define MAX_MIP_LEVELS A3XX_MAX_MIP_LEVELS
 
 #define FD_DBG_MSGS     0x01
 #define FD_DBG_DISASM   0x02