This artificially converts a buffer into a 8K x N 2D texture to fetch texels from. As a result we can access up to 8K x 8K texels.
Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> --- src/gallium/drivers/freedreno/a3xx/fd3_texture.c | 19 +++++++++++++------ src/gallium/drivers/freedreno/freedreno_screen.c | 8 ++------ src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 5 ++++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c index 6ed5e0c..c6b1e6b 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c @@ -189,10 +189,10 @@ tex_type(unsigned target) switch (target) { default: assert(0); - case PIPE_BUFFER: case PIPE_TEXTURE_1D: case PIPE_TEXTURE_1D_ARRAY: return A3XX_TEX_1D; + case PIPE_BUFFER: case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_2D: case PIPE_TEXTURE_2D_ARRAY: @@ -235,12 +235,19 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, so->texconst0 |= A3XX_TEX_CONST_0_SRGB; if (prsc->target == PIPE_BUFFER) { + /* NOTE: This can end up allowing the shader to access up to 8k of + * data outside of the texture. This can be avoided by clamping the + * texture buffer address in the shader. + */ + unsigned elements = cso->u.buf.last_element - + cso->u.buf.first_element + 1; 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); + A3XX_TEX_CONST_1_WIDTH(MIN2(elements, 8192)) | + A3XX_TEX_CONST_1_HEIGHT(DIV_ROUND_UP(elements, 8192)); + so->texconst2 = + A3XX_TEX_CONST_2_PITCH(MIN2(elements, 8192) * util_format_get_blocksize(cso->format)); } else { unsigned miplevels; @@ -252,10 +259,10 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, 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)); + so->texconst2 = + A3XX_TEX_CONST_2_PITCH(util_format_get_nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp); } /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */ - so->texconst2 = - A3XX_TEX_CONST_2_PITCH(util_format_get_nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp); switch (prsc->target) { case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D_ARRAY: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index dabdd0a..12586dc 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -180,12 +180,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 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.. - */ - if (is_a3xx(screen)) return 8192; - if (is_a4xx(screen)) return 16383; + if (is_a3xx(screen)) return 8192 * 8192; + if (is_a4xx(screen)) return 8192; /* TODO: Convert to 2D approach */ return 0; case PIPE_CAP_DEPTH_CLIP_DISABLE: diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index 83a1385..f3827bf 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -1657,7 +1657,10 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex) for (i = 0; i < coords; i++) src0[nsrc0++] = coord[i]; - if (coords == 1) { + if (tex->sampler_dim == GLSL_SAMPLER_DIM_BUF) { + src0[0] = ir3_AND_B(b, coord[0], 0, create_immed(b, 0x1fff), 0); + src0[nsrc0++] = ir3_SHR_B(b, coord[0], 0, create_immed(b, 13), 0); + } else if (coords == 1) { /* hw doesn't do 1d, so we treat it as 2d with * height of 1, and patch up the y coord. * TODO: y coord should be (int)0 in some cases.. -- 2.4.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev