anv: add functions to set up fake render passes

There's two of them because they can be created from three points in the
code that provide different details and this is the least ugly way I
could think of for now.

v2: Avoid allocations (Lionel)

v3: Move definition closer to its usage (Lionel)

v4: (Lionel)
 - Simplify anv_dynamic_pass_init_full
 - Zero out pass/subpass to avoid stall pointers

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13980>
This commit is contained in:
Iván Briano 2021-11-04 12:26:26 -07:00
parent b18bc028ee
commit 73ed019bec
2 changed files with 306 additions and 80 deletions

View File

@ -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;
}
}
}

View File

@ -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)
{