freedreno/a3xx: fix texture buffers, enable offsets
authorIlia Mirkin <imirkin@alum.mit.edu>
Thu, 17 Sep 2015 05:43:36 +0000 (01:43 -0400)
committerRob Clark <robclark@freedesktop.org>
Wed, 18 Nov 2015 19:31:13 +0000 (14:31 -0500)
The main issue is that the current logic looked into cso->u.tex, which
is the wrong side of the union to look into for texture buffers. While I
was at it, it was easy enough to add the logic to handle offsets
(first_element).

 - reduce texture buffer size limit (determined experimentally)
 - don't look at first/last levels, instead look at first/last element
 - include the first element offset
 - set offset alignment to 16 (determined experimentally)

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_texture.c
src/gallium/drivers/freedreno/freedreno_screen.c

index 25ea3e7a7b72a4ca7bca1bd10952f9f57947c3f9..24afbc9e956b459154ed8d9321f8fbd1ac1b5da2 100644 (file)
@@ -209,13 +209,19 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                        fd3_pipe_sampler_view(tex->textures[i]) :
                                        &dummy_view;
                        struct fd_resource *rsc = fd_resource(view->base.texture);
-                       unsigned start = fd_sampler_first_level(&view->base);
-                       unsigned end   = fd_sampler_last_level(&view->base);;
+                       if (rsc && rsc->base.b.target == PIPE_BUFFER) {
+                               OUT_RELOC(ring, rsc->bo, view->base.u.buf.first_element *
+                                                 util_format_get_blocksize(view->base.format), 0, 0);
+                               j = 1;
+                       } else {
+                               unsigned start = fd_sampler_first_level(&view->base);
+                               unsigned end   = fd_sampler_last_level(&view->base);;
 
-                       for (j = 0; j < (end - start + 1); j++) {
-                               struct fd_resource_slice *slice =
+                               for (j = 0; j < (end - start + 1); j++) {
+                                       struct fd_resource_slice *slice =
                                                fd_resource_slice(rsc, j + start);
-                               OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
+                                       OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
+                               }
                        }
 
                        /* pad the remaining entries w/ null: */
index 15e63e7d4786ae1f8a973a681918694b99f30ade..99ae99ea0c13ba0f8b6c7b81e8250e99c4b3a4a0 100644 (file)
@@ -211,8 +211,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 lvl = fd_sampler_first_level(cso);
-       unsigned miplevels = fd_sampler_last_level(cso) - lvl;
+       unsigned lvl;
        uint32_t sz2 = 0;
 
        if (!so)
@@ -227,17 +226,31 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        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);
 
        if (util_format_is_srgb(cso->format))
                so->texconst0 |= A3XX_TEX_CONST_0_SRGB;
 
-       so->texconst1 =
+       if (prsc->target == PIPE_BUFFER) {
+               lvl = 0;
+               so->texconst1 =
+                       A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
+                       A3XX_TEX_CONST_1_WIDTH(cso->u.buf.last_element -
+                                                                  cso->u.buf.first_element + 1) |
+                       A3XX_TEX_CONST_1_HEIGHT(1);
+       } else {
+               unsigned miplevels;
+
+               lvl = fd_sampler_first_level(cso);
+               miplevels = fd_sampler_last_level(cso) - lvl;
+
+               so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels);
+               so->texconst1 =
                        A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
                        A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
                        A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
+       }
        /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */
        so->texconst2 =
                        A3XX_TEX_CONST_2_PITCH(fd3_pipe2nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
index 1e124592a801930cc2a28ef9667e31e13b24e3f2..8440e594308e08ea201dc52ad78ed202fb8dc716 100644 (file)
@@ -180,16 +180,15 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return is_a3xx(screen) || is_a4xx(screen);
 
        case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
-               /* ignoring first/last_element.. but I guess that should be
-                * easy to add..
-                */
-               return 0;
+               return is_a3xx(screen) ? 16 : 0;
        case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
                /* I think 32k on a4xx.. and we could possibly emulate more
                 * by pretending 2d/rect textures and splitting high bits
                 * of index into 2nd dimension..
                 */
-               return 16383;
+               if (is_a3xx(screen)) return 8192;
+               if (is_a4xx(screen)) return 16383;
+               return 0;
 
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
        case PIPE_CAP_CLIP_HALFZ: