diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c index 91e4efd4533..19a839850c0 100644 --- a/src/intel/vulkan/anv_pass.c +++ b/src/intel/vulkan/anv_pass.c @@ -445,3 +445,196 @@ void anv_GetRenderAreaGranularity( *pGranularity = (VkExtent2D) { 1, 1 }; } + +void +anv_dynamic_pass_init(struct anv_dynamic_render_pass *dyn_render_pass, + const struct anv_dynamic_pass_create_info *info) +{ + uint32_t att_count; + + att_count = info->colorAttachmentCount; + if ((info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) || + (info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)) + att_count++; + + struct anv_render_pass *pass = &dyn_render_pass->pass; + pass->attachment_count = att_count; + pass->subpass_count = 1; + pass->attachments = dyn_render_pass->rp_attachments; + + struct anv_subpass *subpass = &dyn_render_pass->subpass; + subpass->attachment_count = att_count; + subpass->attachments = dyn_render_pass->sp_attachments; + if (info->colorAttachmentCount > 0) { + subpass->color_count = info->colorAttachmentCount; + subpass->color_attachments = dyn_render_pass->sp_attachments; + } + subpass->view_mask = info->viewMask; + + uint32_t att; + for (att = 0; att < info->colorAttachmentCount; att++) { + if (info->pColorAttachmentFormats[att] == VK_FORMAT_UNDEFINED) + continue; + pass->attachments[att].format = info->pColorAttachmentFormats[att]; + pass->attachments[att].samples = info->rasterizationSamples; + subpass->attachments[att].attachment = att; + subpass->attachments[att].usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + + if ((info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) || + (info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)) { + pass->attachments[att].format = (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) ? info->depthAttachmentFormat : info->stencilAttachmentFormat; + pass->attachments[att].samples = info->rasterizationSamples; + subpass->attachments[att].attachment = att; + subpass->attachments[att].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + subpass->depth_stencil_attachment = &subpass->attachments[att]; + + att++; + } +} + +void +anv_dynamic_pass_init_full(struct anv_dynamic_render_pass *dyn_render_pass, + const VkRenderingInfoKHR *info) +{ + uint32_t att_count; + uint32_t color_count = 0, ds_count = 0; + uint32_t color_resolve_idx, ds_idx; + bool has_color_resolve, has_ds_resolve; + + struct anv_render_pass *pass = &dyn_render_pass->pass; + struct anv_subpass *subpass = &dyn_render_pass->subpass; + + /* We set some of the fields conditionally below, like + * subpass->ds_resolve_attachment. But the value of this field is used to + * trigger depth/stencil resolve, so clear things to make sure we don't + * leave stale values. + */ + memset(pass, 0, sizeof(*pass)); + memset(subpass, 0, sizeof(*subpass)); + + dyn_render_pass->suspending = info->flags & VK_RENDERING_SUSPENDING_BIT_KHR; + dyn_render_pass->resuming = info->flags & VK_RENDERING_RESUMING_BIT_KHR; + + color_count = info->colorAttachmentCount; + if ((info->pDepthAttachment && info->pDepthAttachment->imageView) || + (info->pStencilAttachment && info->pStencilAttachment->imageView)) + ds_count = 1; + + has_color_resolve = false; + has_ds_resolve = false; + for (uint32_t i = 0; i < info->colorAttachmentCount; i++) { + if (info->pColorAttachments[i].resolveMode != VK_RESOLVE_MODE_NONE) { + has_color_resolve = true; + break; + } + } + if (has_color_resolve) + color_count *= 2; + + has_ds_resolve = + ((info->pDepthAttachment && + info->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) || + (info->pStencilAttachment && + info->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE)); + if (has_ds_resolve) + ds_count *= 2; + + att_count = color_count + ds_count; + color_resolve_idx = info->colorAttachmentCount; + ds_idx = color_count; + + pass->subpass_count = 1; + pass->attachments = dyn_render_pass->rp_attachments; + pass->attachment_count = att_count; + + struct anv_subpass_attachment *subpass_attachments = + dyn_render_pass->sp_attachments; + subpass->attachment_count = att_count; + subpass->attachments = subpass_attachments; + subpass->color_count = info->colorAttachmentCount; + subpass->color_attachments = subpass_attachments; + subpass->has_color_resolve = has_color_resolve; + subpass->resolve_attachments = + subpass_attachments + subpass->color_count; + /* The depth field presence is used to trigger resolve/shadow-buffer-copy, + * only set them if needed. + */ + if (ds_count > 0) { + subpass->depth_stencil_attachment = &subpass_attachments[ds_idx]; + if (has_ds_resolve) + subpass->ds_resolve_attachment = &subpass_attachments[ds_idx + 1]; + } + subpass->view_mask = info->viewMask; + + for (uint32_t att = 0; att < info->colorAttachmentCount; att++) { + if (info->pColorAttachments[att].imageView == VK_NULL_HANDLE) { + subpass->color_attachments[att].attachment = VK_ATTACHMENT_UNUSED; + continue; + } + + ANV_FROM_HANDLE(anv_image_view, iview, info->pColorAttachments[att].imageView); + + pass->attachments[att] = (struct anv_render_pass_attachment) { + .format = iview->vk.format, + .samples = iview->vk.image->samples, + }; + + subpass->color_attachments[att] = (struct anv_subpass_attachment) { + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .attachment = att, + }; + + if (has_color_resolve) { + if (info->pColorAttachments[att].resolveMode == VK_RESOLVE_MODE_NONE) { + subpass->resolve_attachments[att].attachment = VK_ATTACHMENT_UNUSED; + continue; + } + + subpass->resolve_attachments[att] = (struct anv_subpass_attachment) { + .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .attachment = att + color_resolve_idx, + }; + } + } + + if (ds_count) { + /* Easier to reference for the stuff both have in common. */ + const VkRenderingAttachmentInfoKHR *d_att = info->pDepthAttachment; + const VkRenderingAttachmentInfoKHR *s_att = info->pStencilAttachment; + const VkRenderingAttachmentInfoKHR *d_or_s_att = d_att ? d_att : s_att; + VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE; + VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE; + + ANV_FROM_HANDLE(anv_image_view, iview, d_or_s_att->imageView); + + pass->attachments[ds_idx] = (struct anv_render_pass_attachment) { + .format = iview->vk.format, + .samples = iview->vk.image->samples, + }; + + *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) { + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .attachment = ds_idx, + }; + + if (d_att && d_att->imageView) { + depth_resolve_mode = d_att->resolveMode; + } + if (s_att && s_att->imageView) { + stencil_resolve_mode = s_att->resolveMode; + } + + if (has_ds_resolve) { + uint32_t ds_res_idx = ds_idx + 1; + + *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) { + .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .attachment = ds_res_idx, + }; + + subpass->depth_resolve_mode = depth_resolve_mode; + subpass->stencil_resolve_mode = stencil_resolve_mode; + } + } +} diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index bdb5391c157..fede8d6e531 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2912,6 +2912,103 @@ struct anv_cmd_ray_tracing_state { } scratch; }; +struct anv_framebuffer { + struct vk_object_base base; + + uint32_t width; + uint32_t height; + uint32_t layers; + + uint32_t attachment_count; + struct anv_image_view * attachments[0]; +}; + +struct anv_subpass_attachment { + VkImageUsageFlagBits usage; + uint32_t attachment; + VkImageLayout layout; + + /* Used only with attachment containing stencil data. */ + VkImageLayout stencil_layout; +}; + +struct anv_subpass { + uint32_t attachment_count; + + /** + * A pointer to all attachment references used in this subpass. + * Only valid if ::attachment_count > 0. + */ + struct anv_subpass_attachment * attachments; + uint32_t input_count; + struct anv_subpass_attachment * input_attachments; + uint32_t color_count; + struct anv_subpass_attachment * color_attachments; + struct anv_subpass_attachment * resolve_attachments; + + struct anv_subpass_attachment * depth_stencil_attachment; + struct anv_subpass_attachment * ds_resolve_attachment; + VkResolveModeFlagBitsKHR depth_resolve_mode; + VkResolveModeFlagBitsKHR stencil_resolve_mode; + + uint32_t view_mask; + + /** Subpass has a depth/stencil self-dependency */ + bool has_ds_self_dep; + + /** Subpass has at least one color resolve attachment */ + bool has_color_resolve; +}; + +struct anv_render_pass_attachment { + /* TODO: Consider using VkAttachmentDescription instead of storing each of + * its members individually. + */ + VkFormat format; + uint32_t samples; + VkImageUsageFlags usage; + VkAttachmentLoadOp load_op; + VkAttachmentStoreOp store_op; + VkAttachmentLoadOp stencil_load_op; + VkImageLayout initial_layout; + VkImageLayout final_layout; + VkImageLayout first_subpass_layout; + + VkImageLayout stencil_initial_layout; + VkImageLayout stencil_final_layout; + + /* The subpass id in which the attachment will be used last. */ + uint32_t last_subpass_idx; +}; + +struct anv_render_pass { + struct vk_object_base base; + + uint32_t attachment_count; + uint32_t subpass_count; + /* An array of subpass_count+1 flushes, one per subpass boundary */ + enum anv_pipe_bits * subpass_flushes; + struct anv_render_pass_attachment * attachments; + struct anv_subpass subpasses[0]; +}; + +/* RTs * 2 (for resolve attachments) + * depth/sencil * 2 + */ +#define MAX_DYN_RENDER_ATTACHMENTS (MAX_RTS * 2 + 2 * 2) + +/* And this, kids, is what we call a nasty hack. */ +struct anv_dynamic_render_pass { + struct anv_render_pass pass; + struct anv_subpass subpass; + struct anv_framebuffer framebuffer; + struct anv_render_pass_attachment rp_attachments[MAX_DYN_RENDER_ATTACHMENTS]; + struct anv_subpass_attachment sp_attachments[MAX_DYN_RENDER_ATTACHMENTS]; + + bool suspending; + bool resuming; +}; + /** State required while building cmd buffer */ struct anv_cmd_state { /* PIPELINE_SELECT.PipelineSelection */ @@ -4369,92 +4466,12 @@ struct anv_sampler { struct anv_state custom_border_color; }; -struct anv_framebuffer { - struct vk_object_base base; - - uint32_t width; - uint32_t height; - uint32_t layers; - - uint32_t attachment_count; - struct anv_image_view * attachments[0]; -}; - -struct anv_subpass_attachment { - VkImageUsageFlagBits usage; - uint32_t attachment; - VkImageLayout layout; - - /* Used only with attachment containing stencil data. */ - VkImageLayout stencil_layout; -}; - -struct anv_subpass { - uint32_t attachment_count; - - /** - * A pointer to all attachment references used in this subpass. - * Only valid if ::attachment_count > 0. - */ - struct anv_subpass_attachment * attachments; - uint32_t input_count; - struct anv_subpass_attachment * input_attachments; - uint32_t color_count; - struct anv_subpass_attachment * color_attachments; - struct anv_subpass_attachment * resolve_attachments; - - struct anv_subpass_attachment * depth_stencil_attachment; - struct anv_subpass_attachment * ds_resolve_attachment; - VkResolveModeFlagBitsKHR depth_resolve_mode; - VkResolveModeFlagBitsKHR stencil_resolve_mode; - - uint32_t view_mask; - - /** Subpass has a depth/stencil self-dependency */ - bool has_ds_self_dep; - - /** Subpass has at least one color resolve attachment */ - bool has_color_resolve; -}; - static inline unsigned anv_subpass_view_count(const struct anv_subpass *subpass) { return MAX2(1, util_bitcount(subpass->view_mask)); } -struct anv_render_pass_attachment { - /* TODO: Consider using VkAttachmentDescription instead of storing each of - * its members individually. - */ - VkFormat format; - uint32_t samples; - VkImageUsageFlags usage; - VkAttachmentLoadOp load_op; - VkAttachmentStoreOp store_op; - VkAttachmentLoadOp stencil_load_op; - VkImageLayout initial_layout; - VkImageLayout final_layout; - VkImageLayout first_subpass_layout; - - VkImageLayout stencil_initial_layout; - VkImageLayout stencil_final_layout; - - /* The subpass id in which the attachment will be used last. */ - uint32_t last_subpass_idx; -}; - -struct anv_render_pass { - struct vk_object_base base; - - uint32_t attachment_count; - uint32_t subpass_count; - /* An array of subpass_count+1 flushes, one per subpass boundary */ - enum anv_pipe_bits * subpass_flushes; - struct anv_render_pass_attachment * attachments; - struct anv_subpass subpasses[0]; -}; - #define ANV_PIPELINE_STATISTICS_MASK 0x000007ff struct anv_query_pool { @@ -4478,6 +4495,22 @@ struct anv_query_pool { struct intel_perf_query_info **pass_query; }; +struct anv_dynamic_pass_create_info { + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +}; + +void +anv_dynamic_pass_init(struct anv_dynamic_render_pass *dyn_render_pass, + const struct anv_dynamic_pass_create_info *info); +void +anv_dynamic_pass_init_full(struct anv_dynamic_render_pass *dyn_render_pass, + const VkRenderingInfoKHR *info); + static inline uint32_t khr_perf_query_preamble_offset(const struct anv_query_pool *pool, uint32_t pass) {