zink: process one aspect-mask bit at the time
[mesa.git] / src / gallium / drivers / zink / zink_resource.c
index 50b7604a891a60fd1d5985a94cf5985c1b107d15..658774fcdf0ccc28c10edc9d41be675a1bc4fc43 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "zink_resource.h"
 
-#include "zink_cmdbuf.h"
+#include "zink_batch.h"
 #include "zink_context.h"
 #include "zink_screen.h"
 
@@ -146,6 +146,7 @@ zink_resource_create(struct pipe_screen *pscreen,
       case PIPE_TEXTURE_2D_ARRAY:
       case PIPE_TEXTURE_CUBE:
       case PIPE_TEXTURE_CUBE_ARRAY:
+      case PIPE_TEXTURE_RECT:
          ici.imageType = VK_IMAGE_TYPE_2D;
          /* cube and 2D array needs some quirks here */
          if (templ->target == PIPE_TEXTURE_CUBE)
@@ -161,9 +162,6 @@ zink_resource_create(struct pipe_screen *pscreen,
          ici.imageType = VK_IMAGE_TYPE_3D;
          break;
 
-      case PIPE_TEXTURE_RECT:
-         unreachable("texture rects not supported");
-
       case PIPE_BUFFER:
          unreachable("PIPE_BUFFER should already be handled");
 
@@ -339,13 +337,11 @@ zink_transfer_copy_bufimage(struct zink_context *ctx,
                             struct zink_transfer *trans,
                             bool buf2img)
 {
-   struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
-   if (!cmdbuf)
-      return false;
+   struct zink_batch *batch = zink_batch_no_rp(ctx);
 
    if (res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
        res->layout != VK_IMAGE_LAYOUT_GENERAL) {
-      zink_resource_barrier(cmdbuf->cmdbuf, res, res->aspect,
+      zink_resource_barrier(batch->cmdbuf, res, res->aspect,
                             VK_IMAGE_LAYOUT_GENERAL);
       res->layout = VK_IMAGE_LAYOUT_GENERAL;
    }
@@ -354,7 +350,6 @@ zink_transfer_copy_bufimage(struct zink_context *ctx,
    copyRegion.bufferOffset = staging_res->offset;
    copyRegion.bufferRowLength = 0;
    copyRegion.bufferImageHeight = 0;
-   copyRegion.imageSubresource.aspectMask = res->aspect;
    copyRegion.imageSubresource.mipLevel = trans->base.level;
    copyRegion.imageSubresource.layerCount = 1;
    if (res->base.array_size > 1) {
@@ -370,12 +365,20 @@ zink_transfer_copy_bufimage(struct zink_context *ctx,
    copyRegion.imageExtent.width = trans->base.box.width;
    copyRegion.imageExtent.height = trans->base.box.height;
 
-   if (buf2img)
-      vkCmdCopyBufferToImage(cmdbuf->cmdbuf, staging_res->buffer, res->image, res->layout, 1, &copyRegion);
-   else
-      vkCmdCopyImageToBuffer(cmdbuf->cmdbuf, res->image, res->layout, staging_res->buffer, 1, &copyRegion);
+   zink_batch_reference_resoure(batch, res);
+   zink_batch_reference_resoure(batch, staging_res);
+
+   unsigned aspects = res->aspect;
+   while (aspects) {
+      int aspect = 1 << u_bit_scan(&aspects);
+      copyRegion.imageSubresource.aspectMask = aspect;
+
+      if (buf2img)
+         vkCmdCopyBufferToImage(batch->cmdbuf, staging_res->buffer, res->image, res->layout, 1, &copyRegion);
+      else
+         vkCmdCopyImageToBuffer(batch->cmdbuf, res->image, res->layout, staging_res->buffer, 1, &copyRegion);
+   }
 
-   zink_end_cmdbuf(ctx, cmdbuf);
    return true;
 }
 
@@ -422,7 +425,7 @@ zink_transfer_map(struct pipe_context *pctx,
          struct pipe_resource templ = *pres;
          templ.usage = PIPE_USAGE_STAGING;
          templ.target = PIPE_BUFFER;
-         templ.bind = 0; // HACK: there's no transfer binding, but usage should tell us enough 
+         templ.bind = 0;
          templ.width0 = trans->base.layer_stride * box->depth;
          templ.height0 = templ.depth0 = 0;
          templ.last_level = 0;
@@ -492,8 +495,7 @@ zink_transfer_unmap(struct pipe_context *pctx,
          zink_transfer_copy_bufimage(ctx, res, staging_res, trans, true);
       }
 
-      zink_resource_destroy(pctx->screen, trans->staging_res);
-      trans->staging_res = NULL;
+      pipe_resource_reference(&trans->staging_res, NULL);
    } else
       vkUnmapMemory(screen->dev, res->mem);