diff options
author | Rob Clark <[email protected]> | 2014-12-12 13:38:05 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2014-12-13 15:09:37 -0500 |
commit | 0ebd623f6058fd20ee28e206da2da259073fdf86 (patch) | |
tree | 437f4a57e9307a265575b79aabb9cda333df8c92 /src/gallium/drivers/freedreno/freedreno_resource.c | |
parent | cf80694df5fada3d2197626e5a878f17b67625f9 (diff) |
freedreno/a4xx: mipmaps
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_resource.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_resource.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index d604aa3f1f8..c412407314f 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -101,6 +101,7 @@ fd_resource_transfer_map(struct pipe_context *pctx, struct pipe_transfer *ptrans; enum pipe_format format = prsc->format; uint32_t op = 0; + uint32_t offset; char *buf; int ret = 0; @@ -146,10 +147,19 @@ fd_resource_transfer_map(struct pipe_context *pctx, *pptrans = ptrans; - return buf + slice->offset + - box->y / util_format_get_blockheight(format) * ptrans->stride + - box->x / util_format_get_blockwidth(format) * rsc->cpp + - box->z * slice->size0; + if (rsc->layer_first) { + offset = slice->offset + + box->y / util_format_get_blockheight(format) * ptrans->stride + + box->x / util_format_get_blockwidth(format) * rsc->cpp + + box->z * rsc->layer_size; + } else { + offset = slice->offset + + box->y / util_format_get_blockheight(format) * ptrans->stride + + box->x / util_format_get_blockwidth(format) * rsc->cpp + + box->z * slice->size0; + } + + return buf + offset; fail: fd_resource_transfer_unmap(pctx, ptrans); @@ -195,6 +205,10 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment) uint32_t width = prsc->width0; uint32_t height = prsc->height0; uint32_t depth = prsc->depth0; + /* in layer_first layout, the level (slice) contains just one + * layer (since in fact the layer contains the slices) + */ + uint32_t layers_in_level = rsc->layer_first ? 1 : prsc->array_size; for (level = 0; level <= prsc->last_level; level++) { struct fd_resource_slice *slice = fd_resource_slice(rsc, level); @@ -203,7 +217,7 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment) slice->offset = size; slice->size0 = align(slice->pitch * height * rsc->cpp, alignment); - size += slice->size0 * depth * prsc->array_size; + size += slice->size0 * depth * layers_in_level; width = u_minify(width, 1); height = u_minify(height, 1); @@ -216,12 +230,6 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment) static uint32_t slice_alignment(struct pipe_screen *pscreen, const struct pipe_resource *tmpl) { - struct fd_screen *screen = fd_screen(pscreen); - - /* on a4xx, seems like everything is aligned to page: */ - if ((screen->gpu_id >= 400) && (screen->gpu_id < 500)) - return 4096; - /* on a3xx, 2d array and 3d textures seem to want their * layers aligned to page boundaries: */ @@ -266,8 +274,25 @@ fd_resource_create(struct pipe_screen *pscreen, assert(rsc->cpp); + if (is_a4xx(fd_screen(pscreen))) { + switch (tmpl->target) { + case PIPE_TEXTURE_3D: + /* TODO 3D_ARRAY? */ + rsc->layer_first = false; + break; + default: + rsc->layer_first = true; + break; + } + } + size = setup_slices(rsc, slice_alignment(pscreen, tmpl)); + if (rsc->layer_first) { + rsc->layer_size = align(size, 4096); + size = rsc->layer_size * prsc->array_size; + } + realloc_bo(rsc, size); if (!rsc->bo) goto fail; |