freedreno/a4xx: add ARB_texture_buffer_range support
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 21 Nov 2015 15:02:05 +0000 (10:02 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Mon, 23 Nov 2015 16:17:14 +0000 (11:17 -0500)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.c
src/gallium/drivers/freedreno/freedreno_screen.c

index ec454b2a10fbf79dc3ded5ab40294540e2ad67b6..e488450498e160d581f33fb4e8822ec8f8b3456f 100644 (file)
@@ -181,11 +181,12 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
                                CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
                for (i = 0; i < tex->num_textures; i++) {
-                       static const struct fd4_pipe_sampler_view dummy_view = {};
+                       static const struct fd4_pipe_sampler_view dummy_view = {
+                               .base.target = PIPE_TEXTURE_1D,
+                       };
                        const struct fd4_pipe_sampler_view *view = tex->textures[i] ?
                                        fd4_pipe_sampler_view(tex->textures[i]) :
                                        &dummy_view;
-                       unsigned start = fd_sampler_first_level(&view->base);
 
                        OUT_RING(ring, view->texconst0);
                        OUT_RING(ring, view->texconst1);
@@ -193,7 +194,14 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        OUT_RING(ring, view->texconst3);
                        if (view->base.texture) {
                                struct fd_resource *rsc = fd_resource(view->base.texture);
-                               uint32_t offset = fd_resource_offset(rsc, start, 0);
+                               unsigned start = fd_sampler_first_level(&view->base);
+                               uint32_t offset;
+                               if (rsc->base.b.target == PIPE_BUFFER) {
+                                       offset = view->base.u.buf.first_element *
+                                               util_format_get_blocksize(view->base.format);
+                               } else {
+                                       offset = fd_resource_offset(rsc, start, 0);
+                               }
                                OUT_RELOC(ring, rsc->bo, offset, view->texconst4, 0);
                        } else {
                                OUT_RING(ring, 0x00000000);
index 598f1e19116fe01c0af757cdc015567498e6fa11..a37c64473bdbfa7470b3df7ea5b4b6fc05d75f43 100644 (file)
@@ -212,8 +212,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_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)
@@ -228,21 +227,38 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->texconst0 =
                A4XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
                A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(cso->format)) |
-               A4XX_TEX_CONST_0_MIPLVLS(miplevels) |
                fd4_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 |= A4XX_TEX_CONST_0_SRGB;
 
-       so->texconst1 =
-               A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
-               A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
-       so->texconst2 =
-               A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
-               A4XX_TEX_CONST_2_PITCH(
-                       util_format_get_nblocksx(
-                               cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
+       if (prsc->target == PIPE_BUFFER) {
+               unsigned elements = cso->u.buf.last_element -
+                       cso->u.buf.first_element + 1;
+               lvl = 0;
+               so->texconst1 =
+                       A4XX_TEX_CONST_1_WIDTH(elements) |
+                       A4XX_TEX_CONST_1_HEIGHT(1);
+               so->texconst2 =
+                       A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
+                       A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
+       } else {
+               unsigned miplevels;
+
+               lvl = fd_sampler_first_level(cso);
+               miplevels = fd_sampler_last_level(cso) - lvl;
+
+               so->texconst0 |= A4XX_TEX_CONST_0_MIPLVLS(miplevels);
+               so->texconst1 =
+                       A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
+                       A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
+               so->texconst2 =
+                       A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
+                       A4XX_TEX_CONST_2_PITCH(
+                                       util_format_get_nblocksx(
+                                                       cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
+       }
 
        switch (prsc->target) {
        case PIPE_TEXTURE_1D_ARRAY:
index 7bffc8f68c25ed73168984bedcb0c00edc77db30..0c494d4f4c8d4f406b1ad696055ac5ea030a6605 100644 (file)
@@ -183,7 +183,9 @@ 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:
-               return is_a3xx(screen) ? 16 : 0;
+               if (is_a3xx(screen)) return 16;
+               if (is_a4xx(screen)) return 32;
+               return 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