freedreno/a4xx: texture fixes
authorRob Clark <robclark@freedesktop.org>
Fri, 5 Dec 2014 16:43:03 +0000 (11:43 -0500)
committerRob Clark <robclark@freedesktop.org>
Tue, 9 Dec 2014 23:01:49 +0000 (18:01 -0500)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_format.c
src/gallium/drivers/freedreno/a4xx/fd4_format.h
src/gallium/drivers/freedreno/a4xx/fd4_texture.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.h
src/gallium/drivers/freedreno/freedreno_resource.c

index c7be161a073f4895ed28315b5f722345576c808f..5b471584ee067ea716fa837accb097bed70768fd 100644 (file)
@@ -162,12 +162,20 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
        unsigned i;
 
        if (tex->num_samplers > 0) {
+               int num_samplers;
+
+               /* not sure if this is an a420.0 workaround, but we seem
+                * to need to emit these in pairs.. emit a final dummy
+                * entry if odd # of samplers:
+                */
+               num_samplers = align(tex->num_samplers, 2);
+
                /* output sampler state: */
-               OUT_PKT3(ring, CP_LOAD_STATE, 2 + 2 + (2 * tex->num_samplers));
+               OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * num_samplers));
                OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) |
                                CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
                                CP_LOAD_STATE_0_STATE_BLOCK(sb) |
-                               CP_LOAD_STATE_0_NUM_UNIT(tex->num_samplers));
+                               CP_LOAD_STATE_0_NUM_UNIT(num_samplers));
                OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) |
                                CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
                for (i = 0; i < tex->num_samplers; i++) {
@@ -178,9 +186,11 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        OUT_RING(ring, sampler->texsamp0);
                        OUT_RING(ring, sampler->texsamp1);
                }
-               /* maybe an a420.0 (or a4xx.0) workaround?? or just driver bug? */
-               OUT_RING(ring, 0x00000000);
-               OUT_RING(ring, 0x00000000);
+
+               for (; i < num_samplers; i++) {
+                       OUT_RING(ring, 0x00000000);
+                       OUT_RING(ring, 0x00000000);
+               }
        }
 
        if (tex->num_textures > 0) {
@@ -203,7 +213,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        OUT_RING(ring, view->texconst1);
                        OUT_RING(ring, view->texconst2);
                        OUT_RING(ring, view->texconst3);
-                       OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
+                       OUT_RELOC(ring, rsc->bo, slice->offset,
+                                       view->textconst4, 0);
                        OUT_RING(ring, 0x00000000);
                        OUT_RING(ring, 0x00000000);
                        OUT_RING(ring, 0x00000000);
index bbece83d109a41b9f9eac60bfd89e93d83606886..9cff1340ee7483f3a33657ce26ffbe3a06facdcc 100644 (file)
@@ -232,6 +232,23 @@ fd4_pipe2swap(enum pipe_format format)
        return formats[format].swap;
 }
 
+enum a4xx_tex_fetchsize
+fd4_pipe2fetchsize(enum pipe_format format)
+{
+       switch (util_format_get_blocksizebits(format)) {
+       case 8:   return TFETCH4_1_BYTE;
+       case 16:  return TFETCH4_2_BYTE;
+       case 32:  return TFETCH4_4_BYTE;
+       case 64:  return TFETCH4_8_BYTE;
+       case 128: return TFETCH4_16_BYTE;
+       default:
+               debug_printf("Unknown block size for format %s: %d\n",
+                               util_format_name(format),
+                               util_format_get_blocksizebits(format));
+               return TFETCH4_1_BYTE;
+       }
+}
+
 /* we need to special case a bit the depth/stencil restore, because we are
  * using the texture sampler to blit into the depth/stencil buffer, *not*
  * into a color buffer.  Otherwise fd4_tex_swiz() will do the wrong thing,
index 5d6d1ae9e85828a3cf519e2e8bcf0eb27037dd7d..04837da650b0f7f6cc625279f0e10337e5d652ac 100644 (file)
@@ -38,6 +38,7 @@ enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format);
 enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format);
 enum pipe_format fd4_gmem_restore_format(enum pipe_format format);
 enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format);
+enum a4xx_tex_fetchsize fd4_pipe2fetchsize(enum pipe_format format);
 enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format);
 
 uint32_t fd4_tex_swiz(enum pipe_format format, unsigned swizzle_r,
index 2b826d6325d84d604745d2908cd4ccab7c63b22e..849113d80cc2417aba8e8f528661f33927f81621 100644 (file)
@@ -165,13 +165,25 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
                A4XX_TEX_CONST_1_WIDTH(prsc->width0) |
                A4XX_TEX_CONST_1_HEIGHT(prsc->height0);
        so->texconst2 =
+               A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
                A4XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp);
 
        switch (prsc->target) {
        case PIPE_TEXTURE_1D_ARRAY:
        case PIPE_TEXTURE_2D_ARRAY:
+               so->texconst3 =
+                       A4XX_TEX_CONST_3_DEPTH(prsc->array_size) |
+                       A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
+               break;
+       case PIPE_TEXTURE_CUBE:
+       case PIPE_TEXTURE_CUBE_ARRAY:  /* ?? not sure about _CUBE_ARRAY */
+               so->texconst3 =
+                       A4XX_TEX_CONST_3_DEPTH(1) |
+                       A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
+               break;
        case PIPE_TEXTURE_3D:
                so->texconst3 =
+                       A4XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) |
                        A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
                break;
        default:
index 07eb961eb8fb67c38a65d7cd8349734b4b7fa0f4..975dfe5157d473cdbd716c4af566679ddaa01c2c 100644 (file)
@@ -51,7 +51,7 @@ fd4_sampler_stateobj(struct pipe_sampler_state *samp)
 struct fd4_pipe_sampler_view {
        struct pipe_sampler_view base;
        struct fd_resource *tex_resource;
-       uint32_t texconst0, texconst1, texconst2, texconst3;
+       uint32_t texconst0, texconst1, texconst2, texconst3, textconst4;
 };
 
 static INLINE struct fd4_pipe_sampler_view *
index 461e378c89e4b16077321ad42b38a4d8b26d9bdd..d604aa3f1f8f6a2b9f61c747f6efa79a4b4c6089 100644 (file)
@@ -216,6 +216,12 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment)
 static uint32_t
 slice_alignment(struct pipe_screen *pscreen, const struct pipe_resource *tmpl)
 {
+       struct fd_screen *screen = fd_screen(pscreen);
+
+       /* on a4xx, seems like everything is aligned to page: */
+       if ((screen->gpu_id >= 400) && (screen->gpu_id < 500))
+               return 4096;
+
        /* on a3xx, 2d array and 3d textures seem to want their
         * layers aligned to page boundaries:
         */