pvr: Handle pipeline barrier vk_sync.
Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19110>
This commit is contained in:
@@ -226,6 +226,7 @@ ForEachMacros: [
|
||||
'nir_foreach_use',
|
||||
'nir_foreach_use_safe',
|
||||
'nir_foreach_variable_with_modes',
|
||||
'u_foreach_bit',
|
||||
'u_vector_foreach',
|
||||
'util_dynarray_foreach',
|
||||
'vk_foreach_struct',
|
||||
|
@@ -1667,6 +1667,7 @@ static VkResult pvr_cmd_buffer_start_sub_cmd(struct pvr_cmd_buffer *cmd_buffer,
|
||||
|
||||
pvr_cmd_buffer_update_barriers(cmd_buffer, type);
|
||||
|
||||
/* TODO: Add proper support for joining consecutive event sub_cmd? */
|
||||
if (state->current_sub_cmd) {
|
||||
if (state->current_sub_cmd->type == type) {
|
||||
/* Continue adding to the current sub command. */
|
||||
@@ -1729,7 +1730,6 @@ static VkResult pvr_cmd_buffer_start_sub_cmd(struct pvr_cmd_buffer *cmd_buffer,
|
||||
break;
|
||||
|
||||
case PVR_SUB_CMD_TYPE_EVENT:
|
||||
/* TODO: Add support for joining consecutive event sub_cmd? */
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -6196,18 +6196,59 @@ static bool pvr_is_stencil_store_load_needed(
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pvr_insert_mid_frag_barrier(struct pvr_cmd_buffer *cmd_buffer)
|
||||
static VkResult
|
||||
pvr_cmd_buffer_insert_mid_frag_barrier_event(struct pvr_cmd_buffer *cmd_buffer,
|
||||
uint32_t src_stage_mask,
|
||||
uint32_t dst_stage_mask)
|
||||
{
|
||||
struct pvr_sub_cmd *const curr_sub_cmd = cmd_buffer->state.current_sub_cmd;
|
||||
struct pvr_sub_cmd_event *sub_cmd;
|
||||
VkResult result;
|
||||
|
||||
assert(curr_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
|
||||
assert(cmd_buffer->state.current_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
|
||||
|
||||
cmd_buffer->state.current_sub_cmd->gfx.empty_cmd = false;
|
||||
|
||||
pvr_finishme("Handle mid frag barrier stencil store.");
|
||||
|
||||
pvr_cmd_buffer_end_sub_cmd(cmd_buffer);
|
||||
result = pvr_cmd_buffer_start_sub_cmd(cmd_buffer, PVR_SUB_CMD_TYPE_EVENT);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
sub_cmd = &cmd_buffer->state.current_sub_cmd->event;
|
||||
|
||||
sub_cmd->type = PVR_EVENT_TYPE_BARRIER;
|
||||
sub_cmd->barrier.in_render_pass = true;
|
||||
sub_cmd->barrier.wait_for_stage_mask = src_stage_mask;
|
||||
sub_cmd->barrier.wait_at_stage_mask = dst_stage_mask;
|
||||
|
||||
pvr_cmd_buffer_end_sub_cmd(cmd_buffer);
|
||||
pvr_cmd_buffer_start_sub_cmd(cmd_buffer, PVR_SUB_CMD_TYPE_GRAPHICS);
|
||||
|
||||
pvr_finishme("Handle mid frag barrier color attachment load.");
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_cmd_buffer_insert_barrier_event(struct pvr_cmd_buffer *cmd_buffer,
|
||||
uint32_t src_stage_mask,
|
||||
uint32_t dst_stage_mask)
|
||||
{
|
||||
struct pvr_sub_cmd_event *sub_cmd;
|
||||
VkResult result;
|
||||
|
||||
result = pvr_cmd_buffer_start_sub_cmd(cmd_buffer, PVR_SUB_CMD_TYPE_EVENT);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
sub_cmd = &cmd_buffer->state.current_sub_cmd->event;
|
||||
|
||||
sub_cmd->type = PVR_EVENT_TYPE_BARRIER;
|
||||
sub_cmd->barrier.wait_for_stage_mask = src_stage_mask;
|
||||
sub_cmd->barrier.wait_at_stage_mask = dst_stage_mask;
|
||||
|
||||
return pvr_cmd_buffer_end_sub_cmd(cmd_buffer);
|
||||
}
|
||||
|
||||
/* This is just enough to handle vkCmdPipelineBarrier().
|
||||
@@ -6335,10 +6376,23 @@ void pvr_CmdPipelineBarrier2(VkCommandBuffer commandBuffer,
|
||||
pDependencyInfo->pImageMemoryBarriers);
|
||||
|
||||
if (is_stencil_store_load_needed) {
|
||||
pvr_insert_mid_frag_barrier(cmd_buffer);
|
||||
VkResult result;
|
||||
|
||||
result = pvr_cmd_buffer_insert_mid_frag_barrier_event(cmd_buffer,
|
||||
src_stage_mask,
|
||||
dst_stage_mask);
|
||||
if (result != VK_SUCCESS)
|
||||
mesa_loge("Failed to insert mid frag barrier event.");
|
||||
} else {
|
||||
if (is_barrier_needed)
|
||||
pvr_finishme("Insert barrier if needed.");
|
||||
if (is_barrier_needed) {
|
||||
VkResult result;
|
||||
|
||||
result = pvr_cmd_buffer_insert_barrier_event(cmd_buffer,
|
||||
src_stage_mask,
|
||||
dst_stage_mask);
|
||||
if (result != VK_SUCCESS)
|
||||
mesa_loge("Failed to insert pipeline barrier event.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@
|
||||
static void pvr_compute_job_ws_submit_info_init(
|
||||
struct pvr_compute_ctx *ctx,
|
||||
struct pvr_sub_cmd_compute *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -48,6 +49,8 @@ static void pvr_compute_job_ws_submit_info_init(
|
||||
submit_info->frame_num = ctx->device->global_queue_present_count;
|
||||
submit_info->job_num = ctx->device->global_queue_job_count;
|
||||
|
||||
submit_info->barrier = barrier;
|
||||
|
||||
submit_info->waits = waits;
|
||||
submit_info->wait_count = wait_count;
|
||||
submit_info->stage_flags = stage_flags;
|
||||
@@ -87,6 +90,7 @@ static void pvr_compute_job_ws_submit_info_init(
|
||||
|
||||
VkResult pvr_compute_job_submit(struct pvr_compute_ctx *ctx,
|
||||
struct pvr_sub_cmd_compute *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -96,6 +100,7 @@ VkResult pvr_compute_job_submit(struct pvr_compute_ctx *ctx,
|
||||
|
||||
pvr_compute_job_ws_submit_info_init(ctx,
|
||||
sub_cmd,
|
||||
barrier,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
|
@@ -33,6 +33,7 @@ struct vk_sync;
|
||||
|
||||
VkResult pvr_compute_job_submit(struct pvr_compute_ctx *ctx,
|
||||
struct pvr_sub_cmd_compute *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
|
@@ -1509,6 +1509,8 @@ static void pvr_render_job_ws_submit_info_init(
|
||||
struct pvr_render_job *job,
|
||||
const struct pvr_winsys_job_bo *bos,
|
||||
uint32_t bo_count,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -1527,6 +1529,9 @@ static void pvr_render_job_ws_submit_info_init(
|
||||
submit_info->bos = bos;
|
||||
submit_info->bo_count = bo_count;
|
||||
|
||||
submit_info->barrier_geom = barrier_geom;
|
||||
submit_info->barrier_frag = barrier_frag;
|
||||
|
||||
submit_info->waits = waits;
|
||||
submit_info->wait_count = wait_count;
|
||||
submit_info->stage_flags = stage_flags;
|
||||
@@ -1544,6 +1549,8 @@ VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
const struct pvr_winsys_job_bo *bos,
|
||||
uint32_t bo_count,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -1559,6 +1566,8 @@ VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
||||
job,
|
||||
bos,
|
||||
bo_count,
|
||||
barrier_geom,
|
||||
barrier_frag,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
|
@@ -120,6 +120,8 @@ VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
const struct pvr_winsys_job_bo *bos,
|
||||
uint32_t bo_count,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
|
@@ -39,6 +39,7 @@
|
||||
VkResult pvr_transfer_job_submit(struct pvr_device *device,
|
||||
struct pvr_transfer_ctx *ctx,
|
||||
struct pvr_sub_cmd_transfer *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -59,6 +60,17 @@ VkResult pvr_transfer_job_submit(struct pvr_device *device,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (barrier) {
|
||||
VkResult result = vk_sync_wait(&device->vk,
|
||||
barrier,
|
||||
0U,
|
||||
VK_SYNC_WAIT_COMPLETE,
|
||||
UINT64_MAX);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe (struct pvr_transfer_cmd,
|
||||
transfer_cmd,
|
||||
&sub_cmd->transfer_cmds,
|
||||
|
@@ -35,6 +35,7 @@ struct vk_sync;
|
||||
VkResult pvr_transfer_job_submit(struct pvr_device *device,
|
||||
struct pvr_transfer_ctx *ctx,
|
||||
struct pvr_sub_cmd_transfer *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
|
@@ -290,6 +290,13 @@ struct pvr_queue {
|
||||
struct pvr_transfer_ctx *transfer_ctx;
|
||||
|
||||
struct vk_sync *completion[PVR_JOB_TYPE_MAX];
|
||||
|
||||
/* Used to setup a job dependency from jobs previously submitted, onto
|
||||
* the next job per job type.
|
||||
*
|
||||
* Used to create dependencies for pipeline barriers.
|
||||
*/
|
||||
struct vk_sync *job_dependancy[PVR_JOB_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct pvr_vertex_binding {
|
||||
@@ -764,6 +771,15 @@ struct pvr_sub_cmd_event {
|
||||
/* Stages to wait at. */
|
||||
uint32_t *wait_at_stage_masks;
|
||||
} wait;
|
||||
|
||||
struct {
|
||||
bool in_render_pass;
|
||||
|
||||
/* Stages to wait for. */
|
||||
uint32_t wait_for_stage_mask;
|
||||
/* Stages to wait at. */
|
||||
uint32_t wait_at_stage_mask;
|
||||
} barrier;
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -64,6 +64,8 @@ static VkResult pvr_queue_init(struct pvr_device *device,
|
||||
struct pvr_render_ctx *gfx_ctx;
|
||||
VkResult result;
|
||||
|
||||
*queue = (struct pvr_queue){ 0 };
|
||||
|
||||
result =
|
||||
vk_queue_init(&queue->vk, &device->vk, pCreateInfo, index_in_family);
|
||||
if (result != VK_SUCCESS)
|
||||
@@ -91,9 +93,6 @@ static VkResult pvr_queue_init(struct pvr_device *device,
|
||||
queue->compute_ctx = compute_ctx;
|
||||
queue->transfer_ctx = transfer_ctx;
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(queue->completion); i++)
|
||||
queue->completion[i] = NULL;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_compute_ctx_destroy:
|
||||
@@ -147,6 +146,11 @@ err_queues_finish:
|
||||
|
||||
static void pvr_queue_finish(struct pvr_queue *queue)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(queue->job_dependancy); i++) {
|
||||
if (queue->job_dependancy[i])
|
||||
vk_sync_destroy(&queue->device->vk, queue->job_dependancy[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(queue->completion); i++) {
|
||||
if (queue->completion[i])
|
||||
vk_sync_destroy(&queue->device->vk, queue->completion[i]);
|
||||
@@ -194,6 +198,8 @@ pvr_process_graphics_cmd(struct pvr_device *device,
|
||||
struct pvr_queue *queue,
|
||||
struct pvr_cmd_buffer *cmd_buffer,
|
||||
struct pvr_sub_cmd_gfx *sub_cmd,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -256,6 +262,8 @@ pvr_process_graphics_cmd(struct pvr_device *device,
|
||||
&sub_cmd->job,
|
||||
bos,
|
||||
bo_count,
|
||||
barrier_geom,
|
||||
barrier_frag,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
@@ -288,6 +296,7 @@ static VkResult
|
||||
pvr_process_compute_cmd(struct pvr_device *device,
|
||||
struct pvr_queue *queue,
|
||||
struct pvr_sub_cmd_compute *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -307,6 +316,7 @@ pvr_process_compute_cmd(struct pvr_device *device,
|
||||
/* This passes ownership of the wait fences to pvr_compute_job_submit(). */
|
||||
result = pvr_compute_job_submit(queue->compute_ctx,
|
||||
sub_cmd,
|
||||
barrier,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
@@ -329,6 +339,7 @@ static VkResult
|
||||
pvr_process_transfer_cmds(struct pvr_device *device,
|
||||
struct pvr_queue *queue,
|
||||
struct pvr_sub_cmd_transfer *sub_cmd,
|
||||
struct vk_sync *barrier,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
@@ -349,6 +360,7 @@ pvr_process_transfer_cmds(struct pvr_device *device,
|
||||
result = pvr_transfer_job_submit(device,
|
||||
queue->transfer_ctx,
|
||||
sub_cmd,
|
||||
barrier,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
@@ -367,6 +379,193 @@ pvr_process_transfer_cmds(struct pvr_device *device,
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult pvr_process_event_cmd_barrier(
|
||||
struct pvr_device *device,
|
||||
struct pvr_sub_cmd_event *sub_cmd,
|
||||
struct vk_sync *barriers[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *per_cmd_buffer_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *per_submit_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *queue_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *previous_queue_syncobjs[static PVR_JOB_TYPE_MAX])
|
||||
{
|
||||
const uint32_t src_mask = sub_cmd->barrier.wait_for_stage_mask;
|
||||
const uint32_t dst_mask = sub_cmd->barrier.wait_at_stage_mask;
|
||||
const bool in_render_pass = sub_cmd->barrier.in_render_pass;
|
||||
struct vk_sync *new_barriers[PVR_JOB_TYPE_MAX] = { 0 };
|
||||
struct vk_sync *completions[PVR_JOB_TYPE_MAX] = { 0 };
|
||||
struct vk_sync *src_syncobjs[PVR_JOB_TYPE_MAX];
|
||||
uint32_t src_syncobj_count = 0;
|
||||
VkResult result;
|
||||
|
||||
assert(!(src_mask & ~PVR_PIPELINE_STAGE_ALL_BITS));
|
||||
assert(!(dst_mask & ~PVR_PIPELINE_STAGE_ALL_BITS));
|
||||
|
||||
/* TODO: We're likely over synchronizing here, but the kernel doesn't
|
||||
* guarantee that jobs submitted on a context will execute and complete in
|
||||
* order, even though in practice they will, so we play it safe and don't
|
||||
* make any assumptions. If the kernel starts to offer this guarantee then
|
||||
* remove the extra dependencies being added here.
|
||||
*/
|
||||
|
||||
u_foreach_bit (stage, src_mask) {
|
||||
struct vk_sync *syncobj;
|
||||
|
||||
syncobj = per_cmd_buffer_syncobjs[stage];
|
||||
|
||||
if (!in_render_pass & !syncobj) {
|
||||
if (per_submit_syncobjs[stage])
|
||||
syncobj = per_submit_syncobjs[stage];
|
||||
else if (queue_syncobjs[stage])
|
||||
syncobj = queue_syncobjs[stage];
|
||||
else if (previous_queue_syncobjs[stage])
|
||||
syncobj = previous_queue_syncobjs[stage];
|
||||
}
|
||||
|
||||
if (!syncobj)
|
||||
continue;
|
||||
|
||||
src_syncobjs[src_syncobj_count++] = syncobj;
|
||||
}
|
||||
|
||||
/* No previous src jobs that need finishing so no need for a barrier. */
|
||||
if (src_syncobj_count == 0)
|
||||
return VK_SUCCESS;
|
||||
|
||||
u_foreach_bit (stage, dst_mask) {
|
||||
struct vk_sync *completion;
|
||||
|
||||
result = vk_sync_create(&device->vk,
|
||||
&device->pdevice->ws->syncobj_type,
|
||||
0U,
|
||||
0UL,
|
||||
&completion);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_destroy_completions;
|
||||
|
||||
result = device->ws->ops->null_job_submit(device->ws,
|
||||
src_syncobjs,
|
||||
src_syncobj_count,
|
||||
completion);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_sync_destroy(&device->vk, completion);
|
||||
|
||||
goto err_destroy_completions;
|
||||
}
|
||||
|
||||
completions[stage] = completion;
|
||||
}
|
||||
|
||||
u_foreach_bit (stage, dst_mask) {
|
||||
struct vk_sync *barrier_src_syncobjs[2];
|
||||
uint32_t barrier_src_syncobj_count = 0;
|
||||
struct vk_sync *barrier;
|
||||
VkResult result;
|
||||
|
||||
assert(completions[stage]);
|
||||
barrier_src_syncobjs[barrier_src_syncobj_count++] = completions[stage];
|
||||
|
||||
/* If there is a previous barrier we want to merge it with the new one.
|
||||
*
|
||||
* E.g.
|
||||
* A <compute>, B <compute>,
|
||||
* X <barrier src=compute, dst=graphics>,
|
||||
* C <transfer>
|
||||
* Y <barrier src=transfer, dst=graphics>,
|
||||
* D <graphics>
|
||||
*
|
||||
* X barriers A and B at D. Y barriers C at D. So we want to merge both
|
||||
* X and Y graphics vk_sync barriers to pass to D.
|
||||
*
|
||||
* Note that this is the same as:
|
||||
* A <compute>, B <compute>, C <transfer>
|
||||
* X <barrier src=compute, dst=graphics>,
|
||||
* Y <barrier src=transfer, dst=graphics>,
|
||||
* D <graphics>
|
||||
*
|
||||
*/
|
||||
if (barriers[stage])
|
||||
barrier_src_syncobjs[barrier_src_syncobj_count++] = barriers[stage];
|
||||
|
||||
result = vk_sync_create(&device->vk,
|
||||
&device->pdevice->ws->syncobj_type,
|
||||
0U,
|
||||
0UL,
|
||||
&barrier);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_destroy_new_barriers;
|
||||
|
||||
result = device->ws->ops->null_job_submit(device->ws,
|
||||
barrier_src_syncobjs,
|
||||
barrier_src_syncobj_count,
|
||||
barrier);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_sync_destroy(&device->vk, barrier);
|
||||
|
||||
goto err_destroy_new_barriers;
|
||||
}
|
||||
|
||||
new_barriers[stage] = barrier;
|
||||
}
|
||||
|
||||
u_foreach_bit (stage, dst_mask) {
|
||||
if (per_cmd_buffer_syncobjs[stage])
|
||||
vk_sync_destroy(&device->vk, per_cmd_buffer_syncobjs[stage]);
|
||||
|
||||
per_cmd_buffer_syncobjs[stage] = completions[stage];
|
||||
|
||||
if (barriers[stage])
|
||||
vk_sync_destroy(&device->vk, barriers[stage]);
|
||||
|
||||
barriers[stage] = new_barriers[stage];
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_destroy_new_barriers:
|
||||
u_foreach_bit (stage, dst_mask) {
|
||||
if (new_barriers[stage])
|
||||
vk_sync_destroy(&device->vk, new_barriers[stage]);
|
||||
}
|
||||
|
||||
err_destroy_completions:
|
||||
u_foreach_bit (stage, dst_mask) {
|
||||
if (completions[stage])
|
||||
vk_sync_destroy(&device->vk, completions[stage]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult pvr_process_event_cmd(
|
||||
struct pvr_device *device,
|
||||
struct pvr_sub_cmd_event *sub_cmd,
|
||||
struct vk_sync *barriers[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *per_cmd_buffer_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *per_submit_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *queue_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *previous_queue_syncobjs[static PVR_JOB_TYPE_MAX])
|
||||
{
|
||||
switch (sub_cmd->type) {
|
||||
case PVR_EVENT_TYPE_SET:
|
||||
case PVR_EVENT_TYPE_RESET:
|
||||
case PVR_EVENT_TYPE_WAIT:
|
||||
pvr_finishme("Add support for event sub command type: %d", sub_cmd->type);
|
||||
return VK_SUCCESS;
|
||||
|
||||
case PVR_EVENT_TYPE_BARRIER:
|
||||
return pvr_process_event_cmd_barrier(device,
|
||||
sub_cmd,
|
||||
barriers,
|
||||
per_cmd_buffer_syncobjs,
|
||||
per_submit_syncobjs,
|
||||
queue_syncobjs,
|
||||
previous_queue_syncobjs);
|
||||
|
||||
default:
|
||||
unreachable("Invalid event sub-command type.");
|
||||
};
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_set_semaphore_payloads(struct pvr_device *device,
|
||||
struct vk_sync *completions[static PVR_JOB_TYPE_MAX],
|
||||
@@ -459,15 +658,33 @@ pvr_set_fence_payload(struct pvr_device *device,
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_process_cmd_buffer(struct pvr_device *device,
|
||||
static void pvr_update_syncobjs(struct pvr_device *device,
|
||||
struct vk_sync *src[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *dst[static PVR_JOB_TYPE_MAX])
|
||||
{
|
||||
for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
|
||||
if (src[i]) {
|
||||
if (dst[i])
|
||||
vk_sync_destroy(&device->vk, dst[i]);
|
||||
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult pvr_process_cmd_buffer(
|
||||
struct pvr_device *device,
|
||||
struct pvr_queue *queue,
|
||||
VkCommandBuffer commandBuffer,
|
||||
struct vk_sync *barriers[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
struct vk_sync *completions[static PVR_JOB_TYPE_MAX])
|
||||
struct vk_sync *per_submit_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *queue_syncobjs[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *previous_queue_syncobjs[static PVR_JOB_TYPE_MAX])
|
||||
{
|
||||
struct vk_sync *per_cmd_buffer_syncobjs[PVR_JOB_TYPE_MAX] = {};
|
||||
PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
VkResult result;
|
||||
|
||||
@@ -483,35 +700,44 @@ pvr_process_cmd_buffer(struct pvr_device *device,
|
||||
queue,
|
||||
cmd_buffer,
|
||||
&sub_cmd->gfx,
|
||||
barriers[PVR_JOB_TYPE_GEOM],
|
||||
barriers[PVR_JOB_TYPE_FRAG],
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
completions);
|
||||
per_cmd_buffer_syncobjs);
|
||||
break;
|
||||
|
||||
case PVR_SUB_CMD_TYPE_COMPUTE:
|
||||
result = pvr_process_compute_cmd(device,
|
||||
queue,
|
||||
&sub_cmd->compute,
|
||||
barriers[PVR_JOB_TYPE_COMPUTE],
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
completions);
|
||||
per_cmd_buffer_syncobjs);
|
||||
break;
|
||||
|
||||
case PVR_SUB_CMD_TYPE_TRANSFER:
|
||||
result = pvr_process_transfer_cmds(device,
|
||||
queue,
|
||||
&sub_cmd->transfer,
|
||||
barriers[PVR_JOB_TYPE_TRANSFER],
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
completions);
|
||||
per_cmd_buffer_syncobjs);
|
||||
break;
|
||||
|
||||
case PVR_SUB_CMD_TYPE_EVENT:
|
||||
pvr_finishme("Add support to process event sub cmds.");
|
||||
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
result = pvr_process_event_cmd(device,
|
||||
&sub_cmd->event,
|
||||
barriers,
|
||||
per_cmd_buffer_syncobjs,
|
||||
per_submit_syncobjs,
|
||||
queue_syncobjs,
|
||||
previous_queue_syncobjs);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -527,6 +753,8 @@ pvr_process_cmd_buffer(struct pvr_device *device,
|
||||
p_atomic_inc(&device->global_queue_job_count);
|
||||
}
|
||||
|
||||
pvr_update_syncobjs(device, per_cmd_buffer_syncobjs, per_submit_syncobjs);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -584,20 +812,6 @@ err_destroy_completion_syncs:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void pvr_update_syncobjs(struct pvr_device *device,
|
||||
struct vk_sync *src[static PVR_JOB_TYPE_MAX],
|
||||
struct vk_sync *dst[static PVR_JOB_TYPE_MAX])
|
||||
{
|
||||
for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
|
||||
if (src[i]) {
|
||||
if (dst[i])
|
||||
vk_sync_destroy(&device->vk, dst[i]);
|
||||
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkResult pvr_QueueSubmit(VkQueue _queue,
|
||||
uint32_t submitCount,
|
||||
const VkSubmitInfo *pSubmits,
|
||||
@@ -636,10 +850,13 @@ VkResult pvr_QueueSubmit(VkQueue _queue,
|
||||
result = pvr_process_cmd_buffer(device,
|
||||
queue,
|
||||
desc->pCommandBuffers[j],
|
||||
queue->job_dependancy,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
per_submit_completion_syncobjs);
|
||||
per_submit_completion_syncobjs,
|
||||
completion_syncobjs,
|
||||
queue->completion);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
@@ -279,6 +279,8 @@ struct pvr_winsys_transfer_submit_info {
|
||||
uint32_t frame_num;
|
||||
uint32_t job_num;
|
||||
|
||||
struct vk_sync *barrier;
|
||||
|
||||
/* waits and stage_flags are arrays of length wait_count. */
|
||||
struct vk_sync **waits;
|
||||
uint32_t wait_count;
|
||||
@@ -300,6 +302,8 @@ struct pvr_winsys_compute_submit_info {
|
||||
uint32_t frame_num;
|
||||
uint32_t job_num;
|
||||
|
||||
struct vk_sync *barrier;
|
||||
|
||||
/* waits and stage_flags are arrays of length wait_count. */
|
||||
struct vk_sync **waits;
|
||||
uint32_t wait_count;
|
||||
@@ -349,6 +353,9 @@ struct pvr_winsys_render_submit_info {
|
||||
/* FIXME: should this be flags instead? */
|
||||
bool run_frag;
|
||||
|
||||
struct vk_sync *barrier_geom;
|
||||
struct vk_sync *barrier_frag;
|
||||
|
||||
/* waits and stage_flags are arrays of length wait_count. */
|
||||
struct vk_sync **waits;
|
||||
uint32_t wait_count;
|
||||
|
@@ -196,6 +196,20 @@ VkResult pvr_srv_winsys_compute_submit(
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->barrier);
|
||||
|
||||
if (srv_wait_sync->fd >= 0) {
|
||||
int ret;
|
||||
|
||||
ret = sync_accumulate("", &in_fd, srv_wait_sync->fd);
|
||||
if (ret) {
|
||||
result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto end_close_in_fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
result = pvr_srv_rgx_kick_compute2(srv_ws->render_fd,
|
||||
srv_ctx->handle,
|
||||
|
@@ -587,6 +587,36 @@ VkResult pvr_srv_winsys_render_submit(
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier_geom) {
|
||||
struct pvr_srv_sync *srv_wait_sync =
|
||||
to_srv_sync(submit_info->barrier_geom);
|
||||
|
||||
if (srv_wait_sync->fd >= 0) {
|
||||
int ret;
|
||||
|
||||
ret = sync_accumulate("", &in_geom_fd, srv_wait_sync->fd);
|
||||
if (ret) {
|
||||
result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto end_close_in_fds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier_frag) {
|
||||
struct pvr_srv_sync *srv_wait_sync =
|
||||
to_srv_sync(submit_info->barrier_frag);
|
||||
|
||||
if (srv_wait_sync->fd >= 0) {
|
||||
int ret;
|
||||
|
||||
ret = sync_accumulate("", &in_frag_fd, srv_wait_sync->fd);
|
||||
if (ret) {
|
||||
result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto end_close_in_fds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->bo_count <= ARRAY_SIZE(sync_pmrs)) {
|
||||
sync_pmr_count = submit_info->bo_count;
|
||||
} else {
|
||||
|
@@ -244,6 +244,20 @@ VkResult pvr_srv_winsys_transfer_submit(
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->barrier);
|
||||
|
||||
if (srv_wait_sync->fd >= 0) {
|
||||
int ret;
|
||||
|
||||
ret = sync_accumulate("", &in_fd, srv_wait_sync->fd);
|
||||
if (ret) {
|
||||
result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto end_close_in_fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
job_num = submit_info->job_num;
|
||||
|
||||
do {
|
||||
|
Reference in New Issue
Block a user