zink: refactor blitting
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Wed, 24 Jul 2019 21:18:08 +0000 (23:18 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:48 +0000 (08:51 +0000)
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/zink_context.c

index cd4d61ae96936f398b9317e371b1c2236189ed9f..a320f86067ffb65abe5c95276df4b431c9aa1ad7 100644 (file)
@@ -1160,138 +1160,169 @@ zink_flush(struct pipe_context *pctx,
                                  PIPE_TIMEOUT_INFINITE);
 }
 
-static void
-zink_blit(struct pipe_context *pctx,
-          const struct pipe_blit_info *info)
+static bool
+blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info)
 {
-   struct zink_context *ctx = zink_context(pctx);
-   bool is_resolve = false;
    if (info->mask != PIPE_MASK_RGBA ||
        info->scissor_enable ||
-       info->alpha_blend) {
-      if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
-         debug_printf("blit unsupported %s -> %s\n",
-                 util_format_short_name(info->src.resource->format),
-                 util_format_short_name(info->dst.resource->format));
-         return;
-      }
-
-      util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend_state);
-      util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->gfx_pipeline_state.depth_stencil_alpha_state);
-      util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state);
-      util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
-      util_blitter_save_rasterizer(ctx->blitter, ctx->rast_state);
-      util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
-      util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
-      util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
-      util_blitter_save_viewport(ctx->blitter, ctx->viewport_states);
-      util_blitter_save_scissor(ctx->blitter, ctx->scissor_states);
-      util_blitter_save_fragment_sampler_states(ctx->blitter,
-                                                ctx->num_samplers[PIPE_SHADER_FRAGMENT],
-                                                (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]);
-      util_blitter_save_fragment_sampler_views(ctx->blitter,
-                                               ctx->num_image_views[PIPE_SHADER_FRAGMENT],
-                                               ctx->image_views[PIPE_SHADER_FRAGMENT]);
-      util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]);
-      util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
-      util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask);
-
-      util_blitter_blit(ctx->blitter, info);
-      return;
-   }
+       info->alpha_blend)
+      return false;
 
    struct zink_resource *src = zink_resource(info->src.resource);
    struct zink_resource *dst = zink_resource(info->dst.resource);
 
-   if (src->base.nr_samples > 1 && dst->base.nr_samples <= 1)
-      is_resolve = true;
-
    struct zink_batch *batch = zink_batch_no_rp(ctx);
 
    zink_batch_reference_resoure(batch, src);
    zink_batch_reference_resoure(batch, dst);
 
-   if (is_resolve) {
-      VkImageResolve region = {};
-
-      region.srcSubresource.aspectMask = src->aspect;
-      region.srcSubresource.mipLevel = info->src.level;
-      region.srcSubresource.baseArrayLayer = 0; // no clue
-      region.srcSubresource.layerCount = 1; // no clue
-      region.srcOffset.x = info->src.box.x;
-      region.srcOffset.y = info->src.box.y;
-      region.srcOffset.z = info->src.box.z;
+   VkImageResolve region = {};
+
+   region.srcSubresource.aspectMask = src->aspect;
+   region.srcSubresource.mipLevel = info->src.level;
+   region.srcSubresource.baseArrayLayer = 0; // no clue
+   region.srcSubresource.layerCount = 1; // no clue
+   region.srcOffset.x = info->src.box.x;
+   region.srcOffset.y = info->src.box.y;
+   region.srcOffset.z = info->src.box.z;
+
+   region.dstSubresource.aspectMask = dst->aspect;
+   region.dstSubresource.mipLevel = info->dst.level;
+   region.dstSubresource.baseArrayLayer = 0; // no clue
+   region.dstSubresource.layerCount = 1; // no clue
+   region.dstOffset.x = info->dst.box.x;
+   region.dstOffset.y = info->dst.box.y;
+   region.dstOffset.z = info->dst.box.z;
+
+   region.extent.width = info->dst.box.width;
+   region.extent.height = info->dst.box.height;
+   region.extent.depth = info->dst.box.depth;
+   vkCmdResolveImage(batch->cmdbuf, src->image, src->layout,
+                     dst->image, dst->layout,
+                     1, &region);
 
-      region.dstSubresource.aspectMask = dst->aspect;
-      region.dstSubresource.mipLevel = info->dst.level;
-      region.dstSubresource.baseArrayLayer = 0; // no clue
-      region.dstSubresource.layerCount = 1; // no clue
-      region.dstOffset.x = info->dst.box.x;
-      region.dstOffset.y = info->dst.box.y;
-      region.dstOffset.z = info->dst.box.z;
-
-      region.extent.width = info->dst.box.width;
-      region.extent.height = info->dst.box.height;
-      region.extent.depth = info->dst.box.depth;
-      vkCmdResolveImage(batch->cmdbuf, src->image, src->layout,
-                        dst->image, dst->layout,
-                        1, &region);
+   /* HACK: I have no idea why this is needed, but without it ioquake3
+    * randomly keeps fading to black.
+    */
+   flush_batch(ctx);
 
-   } else {
-      if (dst->layout != VK_IMAGE_LAYOUT_GENERAL &&
-          dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
-         zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
-                               VK_IMAGE_LAYOUT_GENERAL);
+   return true;
+}
 
-      VkImageBlit region = {};
-      region.srcSubresource.aspectMask = src->aspect;
-      region.srcSubresource.mipLevel = info->src.level;
-      region.srcOffsets[0].x = info->src.box.x;
-      region.srcOffsets[0].y = info->src.box.y;
-      region.srcOffsets[1].x = info->src.box.x + info->src.box.width;
-      region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
+static bool
+blit_native(struct zink_context *ctx, const struct pipe_blit_info *info)
+{
+   if (info->mask != PIPE_MASK_RGBA ||
+       info->scissor_enable ||
+       info->alpha_blend)
+      return false;
 
-      if (src->base.array_size > 1) {
-         region.srcOffsets[0].z = 0;
-         region.srcOffsets[1].z = 1;
-         region.srcSubresource.baseArrayLayer = info->src.box.z;
-         region.srcSubresource.layerCount = info->src.box.depth;
-      } else {
-         region.srcOffsets[0].z = info->src.box.z;
-         region.srcOffsets[1].z = info->src.box.z + info->src.box.depth;
-         region.srcSubresource.baseArrayLayer = 0;
-         region.srcSubresource.layerCount = 1;
-      }
+   struct zink_resource *src = zink_resource(info->src.resource);
+   struct zink_resource *dst = zink_resource(info->dst.resource);
 
-      region.dstSubresource.aspectMask = dst->aspect;
-      region.dstSubresource.mipLevel = info->dst.level;
-      region.dstOffsets[0].x = info->dst.box.x;
-      region.dstOffsets[0].y = info->dst.box.y;
-      region.dstOffsets[1].x = info->dst.box.x + info->dst.box.width;
-      region.dstOffsets[1].y = info->dst.box.y + info->dst.box.height;
+   struct zink_batch *batch = zink_batch_no_rp(ctx);
+   zink_batch_reference_resoure(batch, src);
+   zink_batch_reference_resoure(batch, dst);
 
-      if (dst->base.array_size > 1) {
-         region.dstOffsets[0].z = 0;
-         region.dstOffsets[1].z = 1;
-         region.dstSubresource.baseArrayLayer = info->dst.box.z;
-         region.dstSubresource.layerCount = info->dst.box.depth;
-      } else {
-         region.dstOffsets[0].z = info->dst.box.z;
-         region.dstOffsets[1].z = info->dst.box.z + info->dst.box.depth;
-         region.dstSubresource.baseArrayLayer = 0;
-         region.dstSubresource.layerCount = 1;
-      }
+   if (dst->layout != VK_IMAGE_LAYOUT_GENERAL &&
+       dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
+      zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
+                            VK_IMAGE_LAYOUT_GENERAL);
+
+   VkImageBlit region = {};
+   region.srcSubresource.aspectMask = src->aspect;
+   region.srcSubresource.mipLevel = info->src.level;
+   region.srcOffsets[0].x = info->src.box.x;
+   region.srcOffsets[0].y = info->src.box.y;
+   region.srcOffsets[1].x = info->src.box.x + info->src.box.width;
+   region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
+
+   if (src->base.array_size > 1) {
+      region.srcOffsets[0].z = 0;
+      region.srcOffsets[1].z = 1;
+      region.srcSubresource.baseArrayLayer = info->src.box.z;
+      region.srcSubresource.layerCount = info->src.box.depth;
+   } else {
+      region.srcOffsets[0].z = info->src.box.z;
+      region.srcOffsets[1].z = info->src.box.z + info->src.box.depth;
+      region.srcSubresource.baseArrayLayer = 0;
+      region.srcSubresource.layerCount = 1;
+   }
 
-      vkCmdBlitImage(batch->cmdbuf, src->image, src->layout,
-                     dst->image, dst->layout,
-                     1, &region,
-                     filter(info->filter));
+   region.dstSubresource.aspectMask = dst->aspect;
+   region.dstSubresource.mipLevel = info->dst.level;
+   region.dstOffsets[0].x = info->dst.box.x;
+   region.dstOffsets[0].y = info->dst.box.y;
+   region.dstOffsets[1].x = info->dst.box.x + info->dst.box.width;
+   region.dstOffsets[1].y = info->dst.box.y + info->dst.box.height;
+
+   if (dst->base.array_size > 1) {
+      region.dstOffsets[0].z = 0;
+      region.dstOffsets[1].z = 1;
+      region.dstSubresource.baseArrayLayer = info->dst.box.z;
+      region.dstSubresource.layerCount = info->dst.box.depth;
+   } else {
+      region.dstOffsets[0].z = info->dst.box.z;
+      region.dstOffsets[1].z = info->dst.box.z + info->dst.box.depth;
+      region.dstSubresource.baseArrayLayer = 0;
+      region.dstSubresource.layerCount = 1;
    }
 
+   vkCmdBlitImage(batch->cmdbuf, src->image, src->layout,
+                  dst->image, dst->layout,
+                  1, &region,
+                  filter(info->filter));
+
    /* HACK: I have no idea why this is needed, but without it ioquake3
     * randomly keeps fading to black.
     */
    flush_batch(ctx);
+
+   return true;
+}
+
+static void
+zink_blit(struct pipe_context *pctx,
+          const struct pipe_blit_info *info)
+{
+   struct zink_context *ctx = zink_context(pctx);
+   if (info->src.resource->nr_samples > 1 &&
+       info->dst.resource->nr_samples <= 1) {
+      if (blit_resolve(ctx, info))
+         return;
+   } else {
+      if (blit_native(ctx, info))
+         return;
+   }
+
+   if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
+      debug_printf("blit unsupported %s -> %s\n",
+              util_format_short_name(info->src.resource->format),
+              util_format_short_name(info->dst.resource->format));
+      return;
+   }
+
+   util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend_state);
+   util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->gfx_pipeline_state.depth_stencil_alpha_state);
+   util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state);
+   util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
+   util_blitter_save_rasterizer(ctx->blitter, ctx->rast_state);
+   util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
+   util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
+   util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
+   util_blitter_save_viewport(ctx->blitter, ctx->viewport_states);
+   util_blitter_save_scissor(ctx->blitter, ctx->scissor_states);
+   util_blitter_save_fragment_sampler_states(ctx->blitter,
+                                             ctx->num_samplers[PIPE_SHADER_FRAGMENT],
+                                             (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]);
+   util_blitter_save_fragment_sampler_views(ctx->blitter,
+                                            ctx->num_image_views[PIPE_SHADER_FRAGMENT],
+                                            ctx->image_views[PIPE_SHADER_FRAGMENT]);
+   util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]);
+   util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
+   util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask);
+
+   util_blitter_blit(ctx->blitter, info);
 }
 
 static void