freedreno: update generated headers
[mesa.git] / src / gallium / drivers / freedreno / freedreno_resource.c
index 461e378c89e4b16077321ad42b38a4d8b26d9bdd..69e545268481177c8d848b51d2c998a819a3e9be 100644 (file)
@@ -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,15 +205,26 @@ 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);
 
-               slice->pitch = align(width, 32);
+               slice->pitch = width = align(width, 32);
                slice->offset = size;
-               slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
+               /* 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.
+                */
+               if (level == 0 || layers_in_level == 1 || alignment == 1)
+                       slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
+               else
+                       slice->size0 = rsc->slices[0].size0;
 
-               size += slice->size0 * depth * prsc->array_size;
+               size += slice->size0 * depth * layers_in_level;
 
                width = u_minify(width, 1);
                height = u_minify(height, 1);
@@ -260,8 +281,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;