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 * a barrier involving geometry stages but none of the draw calls in the
* job actually required a binning sync. * job actually required a binning sync.
*/ */
if (!(cmd_buffer->state.barrier.active_mask & V3DV_BARRIER_GRAPHICS_BIT)) { if (!(cmd_buffer->state.barrier.dst_mask & V3DV_BARRIER_GRAPHICS_BIT)) {
cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0; cmd_buffer->state.barrier.bcl_buffer_access = 0;
cmd_buffer->state.barrier.bcl_barrier_image_access = 0; cmd_buffer->state.barrier.bcl_image_access = 0;
} }
if (cmd_buffer->state.oom) { 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)) if (!v3dv_job_type_is_gpu(job))
return; 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) if (barrier_mask == 0)
return; return;
@ -704,7 +704,7 @@ cmd_buffer_serialize_job_if_needed(struct v3dv_cmd_buffer *cmd_buffer,
if (barrier_mask & bit) { if (barrier_mask & bit) {
job->serialize = true; 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, uint32_t cmd_buffer_count,
const VkCommandBuffer *cmd_buffers) const VkCommandBuffer *cmd_buffers)
{ {
uint8_t pending_barrier = 0; struct v3dv_barrier_state pending_barrier = { 0 };
VkAccessFlags pending_bcl_barrier_buffer_access = 0;
VkAccessFlags pending_bcl_barrier_image_access = 0;
for (uint32_t i = 0; i < cmd_buffer_count; i++) { for (uint32_t i = 0; i < cmd_buffer_count; i++) {
V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[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) if (!job)
return; return;
if (pending_barrier) { if (pending_barrier.dst_mask) {
job->serialize = true; job->serialize = true;
if (pending_bcl_barrier_buffer_access || if (pending_barrier.bcl_buffer_access ||
pending_bcl_barrier_image_access) { pending_barrier.bcl_image_access) {
job->needs_bcl_sync = true; job->needs_bcl_sync = true;
} }
pending_barrier = 0; memset(&pending_barrier, 0, sizeof(pending_barrier));
pending_bcl_barrier_buffer_access = 0;
pending_bcl_barrier_image_access = 0;
} }
} }
@ -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 * barrier state consumed with whatever comes after it (first job in
* the next secondary or the primary, if this was the last secondary). * the next secondary or the primary, if this was the last secondary).
*/ */
assert(secondary->state.barrier.active_mask || assert(secondary->state.barrier.dst_mask ||
(!secondary->state.barrier.bcl_barrier_buffer_access && (!secondary->state.barrier.bcl_buffer_access &&
!secondary->state.barrier.bcl_barrier_image_access)); !secondary->state.barrier.bcl_image_access));
pending_barrier = secondary->state.barrier.active_mask; pending_barrier = secondary->state.barrier;
pending_bcl_barrier_buffer_access =
secondary->state.barrier.bcl_barrier_buffer_access;
pending_bcl_barrier_image_access =
secondary->state.barrier.bcl_barrier_image_access;
} }
if (pending_barrier) { if (pending_barrier.dst_mask)
primary->state.barrier.active_mask = pending_barrier; primary->state.barrier = 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;
}
} }
VKAPI_ATTR void VKAPI_CALL 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]; pipeline->shared_data->maps[BROADCOM_SHADER_GEOMETRY_BIN];
VkAccessFlags buffer_access = VkAccessFlags buffer_access =
cmd_buffer->state.barrier.bcl_barrier_buffer_access; cmd_buffer->state.barrier.bcl_buffer_access;
if (buffer_access) { if (buffer_access) {
/* Index buffer read */ /* Index buffer read */
if (indexed && (buffer_access & VK_ACCESS_INDEX_READ_BIT)) 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 = VkAccessFlags image_access =
cmd_buffer->state.barrier.bcl_barrier_image_access; cmd_buffer->state.barrier.bcl_image_access;
if (image_access) { if (image_access) {
/* Image load / store */ /* Image load / store */
if (image_access & (VK_ACCESS_SHADER_READ_BIT | 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) consume_bcl_sync(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_job *job)
{ {
job->needs_bcl_sync = true; job->needs_bcl_sync = true;
cmd_buffer->state.barrier.bcl_barrier_buffer_access = 0; cmd_buffer->state.barrier.bcl_buffer_access = 0;
cmd_buffer->state.barrier.bcl_barrier_image_access = 0; cmd_buffer->state.barrier.bcl_image_access = 0;
} }
void 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 * to sync at the binning stage by testing if the binning shaders involved
* with the draw call require access to external resources. * with the draw call require access to external resources.
*/ */
if (job->serialize && (cmd_buffer->state.barrier.bcl_barrier_buffer_access || if (job->serialize && (cmd_buffer->state.barrier.bcl_buffer_access ||
cmd_buffer->state.barrier.bcl_barrier_image_access)) { cmd_buffer->state.barrier.bcl_image_access)) {
assert(!job->needs_bcl_sync); assert(!job->needs_bcl_sync);
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
if (cmd_buffer_binning_sync_required(cmd_buffer, 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 | if (dstStageMask & (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_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 | if (dstStageMask & (VK_PIPELINE_STAGE_TRANSFER_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_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 | if (dstStageMask & (~(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_TRANSFER_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 | if (dstStageMask & (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
VK_PIPELINE_STAGE_VERTEX_SHADER_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_GRAPHICS_BIT |
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
for (int i = 0; i < memoryBarrierCount; i++) { 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; pMemoryBarriers[i].dstAccessMask;
cmd_buffer->state.barrier.bcl_barrier_image_access |= cmd_buffer->state.barrier.bcl_image_access |=
pMemoryBarriers[i].dstAccessMask; pMemoryBarriers[i].dstAccessMask;
} }
for (int i = 0; i < bufferBarrierCount; i++) { 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; pBufferBarriers[i].dstAccessMask;
} }
for (int i = 0; i < imageBarrierCount; i++) { for (int i = 0; i < imageBarrierCount; i++) {
if (pImageBarriers[i].oldLayout != VK_IMAGE_LAYOUT_UNDEFINED) { 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; pImageBarriers[i].dstAccessMask;
} }
} }

View file

@ -1197,6 +1197,17 @@ enum {
V3DV_BARRIER_TRANSFER_BIT = (1 << 2), 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_cmd_buffer_state {
struct v3dv_render_pass *pass; struct v3dv_render_pass *pass;
struct v3dv_framebuffer *framebuffer; struct v3dv_framebuffer *framebuffer;
@ -1261,12 +1272,7 @@ struct v3dv_cmd_buffer_state {
bool is_transfer; bool is_transfer;
/* Barrier state tracking */ /* Barrier state tracking */
struct { struct v3dv_barrier_state barrier;
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;
/* Secondary command buffer state */ /* Secondary command buffer state */
struct { 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 * 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. * job to enable MSAA. See cmd_buffer_restart_job_for_msaa_if_needed.
*/ */
uint8_t pending_barrier = false; struct v3dv_barrier_state pending_barrier = { 0 };
VkAccessFlags pending_bcl_barrier_buffer_access = 0;
VkAccessFlags pending_bcl_barrier_image_access = 0;
for (uint32_t i = 0; i < cmd_buffer_count; i++) { for (uint32_t i = 0; i < cmd_buffer_count; i++) {
V3DV_FROM_HANDLE(v3dv_cmd_buffer, secondary, cmd_buffers[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? * branch?
*/ */
struct v3dv_job *primary_job = primary->state.job; 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 = const bool needs_bcl_barrier =
secondary_job->needs_bcl_sync || secondary_job->needs_bcl_sync ||
pending_bcl_barrier_buffer_access || pending_barrier.bcl_buffer_access ||
pending_bcl_barrier_image_access; pending_barrier.bcl_image_access;
primary_job = primary_job =
cmd_buffer_subpass_split_for_barrier(primary, 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_cmd_buffer_finish_job(primary);
v3dv_job_clone_in_cmd_buffer(secondary_job, primary); v3dv_job_clone_in_cmd_buffer(secondary_job, primary);
if (pending_barrier) { if (pending_barrier.dst_mask) {
secondary_job->serialize = true; secondary_job->serialize = true;
if (pending_bcl_barrier_buffer_access || if (pending_barrier.bcl_buffer_access ||
pending_bcl_barrier_image_access) { pending_barrier.bcl_image_access) {
secondary_job->needs_bcl_sync = true; secondary_job->needs_bcl_sync = true;
} }
} }
} }
pending_barrier = 0; memset(&pending_barrier, 0, sizeof(pending_barrier));
pending_bcl_barrier_buffer_access = 0;
pending_bcl_barrier_image_access = 0;
} }
/* If the secondary has recorded any vkCmdEndQuery commands, we need to /* 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 /* If this secondary had any pending barrier state we will need that
* barrier state consumed with whatever comes next in the primary. * barrier state consumed with whatever comes next in the primary.
*/ */
assert(secondary->state.barrier.active_mask || assert(secondary->state.barrier.dst_mask ||
(!secondary->state.barrier.bcl_barrier_buffer_access && (!secondary->state.barrier.bcl_buffer_access &&
!secondary->state.barrier.bcl_barrier_image_access)); !secondary->state.barrier.bcl_image_access));
pending_barrier = secondary->state.barrier.active_mask; pending_barrier = secondary->state.barrier;
pending_bcl_barrier_buffer_access =
secondary->state.barrier.bcl_barrier_buffer_access;
pending_bcl_barrier_image_access =
secondary->state.barrier.bcl_barrier_image_access;
} }
if (pending_barrier) { if (pending_barrier.dst_mask)
primary->state.barrier.active_mask = pending_barrier; primary->state.barrier = 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;
}
} }
static void static void