zink: use c++ template to deduplicate all the buffer barrier code

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22057>
This commit is contained in:
Mike Blumenkrantz
2023-03-21 10:38:51 -04:00
committed by Marge Bot
parent bf0af0f8ed
commit 60af511fc6
3 changed files with 57 additions and 127 deletions
+2
View File
@@ -130,6 +130,8 @@ zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_r
bool
zink_resource_buffer_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned offset, unsigned size);
void
zink_synchronization_init(struct zink_screen *screen);
void
zink_update_descriptor_refs(struct zink_context *ctx, bool compute);
void
zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc);
+1 -2
View File
@@ -3031,12 +3031,11 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->base.vertex_state_destroy = zink_cache_vertex_state_destroy;
glsl_type_singleton_init_or_ref();
zink_synchronization_init(screen);
if (screen->info.have_vulkan13 || screen->info.have_KHR_synchronization2) {
screen->image_barrier = zink_resource_image_barrier2;
screen->buffer_barrier = zink_resource_buffer_barrier2;
} else {
screen->image_barrier = zink_resource_image_barrier;
screen->buffer_barrier = zink_resource_buffer_barrier;
}
zink_init_screen_pipeline_libs(screen);
+54 -125
View File
@@ -524,6 +524,7 @@ buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flags, VkPipelineS
((unordered ? res->obj->unordered_access : res->obj->access) & flags) != flags;
}
template <bool HAS_SYNC2>
void
zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
{
@@ -570,17 +571,6 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res
bool can_skip_ordered = unordered ? false : (!res->obj->access && !unordered_usage_matches);
if (!can_skip_unordered && !can_skip_ordered) {
VkMemoryBarrier bmb;
bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
bmb.pNext = NULL;
VkPipelineStageFlags stages = res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access);;
if (unordered) {
stages = usage_matches ? res->obj->unordered_access_stage : stages;
bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
} else {
bmb.srcAccessMask = res->obj->access;
}
VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
bool marker = false;
if (unlikely(zink_tracing)) {
@@ -595,15 +585,54 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res
}
marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "buffer_barrier(%s)", buf);
}
VKCTX(CmdPipelineBarrier)(
cmdbuf,
stages,
pipeline,
0,
1, &bmb,
0, NULL,
0, NULL
);
VkPipelineStageFlags stages = res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access);;
if (HAS_SYNC2) {
VkMemoryBarrier2 bmb;
bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
bmb.pNext = NULL;
if (unordered) {
bmb.srcStageMask = usage_matches ? res->obj->unordered_access_stage : stages;
bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
} else {
bmb.srcStageMask = stages;
bmb.srcAccessMask = res->obj->access;
}
bmb.dstStageMask = pipeline;
bmb.dstAccessMask = flags;
VkDependencyInfo dep = {
VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
NULL,
0,
1,
&bmb,
0,
NULL,
0,
NULL
};
VKCTX(CmdPipelineBarrier2)(cmdbuf, &dep);
} else {
VkMemoryBarrier bmb;
bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
bmb.pNext = NULL;
if (unordered) {
stages = usage_matches ? res->obj->unordered_access_stage : stages;
bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
} else {
bmb.srcAccessMask = res->obj->access;
}
VKCTX(CmdPipelineBarrier)(
cmdbuf,
stages,
pipeline,
0,
1, &bmb,
0, NULL,
0, NULL
);
}
zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
}
@@ -630,111 +659,11 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res
}
void
zink_resource_buffer_barrier2(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
zink_synchronization_init(struct zink_screen *screen)
{
if (!pipeline)
pipeline = pipeline_access_stage(flags);
bool is_write = zink_resource_access_is_write(flags);
bool unordered = unordered_res_exec(ctx, res, is_write);
if (!buffer_needs_barrier(res, flags, pipeline, unordered))
return;
enum zink_resource_access rw = is_write ? ZINK_RESOURCE_ACCESS_RW : ZINK_RESOURCE_ACCESS_WRITE;
bool completed = zink_resource_usage_check_completion_fast(zink_screen(ctx->base.screen), res, rw);
bool usage_matches = !completed && zink_resource_usage_matches(res, ctx->batch.state);
bool unordered_usage_matches = res->obj->unordered_access && usage_matches;
if (completed) {
/* reset access on complete */
res->obj->access = VK_ACCESS_NONE;
res->obj->access_stage = VK_PIPELINE_STAGE_NONE;
res->obj->last_write = VK_ACCESS_NONE;
} else if (unordered && unordered_usage_matches && res->obj->ordered_access_is_copied) {
/* always reset propagated access to avoid weirdness */
res->obj->access = VK_ACCESS_NONE;
res->obj->access_stage = VK_PIPELINE_STAGE_NONE;
} else if (!unordered && !unordered_usage_matches) {
/* reset unordered access on first ordered barrier */
res->obj->unordered_access = VK_ACCESS_NONE;
res->obj->unordered_access_stage = VK_PIPELINE_STAGE_NONE;
if (screen->info.have_vulkan13 || screen->info.have_KHR_synchronization2) {
screen->buffer_barrier = zink_resource_buffer_barrier<true>;
} else {
screen->buffer_barrier = zink_resource_buffer_barrier<false>;
}
if (!usage_matches) {
/* reset unordered on first new cmdbuf barrier */
res->obj->unordered_access = VK_ACCESS_NONE;
res->obj->unordered_access_stage = VK_PIPELINE_STAGE_NONE;
res->obj->ordered_access_is_copied = false;
}
/* unordered barriers can be skipped if either:
* - there is no current-batch unordered access
* - the unordered access is not write access
*/
bool can_skip_unordered = !unordered ? false : (!unordered_usage_matches || !zink_resource_access_is_write(res->obj->unordered_access));
/* ordered barriers can be skipped if both:
* - there is no current access
* - there is no current-batch unordered access
*/
bool can_skip_ordered = unordered ? false : (!res->obj->access && !unordered_usage_matches);
if (!can_skip_unordered && !can_skip_ordered) {
VkMemoryBarrier2 bmb;
bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
bmb.pNext = NULL;
VkPipelineStageFlags stages = res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access);;
if (unordered) {
bmb.srcStageMask = usage_matches ? res->obj->unordered_access_stage : stages;
bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
} else {
bmb.srcStageMask = stages;
bmb.srcAccessMask = res->obj->access;
}
bmb.dstStageMask = pipeline;
bmb.dstAccessMask = flags;
VkDependencyInfo dep = {
VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
NULL,
0,
1,
&bmb,
0,
NULL,
0,
NULL
};
VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
bool marker = false;
if (unlikely(zink_tracing)) {
char buf[4096];
bool first = true;
unsigned idx = 0;
u_foreach_bit64(bit, flags) {
if (!first)
buf[idx++] = '|';
idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s", vk_AccessFlagBits_to_str((VkAccessFlagBits)(1ul<<bit)));
first = false;
}
marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "buffer_barrier(%s)", buf);
}
VKCTX(CmdPipelineBarrier2)(cmdbuf, &dep);
zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
}
resource_check_defer_buffer_barrier(ctx, res, pipeline);
if (is_write)
res->obj->last_write = flags;
if (unordered) {
/* these should get automatically emitted during submission */
res->obj->unordered_access = flags;
res->obj->unordered_access_stage = pipeline;
if (is_write) {
ctx->batch.state->unordered_write_access |= flags;
ctx->batch.state->unordered_write_stages |= pipeline;
}
}
if (!unordered || !usage_matches || res->obj->ordered_access_is_copied) {
res->obj->access = flags;
res->obj->access_stage = pipeline;
res->obj->ordered_access_is_copied = unordered;
}
if (pipeline != VK_PIPELINE_STAGE_TRANSFER_BIT && is_write)
zink_resource_copies_reset(res);
}