v3dv: compute subpass ranges for attachments at render pass creation time

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga
2020-01-28 16:53:54 +01:00
committed by Marge Bot
parent a7a402c8bd
commit df34b8fac6
3 changed files with 55 additions and 73 deletions
+16 -71
View File
@@ -613,55 +613,10 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
}
}
/* Identifies the first and last subpasses that use each attachment in
* the current render pass.
*
* FIXME: consider doing this at render pass creation time and store it
* in the render pass data.
*/
static void
cmd_buffer_find_subpass_range_for_attachments(struct v3dv_cmd_buffer *cmd_buffer)
{
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_render_pass *pass = state->pass;
for (uint32_t i = 0; i < pass->attachment_count; i++) {
state->attachments[i].first_subpass = pass->subpass_count - 1;
state->attachments[i].last_subpass = 0;
}
for (uint32_t i = 0; i < pass->subpass_count; i++) {
const struct v3dv_subpass *subpass = &pass->subpasses[i];
for (uint32_t j = 0; j < subpass->color_count; j++) {
uint32_t attachment_idx = subpass->color_attachments[j].attachment;
if (attachment_idx == VK_ATTACHMENT_UNUSED)
continue;
if (i < state->attachments[attachment_idx].first_subpass)
state->attachments[attachment_idx].first_subpass = i;
if (i > state->attachments[attachment_idx].last_subpass)
state->attachments[attachment_idx].last_subpass = i;
}
uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
if (i < state->attachments[ds_attachment_idx].first_subpass)
state->attachments[ds_attachment_idx].first_subpass = i;
if (i > state->attachments[ds_attachment_idx].last_subpass)
state->attachments[ds_attachment_idx].last_subpass = i;
}
/* FIXME: input/resolve attachments */
}
}
static void
cmd_buffer_init_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffer,
const VkRenderPassBeginInfo *pRenderPassBegin)
{
cmd_buffer_find_subpass_range_for_attachments(cmd_buffer);
cmd_buffer_state_set_clear_values(cmd_buffer,
pRenderPassBegin->clearValueCount,
pRenderPassBegin->pClearValues);
@@ -801,8 +756,8 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
{
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
const struct v3dv_subpass *subpass =
&state->pass->subpasses[state->subpass_idx];
const struct v3dv_render_pass *pass = state->pass;
const struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx];
for (uint32_t i = 0; i < subpass->color_count; i++) {
uint32_t attachment_idx = subpass->color_attachments[i].attachment;
@@ -813,9 +768,6 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
const struct v3dv_render_pass_attachment *attachment =
&state->pass->attachments[attachment_idx];
const struct v3dv_cmd_buffer_attachment_state *attachment_state =
&state->attachments[attachment_idx];
/* According to the Vulkan spec:
*
* "The load operation for each sample in an attachment happens before
@@ -827,9 +779,9 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
* After that, we always want to load so we don't lose any rendering done
* by a previous subpass to the same attachment.
*/
assert(state->job->first_subpass >= attachment_state->first_subpass);
assert(state->job->first_subpass >= attachment->first_subpass);
bool needs_load =
state->job->first_subpass > attachment_state->first_subpass ||
state->job->first_subpass > attachment->first_subpass ||
attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD;
if (needs_load) {
@@ -843,12 +795,10 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
const struct v3dv_render_pass_attachment *ds_attachment =
&state->pass->attachments[ds_attachment_idx];
const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
&state->attachments[ds_attachment_idx];
assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
assert(state->job->first_subpass >= ds_attachment->first_subpass);
bool needs_load =
state->job->first_subpass > ds_attachment_state->first_subpass ||
state->job->first_subpass > ds_attachment->first_subpass ||
ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD;
if (needs_load) {
@@ -920,21 +870,18 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
const struct v3dv_render_pass_attachment *attachment =
&state->pass->attachments[attachment_idx];
const struct v3dv_cmd_buffer_attachment_state *attachment_state =
&state->attachments[attachment_idx];
assert(state->job->first_subpass >= attachment_state->first_subpass);
assert(state->subpass_idx >= attachment_state->first_subpass);
assert(state->subpass_idx <= attachment_state->last_subpass);
assert(state->job->first_subpass >= attachment->first_subpass);
assert(state->subpass_idx >= attachment->first_subpass);
assert(state->subpass_idx <= attachment->last_subpass);
/* Only clear once on the first subpass that uses the attachment */
bool needs_clear =
state->job->first_subpass == attachment_state->first_subpass &&
state->job->first_subpass == attachment->first_subpass &&
attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
/* Skip the last store if it is not required */
bool needs_store =
state->subpass_idx < attachment_state->last_subpass ||
state->subpass_idx < attachment->last_subpass ||
attachment->desc.storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
needs_clear;
@@ -965,21 +912,19 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
const struct v3dv_render_pass_attachment *ds_attachment =
&state->pass->attachments[ds_attachment_idx];
const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
&state->attachments[ds_attachment_idx];
assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
assert(state->subpass_idx >= ds_attachment_state->first_subpass);
assert(state->subpass_idx <= ds_attachment_state->last_subpass);
assert(state->job->first_subpass >= ds_attachment->first_subpass);
assert(state->subpass_idx >= ds_attachment->first_subpass);
assert(state->subpass_idx <= ds_attachment->last_subpass);
/* Only clear once on the first subpass that uses the attachment */
needs_ds_clear =
state->job->first_subpass == ds_attachment_state->first_subpass &&
state->job->first_subpass == ds_attachment->first_subpass &&
ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
/* Skip the last store if it is not required */
bool needs_ds_store =
state->subpass_idx < ds_attachment_state->last_subpass ||
state->subpass_idx < ds_attachment->last_subpass ||
ds_attachment->desc.storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
needs_ds_clear;
+37
View File
@@ -32,6 +32,41 @@ num_subpass_attachments(const VkSubpassDescription *desc)
(desc->pDepthStencilAttachment != NULL);
}
static void
pass_find_subpass_range_for_attachments(struct v3dv_render_pass *pass)
{
for (uint32_t i = 0; i < pass->attachment_count; i++) {
pass->attachments[i].first_subpass = pass->subpass_count - 1;
pass->attachments[i].last_subpass = 0;
}
for (uint32_t i = 0; i < pass->subpass_count; i++) {
const struct v3dv_subpass *subpass = &pass->subpasses[i];
for (uint32_t j = 0; j < subpass->color_count; j++) {
uint32_t attachment_idx = subpass->color_attachments[j].attachment;
if (attachment_idx == VK_ATTACHMENT_UNUSED)
continue;
if (i < pass->attachments[attachment_idx].first_subpass)
pass->attachments[attachment_idx].first_subpass = i;
if (i > pass->attachments[attachment_idx].last_subpass)
pass->attachments[attachment_idx].last_subpass = i;
}
uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
if (i < pass->attachments[ds_attachment_idx].first_subpass)
pass->attachments[ds_attachment_idx].first_subpass = i;
if (i > pass->attachments[ds_attachment_idx].last_subpass)
pass->attachments[ds_attachment_idx].last_subpass = i;
}
/* FIXME: input/resolve attachments */
}
}
VkResult
v3dv_CreateRenderPass(VkDevice _device,
const VkRenderPassCreateInfo *pCreateInfo,
@@ -137,6 +172,8 @@ v3dv_CreateRenderPass(VkDevice _device,
}
}
pass_find_subpass_range_for_attachments(pass);
/* FIXME: handle subpass dependencies */
*pRenderPass = v3dv_render_pass_to_handle(pass);
+2 -2
View File
@@ -358,6 +358,8 @@ struct v3dv_subpass {
struct v3dv_render_pass_attachment {
VkAttachmentDescription desc;
uint32_t first_subpass;
uint32_t last_subpass;
};
struct v3dv_render_pass {
@@ -412,8 +414,6 @@ union v3dv_clear_value {
struct v3dv_cmd_buffer_attachment_state {
union v3dv_clear_value clear_value;
uint32_t first_subpass;
uint32_t last_subpass;
};
struct v3dv_viewport_state {