Mesa (master): lavapipe: add clear support for multiview
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Mar 12 05:34:53 UTC 2021
Module: Mesa
Branch: master
Commit: 4d72515e32dcea8762821d688f188ba772187672
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4d72515e32dcea8762821d688f188ba772187672
Author: Dave Airlie <airlied at redhat.com>
Date: Thu Mar 4 14:00:23 2021 +1000
lavapipe: add clear support for multiview
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9399>
---
src/gallium/frontends/lavapipe/lvp_execute.c | 158 +++++++++++++++++----------
1 file changed, 101 insertions(+), 57 deletions(-)
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index bb464e6cba7..1c0c7efe922 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -124,6 +124,7 @@ struct rendering_state {
const struct lvp_attachment_state *attachments;
VkImageAspectFlags *pending_clear_aspects;
+ uint32_t *cleared_views;
int num_pending_aspects;
uint32_t num_so_targets;
@@ -1195,8 +1196,11 @@ static inline bool
attachment_needs_clear(struct rendering_state *state,
uint32_t a)
{
+ const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
+ uint32_t view_mask = subpass->view_mask;
return (a != VK_ATTACHMENT_UNUSED &&
- state->pending_clear_aspects[a]);
+ state->pending_clear_aspects[a] &&
+ (!view_mask || (view_mask & ~state->cleared_views[a])));
}
static bool
@@ -1217,6 +1221,40 @@ subpass_needs_clear(struct rendering_state *state)
return false;
}
+static void clear_attachment_layers(struct rendering_state *state,
+ struct lvp_image_view *imgv,
+ VkRect2D *rect,
+ unsigned base_layer, unsigned layer_count,
+ unsigned ds_clear_flags, double dclear_val,
+ uint32_t sclear_val,
+ union pipe_color_union *col_val)
+{
+ struct pipe_surface *clear_surf = create_img_surface(state,
+ imgv,
+ imgv->format,
+ state->framebuffer.width,
+ state->framebuffer.height,
+ base_layer,
+ base_layer + layer_count - 1);
+
+ if (ds_clear_flags) {
+ state->pctx->clear_depth_stencil(state->pctx,
+ clear_surf,
+ ds_clear_flags,
+ dclear_val, sclear_val,
+ rect->offset.x, rect->offset.y,
+ rect->extent.width, rect->extent.height,
+ true);
+ } else {
+ state->pctx->clear_render_target(state->pctx, clear_surf,
+ col_val,
+ rect->offset.x, rect->offset.y,
+ rect->extent.width, rect->extent.height,
+ true);
+ }
+ state->pctx->surface_destroy(state->pctx, clear_surf);
+}
+
static void render_subpass_clear(struct rendering_state *state)
{
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
@@ -1227,25 +1265,31 @@ static void render_subpass_clear(struct rendering_state *state)
if (!attachment_needs_clear(state, a))
continue;
- struct lvp_render_pass_attachment *att = &state->pass->attachments[a];
- struct lvp_image_view *imgv = state->vk_framebuffer->attachments[a];
-
- add_img_view_surface(state, imgv, att->format, state->framebuffer.width, state->framebuffer.height);
-
union pipe_color_union color_clear_val = { 0 };
const VkClearValue value = state->attachments[a].clear_value;
color_clear_val.ui[0] = value.color.uint32[0];
color_clear_val.ui[1] = value.color.uint32[1];
color_clear_val.ui[2] = value.color.uint32[2];
color_clear_val.ui[3] = value.color.uint32[3];
- state->pctx->clear_render_target(state->pctx,
- imgv->surface,
- &color_clear_val,
- state->render_area.offset.x, state->render_area.offset.y,
- state->render_area.extent.width, state->render_area.extent.height,
- false);
- state->pending_clear_aspects[a] = 0;
+ struct lvp_image_view *imgv = state->vk_framebuffer->attachments[a];
+
+ assert(imgv->surface);
+
+ if (subpass->view_mask) {
+ u_foreach_bit(i, subpass->view_mask)
+ clear_attachment_layers(state, imgv, &state->render_area,
+ i, 1, 0, 0, 0, &color_clear_val);
+ state->cleared_views[a] |= subpass->view_mask;
+ } else {
+ state->pctx->clear_render_target(state->pctx,
+ imgv->surface,
+ &color_clear_val,
+ state->render_area.offset.x, state->render_area.offset.y,
+ state->render_area.extent.width, state->render_area.extent.height,
+ false);
+ state->pending_clear_aspects[a] = 0;
+ }
}
if (subpass->depth_stencil_attachment) {
@@ -1257,28 +1301,34 @@ static void render_subpass_clear(struct rendering_state *state)
struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
struct lvp_image_view *imgv = state->vk_framebuffer->attachments[ds];
- add_img_view_surface(state, imgv, att->format, state->framebuffer.width, state->framebuffer.height);
+ assert (util_format_is_depth_or_stencil(imgv->surface->format));
- if (util_format_is_depth_or_stencil(imgv->surface->format)) {
- const struct util_format_description *desc = util_format_description(imgv->surface->format);
- double dclear_val = 0;
- uint32_t sclear_val = 0;
- uint32_t ds_clear_flags = 0;
+ const struct util_format_description *desc = util_format_description(imgv->surface->format);
+ double dclear_val = 0;
+ uint32_t sclear_val = 0;
+ uint32_t ds_clear_flags = 0;
- if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
- (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
- ds_clear_flags |= PIPE_CLEAR_STENCIL;
- if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
- sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
- }
- if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
- (util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
- ds_clear_flags |= PIPE_CLEAR_DEPTH;
- if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
- dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
- }
+ if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
+ (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
+ ds_clear_flags |= PIPE_CLEAR_STENCIL;
+ if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
+ sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
+ }
+ if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
+ (util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
+ ds_clear_flags |= PIPE_CLEAR_DEPTH;
+ if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
+ dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
+ }
- if (ds_clear_flags)
+ assert(imgv->surface);
+ if (ds_clear_flags) {
+ if (subpass->view_mask) {
+ u_foreach_bit(i, subpass->view_mask)
+ clear_attachment_layers(state, imgv, &state->render_area,
+ i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
+ state->cleared_views[ds] |= subpass->view_mask;
+ } else {
state->pctx->clear_depth_stencil(state->pctx,
imgv->surface,
ds_clear_flags,
@@ -1286,8 +1336,10 @@ static void render_subpass_clear(struct rendering_state *state)
state->render_area.offset.x, state->render_area.offset.y,
state->render_area.extent.width, state->render_area.extent.height,
false);
- state->pending_clear_aspects[ds] = 0;
+ state->pending_clear_aspects[ds] = 0;
+ }
}
+
}
}
@@ -1314,6 +1366,8 @@ static void render_subpass_clear_fast(struct rendering_state *state)
state->render_area.extent.height != state->framebuffer.height)
goto slow_clear;
+ if (subpass->view_mask)
+ goto slow_clear;
for (unsigned i = 0; i < subpass->color_count; i++) {
uint32_t a = subpass->color_attachments[i].attachment;
@@ -1458,11 +1512,13 @@ static void handle_begin_render_pass(struct lvp_cmd_buffer_entry *cmd,
if (state->num_pending_aspects < state->pass->attachment_count) {
state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);
+ state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count);
state->num_pending_aspects = state->pass->attachment_count;
}
for (unsigned a = 0; a < state->pass->attachment_count; a++) {
state->pending_clear_aspects[a] = state->attachments[a].pending_clear_aspects;
+ state->cleared_views[a] = 0;
}
begin_render_subpass(state, 0);
}
@@ -2437,30 +2493,17 @@ static void handle_clear_attachments(struct lvp_cmd_buffer_entry *cmd,
for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
- struct pipe_surface *clear_surf = create_img_surface(state,
- imgv,
- imgv->format,
- state->framebuffer.width,
- state->framebuffer.height,
- rect->baseArrayLayer,
- rect->baseArrayLayer + rect->layerCount - 1);
-
- if (ds_clear_flags) {
- state->pctx->clear_depth_stencil(state->pctx,
- clear_surf,
- ds_clear_flags,
- dclear_val, sclear_val,
- rect->rect.offset.x, rect->rect.offset.y,
- rect->rect.extent.width, rect->rect.extent.height,
- true);
- } else {
- state->pctx->clear_render_target(state->pctx, clear_surf,
- &col_val,
- rect->rect.offset.x, rect->rect.offset.y,
- rect->rect.extent.width, rect->rect.extent.height,
- true);
- }
- state->pctx->surface_destroy(state->pctx, clear_surf);
+ if (subpass->view_mask) {
+ u_foreach_bit(i, subpass->view_mask)
+ clear_attachment_layers(state, imgv, &rect->rect,
+ i, 1,
+ ds_clear_flags, dclear_val, sclear_val,
+ &col_val);
+ } else
+ clear_attachment_layers(state, imgv, &rect->rect,
+ rect->baseArrayLayer, rect->layerCount,
+ ds_clear_flags, dclear_val, sclear_val,
+ &col_val);
}
}
}
@@ -3062,5 +3105,6 @@ VkResult lvp_execute_cmds(struct lvp_device *device,
}
free(state.pending_clear_aspects);
+ free(state.cleared_views);
return VK_SUCCESS;
}
More information about the mesa-commit
mailing list