freedreno/a4xx: add ARB_texture_buffer_range support

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin
2015-11-21 10:02:05 -05:00
parent d4c40f99ab
commit 99f12a3f1a
3 changed files with 41 additions and 15 deletions
+11 -3
View 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);
@@ -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:
@@ -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