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