Mesa (main): lavapipe: VK_KHR_dynamic_rendering

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 4 03:46:49 UTC 2021


Module: Mesa
Branch: main
Commit: 8a6160a35428264fa3b4722d8c72b9c8aa4b8256
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8a6160a35428264fa3b4722d8c72b9c8aa4b8256

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Mon Oct  4 14:56:31 2021 -0400

lavapipe: VK_KHR_dynamic_rendering

this is a conformant implementation

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13627>

---

 src/gallium/frontends/lavapipe/lvp_device.c   |   6 +
 src/gallium/frontends/lavapipe/lvp_execute.c  | 187 +++++++++++++++++++++++++-
 src/gallium/frontends/lavapipe/lvp_pipeline.c |   7 +-
 3 files changed, 196 insertions(+), 4 deletions(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index bfc07ba84eb..6c763c62c29 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -92,6 +92,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
    .KHR_device_group                      = true,
    .KHR_draw_indirect_count               = true,
    .KHR_driver_properties                 = true,
+   .KHR_dynamic_rendering                 = true,
    .KHR_external_fence                    = true,
    .KHR_external_memory                   = true,
 #ifdef PIPE_MEMORY_FD
@@ -666,6 +667,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
          features->primitiveTopologyPatchListRestart = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR: {
+         VkPhysicalDeviceDynamicRenderingFeaturesKHR *features = (VkPhysicalDeviceDynamicRenderingFeaturesKHR *)ext;
+         features->dynamicRendering = VK_TRUE;
+         break;
+      }
       default:
          break;
       }
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index 3f53e822428..1e4422203cd 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -1805,8 +1805,171 @@ static void handle_begin_render_pass2(struct vk_cmd_queue_entry *cmd,
    begin_render_pass(cmd->u.begin_render_pass2.render_pass_begin, state);
 }
 
-static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
-                                    struct rendering_state *state)
+static VkAttachmentLoadOp
+get_load_op(VkAttachmentLoadOp op, bool resuming)
+{
+   if (!resuming)
+      return op;
+   if (op == VK_ATTACHMENT_LOAD_OP_CLEAR)
+      return VK_ATTACHMENT_LOAD_OP_LOAD;
+   return op;
+}
+
+static void handle_begin_rendering(struct vk_cmd_queue_entry *cmd,
+                                   struct rendering_state *state)
+{
+   const VkRenderingInfoKHR *info = cmd->u.begin_rendering_khr.rendering_info;
+   bool resuming = (info->flags & VK_RENDERING_RESUMING_BIT_KHR) == VK_RENDERING_RESUMING_BIT_KHR;
+   bool suspending = (info->flags & VK_RENDERING_SUSPENDING_BIT_KHR) == VK_RENDERING_SUSPENDING_BIT_KHR;
+   assert(!state->pass);
+   state->vk_framebuffer = NULL;
+   state->render_area = info->renderArea;
+
+   unsigned num_attachments = info->colorAttachmentCount + (info->pDepthAttachment || info->pStencilAttachment);
+   unsigned i, color_resolves = 0;
+   for (i = 0; i < info->colorAttachmentCount; i++) {
+      if (info->pColorAttachments[i].resolveImageView)
+         color_resolves++;
+   }
+   bool zresolve = info->pDepthAttachment && info->pDepthAttachment->resolveImageView;
+   bool sresolve = info->pStencilAttachment && info->pStencilAttachment->resolveImageView;
+   unsigned num_resolves = color_resolves + (zresolve || sresolve);
+   unsigned attachment_count = num_attachments + num_resolves;
+   state->imageless_views = realloc(state->imageless_views, sizeof(*state->imageless_views) * attachment_count);
+
+   state->render_area = info->renderArea;
+   state->framebuffer.width = info->renderArea.offset.x + info->renderArea.extent.width;
+   state->framebuffer.height = info->renderArea.offset.y + info->renderArea.extent.height;
+   state->framebuffer.layers = info->layerCount;
+
+   if (state->num_pending_aspects < attachment_count) {
+      state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * attachment_count);
+      state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * attachment_count);
+      state->num_pending_aspects = attachment_count;
+   }
+
+   /* [lvp_subpass] [attachment_count * lvp_render_pass_attachment] [attachment_count * lvp_render_pass_attachment*] */
+   size_t size = sizeof(struct lvp_subpass) + attachment_count * (sizeof(void*) + sizeof(struct lvp_render_pass_attachment));
+   size_t attachment_offset = sizeof(struct lvp_subpass);
+   size_t attachment_ref_offset = attachment_offset + attachment_count * sizeof(struct lvp_render_pass_attachment);
+   struct lvp_subpass *subpass = calloc(1, size);
+   subpass->color_count = info->colorAttachmentCount;
+   bool has_ds = !!info->pDepthAttachment + !!info->pStencilAttachment;
+   state->attachments = realloc(state->attachments, sizeof(*state->attachments) * attachment_count);
+   struct lvp_render_pass_attachment *attachments = (void*)((uint8_t*)subpass + attachment_offset);
+   struct lvp_render_pass_attachment *resolve_attachments = num_resolves ? &attachments[subpass->color_count + has_ds] : NULL;
+   struct lvp_render_pass_attachment **attachment_refs = (void*)((uint8_t*)subpass + attachment_ref_offset);
+   struct lvp_render_pass_attachment **resolve_attachment_refs = num_resolves ? &attachment_refs[subpass->color_count + has_ds] : NULL;
+
+   subpass->view_mask = info->viewMask;
+   subpass->has_color_resolve = color_resolves > 0;
+   if (info->colorAttachmentCount)
+      subpass->color_attachments = attachment_refs;
+   if (has_ds)
+      subpass->depth_stencil_attachment = &attachment_refs[info->colorAttachmentCount];
+   if (color_resolves)
+      subpass->resolve_attachments = resolve_attachment_refs;
+   if (zresolve || sresolve)
+      subpass->ds_resolve_attachment = &resolve_attachment_refs[color_resolves];
+
+   unsigned resolve_idx = 0;
+   for (i = 0; i < info->colorAttachmentCount; i++) {
+      if (!info->pColorAttachments[i].imageView)
+         continue;
+      struct lvp_render_pass_attachment *att = &attachments[i];
+
+      att->attachment = i;
+      att->load_op = get_load_op(info->pColorAttachments[i].loadOp, resuming);
+      if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+         state->attachments[i].pending_clear_aspects = VK_IMAGE_ASPECT_COLOR_BIT;
+         state->attachments[i].clear_value = info->pColorAttachments[i].clearValue;
+      } else
+         state->attachments[i].pending_clear_aspects = 0;
+
+      state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
+      state->cleared_views[i] = 0;
+
+      state->imageless_views[i] = lvp_image_view_from_handle(info->pColorAttachments[i].imageView);
+      att->format = state->imageless_views[i]->format;
+      att->samples = state->imageless_views[i]->image->bo->nr_samples;
+      attachment_refs[i] = att;
+      if (!suspending && info->pColorAttachments[i].resolveImageView) {
+         struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
+         resolve_att->attachment = num_attachments + resolve_idx;
+         resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+         state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pColorAttachments[i].resolveImageView);
+         resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
+         resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
+         resolve_attachment_refs[resolve_idx] = resolve_att;
+         resolve_idx++;
+      }
+   }
+   if (info->pDepthAttachment && info->pDepthAttachment->imageView) {
+      struct lvp_render_pass_attachment *att = &attachments[i];
+
+      att->attachment = i;
+      att->load_op = get_load_op(info->pDepthAttachment->loadOp, resuming);
+      att->stencil_load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+      if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+         state->attachments[i].pending_clear_aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
+         state->attachments[i].clear_value = info->pDepthAttachment->clearValue;
+      } else
+         state->attachments[i].pending_clear_aspects = 0;
+
+      state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
+      state->cleared_views[i] = 0;
+
+      state->imageless_views[i] = lvp_image_view_from_handle(info->pDepthAttachment->imageView);
+      att->format = state->imageless_views[i]->format;
+      att->samples = state->imageless_views[i]->image->bo->nr_samples;
+      attachment_refs[i] = att;
+      if (!suspending && info->pDepthAttachment->resolveImageView) {
+         struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
+         resolve_att->attachment = num_attachments + resolve_idx;
+         resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+         state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pDepthAttachment->resolveImageView);
+         resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
+         resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
+         resolve_attachment_refs[resolve_idx] = resolve_att;
+      }
+   }
+   if (info->pStencilAttachment && info->pStencilAttachment->imageView) {
+      struct lvp_render_pass_attachment *att = &attachments[i];
+
+      att->attachment = i;
+      if (!info->pDepthAttachment)
+         att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+      att->stencil_load_op = get_load_op(info->pStencilAttachment->loadOp, resuming);
+      if (!info->pDepthAttachment)
+         state->attachments[i].pending_clear_aspects = 0;
+      if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+         state->attachments[i].pending_clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
+         state->attachments[i].clear_value.depthStencil.stencil = info->pStencilAttachment->clearValue.depthStencil.stencil;
+      }
+
+      state->pending_clear_aspects[i] |= state->attachments[i].pending_clear_aspects;
+      state->cleared_views[i] = 0;
+
+      state->imageless_views[i] = lvp_image_view_from_handle(info->pStencilAttachment->imageView);
+      att->format = state->imageless_views[i]->format;
+      att->samples = state->imageless_views[i]->image->bo->nr_samples;
+      attachment_refs[i] = att;
+      if (!suspending && info->pStencilAttachment->resolveImageView) {
+         struct lvp_render_pass_attachment *resolve_att = &resolve_attachments[resolve_idx];
+         resolve_att->attachment = num_attachments + resolve_idx;
+         resolve_att->load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+         state->imageless_views[num_attachments + resolve_idx] = lvp_image_view_from_handle(info->pStencilAttachment->resolveImageView);
+         resolve_att->format = state->imageless_views[num_attachments + resolve_idx]->format;
+         resolve_att->samples = state->imageless_views[num_attachments + resolve_idx]->image->bo->nr_samples;
+         resolve_attachment_refs[resolve_idx] = resolve_att;
+      }
+   }
+
+   begin_render_subpass(state, subpass);
+}
+
+static void
+end_rendering(struct rendering_state *state)
 {
    state->pctx->flush(state->pctx, NULL, 0);
 
@@ -1815,6 +1978,20 @@ static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
    free(state->attachments);
    state->attachments = NULL;
    state->pass = NULL;
+}
+
+static void handle_end_rendering(struct vk_cmd_queue_entry *cmd,
+                                 struct rendering_state *state)
+{
+   end_rendering(state);
+   free(state->subpass);
+   state->subpass = NULL;
+}
+
+static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
+                                    struct rendering_state *state)
+{
+   end_rendering(state);
    state->subpass = NULL;
 }
 
@@ -3909,6 +4086,12 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
       case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT:
          handle_set_color_write_enable(cmd, state);
          break;
+      case VK_CMD_BEGIN_RENDERING_KHR:
+         handle_begin_rendering(cmd, state);
+         break;
+      case VK_CMD_END_RENDERING_KHR:
+         handle_end_rendering(cmd, state);
+         break;
       case VK_CMD_SET_DEVICE_MASK:
          /* no-op */
          break;
diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c
index ef5de756281..8720fd8479b 100644
--- a/src/gallium/frontends/lavapipe/lvp_pipeline.c
+++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c
@@ -279,6 +279,7 @@ deep_copy_graphics_create_info(void *mem_ctx,
    VkPipelineVertexInputStateCreateInfo *vertex_input;
    VkPipelineRasterizationStateCreateInfo *rasterization_state;
    LVP_FROM_HANDLE(lvp_render_pass, pass, src->renderPass);
+   const VkPipelineRenderingCreateInfoKHR *rp_info = vk_find_struct_const(src->pNext, PIPELINE_RENDERING_CREATE_INFO_KHR);
 
    dst->sType = src->sType;
    dst->pNext = NULL;
@@ -367,7 +368,8 @@ deep_copy_graphics_create_info(void *mem_ctx,
       dst->pMultisampleState = NULL;
 
    /* pDepthStencilState */
-   if (src->pDepthStencilState && !rasterization_disabled && pass->has_zs_attachment) {
+   if (src->pDepthStencilState && !rasterization_disabled &&
+       (pass ? pass->has_zs_attachment : (rp_info->depthAttachmentFormat || rp_info->stencilAttachmentFormat))) {
       LVP_PIPELINE_DUP(dst->pDepthStencilState,
                        src->pDepthStencilState,
                        VkPipelineDepthStencilStateCreateInfo,
@@ -376,7 +378,8 @@ deep_copy_graphics_create_info(void *mem_ctx,
       dst->pDepthStencilState = NULL;
 
    /* pColorBlendState */
-   if (src->pColorBlendState && !rasterization_disabled && pass->has_color_attachment) {
+   if (src->pColorBlendState && !rasterization_disabled &&
+       (pass ? pass->has_color_attachment : rp_info->colorAttachmentCount)) {
       VkPipelineColorBlendStateCreateInfo*    cb_state;
 
       cb_state = ralloc(mem_ctx, VkPipelineColorBlendStateCreateInfo);



More information about the mesa-commit mailing list