From 99f12a3f1a825c53d790f12dae114f388bb6244c Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sat, 21 Nov 2015 10:02:05 -0500 Subject: [PATCH] freedreno/a4xx: add ARB_texture_buffer_range support Signed-off-by: Ilia Mirkin --- src/gallium/drivers/freedreno/a4xx/fd4_emit.c | 14 +++++++-- src/gallium/drivers/freedreno/a4xx/fd4_texture.c | 38 +++++++++++++++++------- src/gallium/drivers/freedreno/freedreno_screen.c | 4 ++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index ec454b2..e488450 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -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); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c index 598f1e1..a37c644 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c @@ -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: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 7bffc8f..0c494d4 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -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 -- 2.7.4