v3dv: use an explicit struct type to track barrier state

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16743>
This commit is contained in:
Iago Toral Quiroga
2022-05-30 08:31:17 +02:00
committed by Marge Bot
parent eccc0e6a0b
commit f7ce42636c
3 changed files with 56 additions and 75 deletions

View File

@@ -595,9 +595,9 @@ v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer)
* a barrier involving geometry stages but none of the draw calls in the
* job actually required a binning sync.
*/
if (!(cmd_buffer->state.barrier.active_mask & V3DV_BARRIER_GRAPHICS_BIT)) {
cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0;
cmd_buffer->state.barrier.bcl_barrier_image_access = 0;
if (!(cmd_buffer->state.barrier.dst_mask & V3DV_BARRIER_GRAPHICS_BIT)) {
cmd_buffer->state.barrier.bcl_buffer_access = 0;
cmd_buffer->state.barrier.bcl_image_access = 0;
}
if (cmd_buffer->state.oom) {
@@ -683,7 +683,7 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer,
if (!v3dv_job_type_is_gpu(job))
return;
uint8_t barrier_mask = cmd_buffer->state.barrier.active_mask;
uint8_t barrier_mask = cmd_buffer->state.barrier.dst_mask;
if (barrier_mask == 0)
return;
@@ -704,7 +704,7 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer,
if (barrier_mask & bit) {
job->serialize = true;
cmd_buffer->state.barrier.active_mask &= ~bit;
cmd_buffer->state.barrier.dst_mask &= ~bit;
}
}
@@ -1680,9 +1680,7 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary,
uint32_t cmd_buffer_count,
const VkCommandBuffer *cmd_buffers)
{
uint8_t pending_barrier = 0;
VkAccessFlags pending_bcl_barrier_buffer_access = 0;
VkAccessFlags pending_bcl_barrier_image_access = 0;
struct v3dv_barrier_state pending_barrier = { 0 };
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[i]);
@@ -1710,15 +1708,13 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary,
if (!job)
return;
if (pending_barrier) {
if (pending_barrier.dst_mask) {
job->serialize = true;
if (pending_bcl_barrier_buffer_access ||
pending_bcl_barrier_image_access) {
if (pending_barrier.bcl_buffer_access ||
pending_barrier.bcl_image_access) {
job->needs_bcl_sync = true;
}
pending_barrier = 0;
pending_bcl_barrier_buffer_access = 0;
pending_bcl_barrier_image_access = 0;
memset(&pending_barrier, 0, sizeof(pending_barrier));
}
}
@@ -1726,23 +1722,14 @@ cmd_buffer_execute_outside_pass(struct v3dv_cmd_buffer *primary,
* barrier state consumed with whatever comes after it (first job in
* the next secondary or the primary, if this was the last secondary).
*/
assert(secondary->state.barrier.active_mask ||
(!secondary->state.barrier.bcl_barrier_buffer_access &&
!secondary->state.barrier.bcl_barrier_image_access));
pending_barrier = secondary->state.barrier.active_mask;
pending_bcl_barrier_buffer_access =
secondary->state.barrier.bcl_barrier_buffer_access;
pending_bcl_barrier_image_access =
secondary->state.barrier.bcl_barrier_image_access;
assert(secondary->state.barrier.dst_mask ||
(!secondary->state.barrier.bcl_buffer_access &&
!secondary->state.barrier.bcl_image_access));
pending_barrier = secondary->state.barrier;
}
if (pending_barrier) {
primary->state.barrier.active_mask = pending_barrier;
primary->state.barrier.bcl_barrier_buffer_access |=
pending_bcl_barrier_buffer_access;
primary->state.barrier.bcl_barrier_image_access |=
pending_bcl_barrier_image_access;
}
if (pending_barrier.dst_mask)
primary->state.barrier = pending_barrier;
}
VKAPI_ATTR void VKAPI_CALL
@@ -2450,7 +2437,7 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer,
pipeline->shared_data->maps[BROADCOM_SHADER_GEOMETRY_BIN];
VkAccessFlags buffer_access =
cmd_buffer->state.barrier.bcl_barrier_buffer_access;
cmd_buffer->state.barrier.bcl_buffer_access;
if (buffer_access) {
/* Index buffer read */
if (indexed && (buffer_access & VK_ACCESS_INDEX_READ_BIT))
@@ -2499,7 +2486,7 @@ cmd_buffer_binning_sync_required(struct v3dv_cmd_buffer *cmd_buffer,
}
VkAccessFlags image_access =
cmd_buffer->state.barrier.bcl_barrier_image_access;
cmd_buffer->state.barrier.bcl_image_access;
if (image_access) {
/* Image load / store */
if (image_access & (VK_ACCESS_SHADER_READ_BIT |
@@ -2520,8 +2507,8 @@ static void
consume_bcl_sync(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_job *job)
{
job->needs_bcl_sync = true;
cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0;
cmd_buffer->state.barrier.bcl_barrier_image_access = 0;
cmd_buffer->state.barrier.bcl_buffer_access = 0;
cmd_buffer->state.barrier.bcl_image_access = 0;
}
void
@@ -2553,8 +2540,8 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
* to sync at the binning stage by testing if the binning shaders involved
* with the draw call require access to external resources.
*/
if (job->serialize && (cmd_buffer->state.barrier.bcl_barrier_buffer_access ||
cmd_buffer->state.barrier.bcl_barrier_image_access)) {
if (job->serialize && (cmd_buffer->state.barrier.bcl_buffer_access ||
cmd_buffer->state.barrier.bcl_image_access)) {
assert(!job->needs_bcl_sync);
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
if (cmd_buffer_binning_sync_required(cmd_buffer, pipeline,
@@ -2817,17 +2804,17 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
if (dstStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_COMPUTE_BIT;
cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_COMPUTE_BIT;
}
if (dstStageMask & (VK_PIPELINE_STAGE_TRANSFER_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_TRANSFER_BIT;
cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_TRANSFER_BIT;
}
if (dstStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_TRANSFER_BIT))) {
cmd_buffer->state.barrier.active_mask |= V3DV_BARRIER_GRAPHICS_BIT;
cmd_buffer->state.barrier.dst_mask |= V3DV_BARRIER_GRAPHICS_BIT;
if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
@@ -2838,18 +2825,18 @@ v3dv_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
for (int i = 0; i < memoryBarrierCount; i++) {
cmd_buffer->state.barrier.bcl_barrier_buffer_access |=
cmd_buffer->state.barrier.bcl_buffer_access |=
pMemoryBarriers[i].dstAccessMask;
cmd_buffer->state.barrier.bcl_barrier_image_access |=
cmd_buffer->state.barrier.bcl_image_access |=
pMemoryBarriers[i].dstAccessMask;
}
for (int i = 0; i < bufferBarrierCount; i++) {
cmd_buffer->state.barrier.bcl_barrier_buffer_access |=
cmd_buffer->state.barrier.bcl_buffer_access |=
pBufferBarriers[i].dstAccessMask;
}
for (int i = 0; i < imageBarrierCount; i++) {
if (pImageBarriers[i].oldLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
cmd_buffer->state.barrier.bcl_barrier_image_access |=
cmd_buffer->state.barrier.bcl_image_access |=
pImageBarriers[i].dstAccessMask;
}
}

View File

@@ -1197,6 +1197,17 @@ enum {
V3DV_BARRIER_TRANSFER_BIT = (1 << 2),
};
struct v3dv_barrier_state {
/* Mask of V3DV_BARRIER_* indicating where we consume a barrier. */
uint8_t dst_mask;
/* For graphics barriers, access masks involved. Used to decide if we need
* to execute a binning or render barrier.
*/
VkAccessFlags bcl_buffer_access;
VkAccessFlags bcl_image_access;
};
struct v3dv_cmd_buffer_state {
struct v3dv_render_pass *pass;
struct v3dv_framebuffer *framebuffer;
@@ -1261,12 +1272,7 @@ struct v3dv_cmd_buffer_state {
bool is_transfer;
/* Barrier state tracking */
struct {
uint8_t active_mask; /* Bitmask of V3DV_BARRIER_* */
/* Access flags relevant to decide about BCL barriers for CLs */
VkAccessFlags bcl_barrier_buffer_access;
VkAccessFlags bcl_barrier_image_access;
} barrier;
struct v3dv_barrier_state barrier;
/* Secondary command buffer state */
struct {

View File

@@ -1630,9 +1630,7 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary,
* pipelines used by the secondaries do, we need to re-start the primary
* job to enable MSAA. See cmd_buffer_restart_job_for_msaa_if_needed.
*/
uint8_t pending_barrier = false;
VkAccessFlags pending_bcl_barrier_buffer_access = 0;
VkAccessFlags pending_bcl_barrier_image_access = 0;
struct v3dv_barrier_state pending_barrier = { 0 };
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[i]);
@@ -1666,11 +1664,12 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary,
* branch?
*/
struct v3dv_job *primary_job = primary->state.job;
if (!primary_job || secondary_job->serialize || pending_barrier) {
if (!primary_job || secondary_job->serialize ||
pending_barrier.dst_mask) {
const bool needs_bcl_barrier =
secondary_job->needs_bcl_sync ||
pending_bcl_barrier_buffer_access ||
pending_bcl_barrier_image_access;
pending_barrier.bcl_buffer_access ||
pending_barrier.bcl_image_access;
primary_job =
cmd_buffer_subpass_split_for_barrier(primary,
@@ -1711,18 +1710,16 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary,
*/
v3dv_cmd_buffer_finish_job(primary);
v3dv_job_clone_in_cmd_buffer(secondary_job, primary);
if (pending_barrier) {
if (pending_barrier.dst_mask) {
secondary_job->serialize = true;
if (pending_bcl_barrier_buffer_access ||
pending_bcl_barrier_image_access) {
if (pending_barrier.bcl_buffer_access ||
pending_barrier.bcl_image_access) {
secondary_job->needs_bcl_sync = true;
}
}
}
pending_barrier = 0;
pending_bcl_barrier_buffer_access = 0;
pending_bcl_barrier_image_access = 0;
memset(&pending_barrier, 0, sizeof(pending_barrier));
}
/* If the secondary has recorded any vkCmdEndQuery commands, we need to
@@ -1734,24 +1731,15 @@ v3dX(cmd_buffer_execute_inside_pass)(struct v3dv_cmd_buffer *primary,
/* If this secondary had any pending barrier state we will need that
* barrier state consumed with whatever comes next in the primary.
*/
assert(secondary->state.barrier.active_mask ||
(!secondary->state.barrier.bcl_barrier_buffer_access &&
!secondary->state.barrier.bcl_barrier_image_access));
assert(secondary->state.barrier.dst_mask ||
(!secondary->state.barrier.bcl_buffer_access &&
!secondary->state.barrier.bcl_image_access));
pending_barrier = secondary->state.barrier.active_mask;
pending_bcl_barrier_buffer_access =
secondary->state.barrier.bcl_barrier_buffer_access;
pending_bcl_barrier_image_access =
secondary->state.barrier.bcl_barrier_image_access;
pending_barrier = secondary->state.barrier;
}
if (pending_barrier) {
primary->state.barrier.active_mask = pending_barrier;
primary->state.barrier.bcl_barrier_buffer_access |=
pending_bcl_barrier_buffer_access;
primary->state.barrier.bcl_barrier_image_access |=
pending_bcl_barrier_image_access;
}
if (pending_barrier.dst_mask)
primary->state.barrier = pending_barrier;
}
static void