From 58e18a2be9a601581196bb19b31d63f105c8ec06 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 1 Oct 2021 15:53:34 -0400 Subject: [PATCH] lavapipe: remove lvp_subpass_attachment and use lvp_render_pass_attachment refs this is one fewer indirect reference that allows removing a bunch of stuff from renderpass creation now also unused subpass attachments are just NULL pointers, making detection simpler Reviewed-by: Dave Airlie Part-of: --- src/gallium/frontends/lavapipe/lvp_execute.c | 133 +++++++++++----------- src/gallium/frontends/lavapipe/lvp_pass.c | 160 +++++++-------------------- src/gallium/frontends/lavapipe/lvp_private.h | 33 ++---- 3 files changed, 121 insertions(+), 205 deletions(-) diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 6cbd02d..e196734 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -1368,12 +1368,14 @@ subpass_needs_clear(struct rendering_state *state) uint32_t a; const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; for (uint32_t i = 0; i < subpass->color_count; i++) { - a = subpass->color_attachments[i].attachment; + if (!subpass->color_attachments[i]) + continue; + a = subpass->color_attachments[i]->attachment; if (attachment_needs_clear(state, a)) return true; } - if (subpass->depth_stencil_attachment) { - a = subpass->depth_stencil_attachment->attachment; + if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment) { + a = subpass->depth_stencil_attachment[0]->attachment; if (attachment_needs_clear(state, a)) return true; } @@ -1429,7 +1431,9 @@ static void render_subpass_clear(struct rendering_state *state) const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; for (unsigned i = 0; i < subpass->color_count; i++) { - uint32_t a = subpass->color_attachments[i].attachment; + if (!subpass->color_attachments[i]) + continue; + uint32_t a = subpass->color_attachments[i]->attachment; if (!attachment_needs_clear(state, a)) continue; @@ -1461,8 +1465,8 @@ static void render_subpass_clear(struct rendering_state *state) } } - if (subpass->depth_stencil_attachment) { - uint32_t ds = subpass->depth_stencil_attachment->attachment; + if (subpass->depth_stencil_attachment && subpass->depth_stencil_attachment[0]) { + uint32_t ds = subpass->depth_stencil_attachment[0]->attachment; if (!attachment_needs_clear(state, ds)) return; @@ -1538,7 +1542,9 @@ static void render_subpass_clear_fast(struct rendering_state *state) if (subpass->view_mask) goto slow_clear; for (unsigned i = 0; i < subpass->color_count; i++) { - uint32_t a = subpass->color_attachments[i].attachment; + if (!subpass->color_attachments[i]) + continue; + uint32_t a = subpass->color_attachments[i]->attachment; if (!attachment_needs_clear(state, a)) continue; @@ -1553,7 +1559,9 @@ static void render_subpass_clear_fast(struct rendering_state *state) } for (unsigned i = 0; i < subpass->color_count; i++) { - uint32_t a = subpass->color_attachments[i].attachment; + if (!subpass->color_attachments[i]) + continue; + uint32_t a = subpass->color_attachments[i]->attachment; if (!attachment_needs_clear(state, a)) continue; @@ -1561,9 +1569,9 @@ static void render_subpass_clear_fast(struct rendering_state *state) state->pending_clear_aspects[a] = 0; } - if (subpass->depth_stencil_attachment && - attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) { - uint32_t ds = subpass->depth_stencil_attachment->attachment; + if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment && + attachment_needs_clear(state, subpass->depth_stencil_attachment[0]->attachment)) { + uint32_t ds = subpass->depth_stencil_attachment[0]->attachment; struct lvp_render_pass_attachment *att = &state->pass->attachments[ds]; struct lvp_image_view *imgv = get_attachment(state, ds); @@ -1597,70 +1605,69 @@ static void render_pass_resolve(struct rendering_state *state) { const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass]; - if (subpass->depth_stencil_attachment && subpass->ds_resolve_attachment) { - struct lvp_subpass_attachment src_att = *subpass->depth_stencil_attachment; - struct lvp_subpass_attachment dst_att = *subpass->ds_resolve_attachment; - if (dst_att.attachment != VK_ATTACHMENT_UNUSED) { - int num_blits = 1; - if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode) - num_blits = 2; + if (subpass->depth_stencil_attachment && *subpass->depth_stencil_attachment && + subpass->ds_resolve_attachment && *subpass->ds_resolve_attachment) { + struct lvp_render_pass_attachment *src_att = *subpass->depth_stencil_attachment; + struct lvp_render_pass_attachment *dst_att = *subpass->ds_resolve_attachment; + int num_blits = 1; + if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode) + num_blits = 2; - for (unsigned i = 0; i < num_blits; i++) { + for (unsigned i = 0; i < num_blits; i++) { - if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE) - continue; + if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE) + continue; - if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE) - continue; + if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE) + continue; - struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment); - struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment); + struct lvp_image_view *src_imgv = get_attachment(state, src_att->attachment); + struct lvp_image_view *dst_imgv = get_attachment(state, dst_att->attachment); - struct pipe_blit_info info; - memset(&info, 0, sizeof(info)); + struct pipe_blit_info info; + memset(&info, 0, sizeof(info)); - info.src.resource = src_imgv->image->bo; - info.dst.resource = dst_imgv->image->bo; - info.src.format = src_imgv->pformat; - info.dst.format = dst_imgv->pformat; - info.filter = PIPE_TEX_FILTER_NEAREST; + info.src.resource = src_imgv->image->bo; + info.dst.resource = dst_imgv->image->bo; + info.src.format = src_imgv->pformat; + info.dst.format = dst_imgv->pformat; + info.filter = PIPE_TEX_FILTER_NEAREST; - if (num_blits == 1) - info.mask = PIPE_MASK_ZS; - else if (i == 0) - info.mask = PIPE_MASK_Z; - else - info.mask = PIPE_MASK_S; + if (num_blits == 1) + info.mask = PIPE_MASK_ZS; + else if (i == 0) + info.mask = PIPE_MASK_Z; + else + info.mask = PIPE_MASK_S; - if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) - info.sample0_only = true; - if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) - info.sample0_only = true; + if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) + info.sample0_only = true; + if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) + info.sample0_only = true; - info.src.box.x = state->render_area.offset.x; - info.src.box.y = state->render_area.offset.y; - info.src.box.width = state->render_area.extent.width; - info.src.box.height = state->render_area.extent.height; - info.src.box.depth = state->vk_framebuffer->layers; + info.src.box.x = state->render_area.offset.x; + info.src.box.y = state->render_area.offset.y; + info.src.box.width = state->render_area.extent.width; + info.src.box.height = state->render_area.extent.height; + info.src.box.depth = state->vk_framebuffer->layers; - info.dst.box = info.src.box; + info.dst.box = info.src.box; - state->pctx->blit(state->pctx, &info); - } + state->pctx->blit(state->pctx, &info); } } if (!subpass->has_color_resolve) return; for (uint32_t i = 0; i < subpass->color_count; i++) { - struct lvp_subpass_attachment src_att = subpass->color_attachments[i]; - struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i]; + struct lvp_render_pass_attachment *src_att = subpass->color_attachments[i]; + struct lvp_render_pass_attachment *dst_att = subpass->resolve_attachments[i]; - if (dst_att.attachment == VK_ATTACHMENT_UNUSED) + if (!src_att || !dst_att) continue; - struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment); - struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment); + struct lvp_image_view *src_imgv = get_attachment(state, src_att->attachment); + struct lvp_image_view *dst_imgv = get_attachment(state, dst_att->attachment); struct pipe_blit_info info; memset(&info, 0, sizeof(info)); @@ -1695,8 +1702,8 @@ static void begin_render_subpass(struct rendering_state *state, const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx]; for (unsigned i = 0; i < subpass->color_count; i++) { - struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i]; - if (color_att->attachment != VK_ATTACHMENT_UNUSED) { + struct lvp_render_pass_attachment *color_att = subpass->color_attachments[i]; + if (color_att) { struct lvp_image_view *imgv = get_attachment(state, color_att->attachment); add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height); state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface; @@ -1706,9 +1713,9 @@ static void begin_render_subpass(struct rendering_state *state, } if (subpass->depth_stencil_attachment) { - struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment; + struct lvp_render_pass_attachment *ds_att = *subpass->depth_stencil_attachment; - if (ds_att->attachment != VK_ATTACHMENT_UNUSED) { + if (ds_att) { struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment); add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height); state->framebuffer.zsbuf = imgv->surface; @@ -2962,13 +2969,13 @@ static void handle_clear_attachments(struct vk_cmd_queue_entry *cmd, struct lvp_image_view *imgv; if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { - struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment]; - if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED) + struct lvp_render_pass_attachment *color_att = subpass->color_attachments[att->colorAttachment]; + if (!color_att) continue; imgv = get_attachment(state, color_att->attachment); } else { - struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment; - if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED) + struct lvp_render_pass_attachment *ds_att = *subpass->depth_stencil_attachment; + if (!ds_att) continue; imgv = get_attachment(state, ds_att->attachment); } diff --git a/src/gallium/frontends/lavapipe/lvp_pass.c b/src/gallium/frontends/lavapipe/lvp_pass.c index 19799eb..3e5cbe3 100644 --- a/src/gallium/frontends/lavapipe/lvp_pass.c +++ b/src/gallium/frontends/lavapipe/lvp_pass.c @@ -25,81 +25,6 @@ #include "vk_util.h" -static void -lvp_render_pass_compile(struct lvp_render_pass *pass) -{ - for (uint32_t i = 0; i < pass->subpass_count; i++) { - struct lvp_subpass *subpass = &pass->subpasses[i]; - - for (uint32_t j = 0; j < subpass->attachment_count; j++) { - struct lvp_subpass_attachment *subpass_att = - &subpass->attachments[j]; - if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) - continue; - - struct lvp_render_pass_attachment *pass_att = - &pass->attachments[subpass_att->attachment]; - - pass_att->first_subpass_idx = UINT32_MAX; - } - } - - for (uint32_t i = 0; i < pass->subpass_count; i++) { - struct lvp_subpass *subpass = &pass->subpasses[i]; - - /* We don't allow depth_stencil_attachment to be non-NULL and - * be VK_ATTACHMENT_UNUSED. This way something can just check - * for NULL and be guaranteed that they have a valid - * attachment. - */ - if (subpass->depth_stencil_attachment && - subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED) - subpass->depth_stencil_attachment = NULL; - - if (subpass->ds_resolve_attachment && - subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED) - subpass->ds_resolve_attachment = NULL; - - for (uint32_t j = 0; j < subpass->attachment_count; j++) { - struct lvp_subpass_attachment *subpass_att = - &subpass->attachments[j]; - if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) - continue; - - struct lvp_render_pass_attachment *pass_att = - &pass->attachments[subpass_att->attachment]; - - if (i < pass_att->first_subpass_idx) - pass_att->first_subpass_idx = i; - pass_att->last_subpass_idx = i; - } - - subpass->has_color_att = false; - for (uint32_t j = 0; j < subpass->color_count; j++) { - struct lvp_subpass_attachment *subpass_att = - &subpass->color_attachments[j]; - if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) - continue; - - subpass->has_color_att = true; - } - - /* We have to handle resolve attachments specially */ - subpass->has_color_resolve = false; - if (subpass->resolve_attachments) { - for (uint32_t j = 0; j < subpass->color_count; j++) { - struct lvp_subpass_attachment *resolve_att = - &subpass->resolve_attachments[j]; - - if (resolve_att->attachment == VK_ATTACHMENT_UNUSED) - continue; - - subpass->has_color_resolve = true; - } - } - } -} - static unsigned lvp_num_subpass_attachments2(const VkSubpassDescription2 *desc) { @@ -124,12 +49,19 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass2( size_t attachments_offset; size_t size; + uint32_t subpass_attachment_count = 0; + for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { + subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); + } + size = sizeof(*pass); size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]); attachments_offset = size; size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]); + uint32_t subpass_attachment_offset = size; + size += subpass_attachment_count * sizeof(void*); - pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, + pass = vk_zalloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (pass == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -152,98 +84,86 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass2( att->samples = pCreateInfo->pAttachments[i].samples; att->load_op = pCreateInfo->pAttachments[i].loadOp; att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; - att->first_subpass_idx = UINT32_MAX; att->attachment = i; bool is_zs = util_format_is_depth_or_stencil(lvp_vk_format_to_pipe_format(att->format)); pass->has_zs_attachment |= is_zs; pass->has_color_attachment |= !is_zs; } - uint32_t subpass_attachment_count = 0; - for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); - } - if (subpass_attachment_count) { - pass->subpass_attachments = - vk_alloc2(&device->vk.alloc, pAllocator, - subpass_attachment_count * sizeof(struct lvp_subpass_attachment), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pass->subpass_attachments == NULL) { - vk_free2(&device->vk.alloc, pAllocator, pass); - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - } - } else - pass->subpass_attachments = NULL; + uint32_t subpass_attachment_idx = 0; +#define ATTACHMENT_OFFSET (struct lvp_render_pass_attachment**)(((uint8_t*)pass) + subpass_attachment_offset + (subpass_attachment_idx * sizeof(void*))) +#define CHECK_UNUSED_ATTACHMENT(SRC, DST, IDX) do { \ + if (desc->SRC[IDX].attachment == VK_ATTACHMENT_UNUSED) \ + subpass->DST[IDX] = NULL; \ + else \ + subpass->DST[IDX] = &pass->attachments[desc->SRC[IDX].attachment]; \ + } while (0) - struct lvp_subpass_attachment *p = pass->subpass_attachments; for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; struct lvp_subpass *subpass = &pass->subpasses[i]; subpass->input_count = desc->inputAttachmentCount; subpass->color_count = desc->colorAttachmentCount; - subpass->attachment_count = lvp_num_subpass_attachments2(desc); - subpass->attachments = p; subpass->view_mask = desc->viewMask; + subpass->has_color_resolve = false; if (desc->inputAttachmentCount > 0) { - subpass->input_attachments = p; - p += desc->inputAttachmentCount; + subpass->input_attachments = ATTACHMENT_OFFSET; + subpass_attachment_idx += desc->inputAttachmentCount; for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { - subpass->input_attachments[j] = (struct lvp_subpass_attachment) { - .attachment = desc->pInputAttachments[j].attachment, - }; + CHECK_UNUSED_ATTACHMENT(pInputAttachments, input_attachments, j); } } if (desc->colorAttachmentCount > 0) { - subpass->color_attachments = p; - p += desc->colorAttachmentCount; + subpass->color_attachments = ATTACHMENT_OFFSET; + subpass_attachment_idx += desc->colorAttachmentCount; for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { - subpass->color_attachments[j] = (struct lvp_subpass_attachment) { - .attachment = desc->pColorAttachments[j].attachment, - }; + CHECK_UNUSED_ATTACHMENT(pColorAttachments, color_attachments, j); + if (subpass->color_attachments[j]) + subpass->has_color_att = true; } } if (desc->pResolveAttachments) { - subpass->resolve_attachments = p; - p += desc->colorAttachmentCount; + subpass->resolve_attachments = ATTACHMENT_OFFSET; + subpass_attachment_idx += desc->colorAttachmentCount; for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { - subpass->resolve_attachments[j] = (struct lvp_subpass_attachment) { - .attachment = desc->pResolveAttachments[j].attachment, - }; + CHECK_UNUSED_ATTACHMENT(pResolveAttachments, resolve_attachments, j); + if (subpass->resolve_attachments[j]) + subpass->has_color_resolve = true; } } if (desc->pDepthStencilAttachment) { - subpass->depth_stencil_attachment = p++; + subpass->depth_stencil_attachment = ATTACHMENT_OFFSET; + subpass_attachment_idx++; - *subpass->depth_stencil_attachment = (struct lvp_subpass_attachment) { - .attachment = desc->pDepthStencilAttachment->attachment, - }; + CHECK_UNUSED_ATTACHMENT(pDepthStencilAttachment, depth_stencil_attachment, 0); } const VkSubpassDescriptionDepthStencilResolve *ds_resolve = vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE); if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) { - subpass->ds_resolve_attachment = p++; + subpass->ds_resolve_attachment = ATTACHMENT_OFFSET; + subpass_attachment_idx++; - *subpass->ds_resolve_attachment = (struct lvp_subpass_attachment){ - .attachment = ds_resolve->pDepthStencilResolveAttachment->attachment, - }; + if (ds_resolve->pDepthStencilResolveAttachment->attachment == VK_ATTACHMENT_UNUSED) + *subpass->ds_resolve_attachment = NULL; + else + *subpass->ds_resolve_attachment = &pass->attachments[ds_resolve->pDepthStencilResolveAttachment->attachment]; subpass->depth_resolve_mode = ds_resolve->depthResolveMode; subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode; } } - - lvp_render_pass_compile(pass); +#undef ATTACHMENT_OFFSET *pRenderPass = lvp_render_pass_to_handle(pass); return VK_SUCCESS; diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index afa5d07..bb05a2a 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -259,21 +259,22 @@ struct lvp_image_view { struct pipe_surface *surface; /* have we created a pipe surface for this? */ }; -struct lvp_subpass_attachment { - uint32_t attachment; +struct lvp_render_pass_attachment { + uint32_t attachment; //index + VkFormat format; + uint32_t samples; + VkAttachmentLoadOp load_op; + VkAttachmentLoadOp stencil_load_op; }; struct lvp_subpass { - uint32_t attachment_count; - struct lvp_subpass_attachment * attachments; - uint32_t input_count; uint32_t color_count; - struct lvp_subpass_attachment * input_attachments; - struct lvp_subpass_attachment * color_attachments; - struct lvp_subpass_attachment * resolve_attachments; - struct lvp_subpass_attachment * depth_stencil_attachment; - struct lvp_subpass_attachment * ds_resolve_attachment; + struct lvp_render_pass_attachment ** input_attachments; + struct lvp_render_pass_attachment ** color_attachments; + struct lvp_render_pass_attachment ** resolve_attachments; + struct lvp_render_pass_attachment ** depth_stencil_attachment; + struct lvp_render_pass_attachment ** ds_resolve_attachment; VkResolveModeFlagBits depth_resolve_mode; VkResolveModeFlagBits stencil_resolve_mode; @@ -286,18 +287,6 @@ struct lvp_subpass { uint32_t view_mask; }; -struct lvp_render_pass_attachment { - uint32_t attachment; //index - VkFormat format; - uint32_t samples; - VkAttachmentLoadOp load_op; - VkAttachmentLoadOp stencil_load_op; - - /* The subpass id in which the attachment will be used first/last. */ - uint32_t first_subpass_idx; - uint32_t last_subpass_idx; -}; - struct lvp_render_pass { struct vk_object_base base; uint32_t attachment_count; -- 2.7.4