diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_texture.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_resource.c | 16 |
2 files changed, 16 insertions, 7 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c index 05d826e40ec..69e2d587c93 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c @@ -212,6 +212,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, struct fd_resource *rsc = fd_resource(prsc); unsigned lvl = cso->u.tex.first_level; unsigned miplevels = cso->u.tex.last_level - lvl; + uint32_t sz2 = 0; if (!so) return NULL; @@ -251,8 +252,10 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, case PIPE_TEXTURE_3D: so->texconst3 = A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) | - A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) | - A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0); + A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[lvl].size0); + while (lvl < cso->u.tex.last_level && sz2 != rsc->slices[lvl+1].size0) + sz2 = rsc->slices[++lvl].size0; + so->texconst3 |= A3XX_TEX_CONST_3_LAYERSZ2(sz2); break; default: so->texconst3 = 0x00000000; diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 69e54526848..efafb8988b4 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -215,14 +215,20 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment) slice->pitch = width = align(width, 32); slice->offset = size; - /* 1d array, 2d array, 3d textures (but not cube!) must all have the - * same layer size for each miplevel on a3xx. These are also the - * targets that have non-1 alignment. + /* 1d array and 2d array textures must all have the same layer size + * for each miplevel on a3xx. 3d textures can have different layer + * sizes for high levels, but the hw auto-sizer is buggy (or at least + * different than what this code does), so as soon as the layer size + * range gets into range, we stop reducing it. */ - if (level == 0 || layers_in_level == 1 || alignment == 1) + if (prsc->target == PIPE_TEXTURE_3D && ( + level == 1 || + (level > 1 && rsc->slices[level - 1].size0 > 0xf000))) + slice->size0 = align(slice->pitch * height * rsc->cpp, alignment); + else if (level == 0 || rsc->layer_first || alignment == 1) slice->size0 = align(slice->pitch * height * rsc->cpp, alignment); else - slice->size0 = rsc->slices[0].size0; + slice->size0 = rsc->slices[level - 1].size0; size += slice->size0 * depth * layers_in_level; |