mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 17:30:12 +01:00
pvr: Use common queue submit implementation
A simplification of the synchronization code is also undertaken as part of this commit to account for the implicit guarantee the FW gives the driver that jobs submitted to the same context will be run in submission order. Signed-off-by: Jarred Davies <jarred.davies@imgtec.com> Reviewed-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21577>
This commit is contained in:
parent
5ce99bc568
commit
80f864cd23
19 changed files with 733 additions and 1009 deletions
|
|
@ -179,10 +179,7 @@ pvr_submit_info_flags_init(const struct pvr_device_info *const dev_info,
|
|||
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,
|
||||
struct vk_sync *wait,
|
||||
struct pvr_winsys_compute_submit_info *submit_info)
|
||||
{
|
||||
const struct pvr_device *const device = ctx->device;
|
||||
|
|
@ -193,11 +190,7 @@ static void pvr_compute_job_ws_submit_info_init(
|
|||
submit_info->frame_num = device->global_queue_present_count;
|
||||
submit_info->job_num = device->global_cmd_buffer_submit_count;
|
||||
|
||||
submit_info->barrier = barrier;
|
||||
|
||||
submit_info->waits = waits;
|
||||
submit_info->wait_count = wait_count;
|
||||
submit_info->stage_flags = stage_flags;
|
||||
submit_info->wait = wait;
|
||||
|
||||
pvr_submit_info_stream_init(ctx, sub_cmd, submit_info);
|
||||
pvr_submit_info_ext_stream_init(ctx, submit_info);
|
||||
|
|
@ -206,22 +199,13 @@ 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,
|
||||
struct vk_sync *wait,
|
||||
struct vk_sync *signal_sync)
|
||||
{
|
||||
struct pvr_winsys_compute_submit_info submit_info;
|
||||
struct pvr_device *device = ctx->device;
|
||||
|
||||
pvr_compute_job_ws_submit_info_init(ctx,
|
||||
sub_cmd,
|
||||
barrier,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
&submit_info);
|
||||
pvr_compute_job_ws_submit_info_init(ctx, sub_cmd, wait, &submit_info);
|
||||
|
||||
if (PVR_IS_DEBUG_SET(DUMP_CONTROL_STREAM)) {
|
||||
pvr_csb_dump(&sub_cmd->control_stream,
|
||||
|
|
|
|||
|
|
@ -33,10 +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,
|
||||
struct vk_sync *wait,
|
||||
struct vk_sync *signal_sync);
|
||||
|
||||
#endif /* PVR_JOB_COMPUTE_H */
|
||||
|
|
|
|||
|
|
@ -1279,10 +1279,13 @@ static void pvr_geom_state_flags_init(const struct pvr_render_job *const job,
|
|||
static void
|
||||
pvr_render_job_ws_geometry_state_init(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
struct vk_sync *wait,
|
||||
struct pvr_winsys_geometry_state *state)
|
||||
{
|
||||
pvr_geom_state_stream_init(ctx, job, state);
|
||||
pvr_geom_state_stream_ext_init(ctx, job, state);
|
||||
|
||||
state->wait = wait;
|
||||
pvr_geom_state_flags_init(job, &state->flags);
|
||||
}
|
||||
|
||||
|
|
@ -1687,21 +1690,21 @@ static void pvr_frag_state_flags_init(const struct pvr_render_job *const job,
|
|||
static void
|
||||
pvr_render_job_ws_fragment_state_init(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
struct vk_sync *wait,
|
||||
struct pvr_winsys_fragment_state *state)
|
||||
{
|
||||
pvr_frag_state_stream_init(ctx, job, state);
|
||||
pvr_frag_state_stream_ext_init(ctx, job, state);
|
||||
|
||||
state->wait = wait;
|
||||
pvr_frag_state_flags_init(job, &state->flags);
|
||||
}
|
||||
|
||||
static void pvr_render_job_ws_submit_info_init(
|
||||
struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
struct vk_sync *wait_geom,
|
||||
struct vk_sync *wait_frag,
|
||||
struct pvr_winsys_render_submit_info *submit_info)
|
||||
{
|
||||
memset(submit_info, 0, sizeof(*submit_info));
|
||||
|
|
@ -1712,29 +1715,25 @@ static void pvr_render_job_ws_submit_info_init(
|
|||
submit_info->frame_num = ctx->device->global_queue_present_count;
|
||||
submit_info->job_num = ctx->device->global_cmd_buffer_submit_count;
|
||||
|
||||
submit_info->barrier_geom = barrier_geom;
|
||||
|
||||
submit_info->waits = waits;
|
||||
submit_info->wait_count = wait_count;
|
||||
submit_info->stage_flags = stage_flags;
|
||||
|
||||
pvr_render_job_ws_geometry_state_init(ctx, job, &submit_info->geometry);
|
||||
pvr_render_job_ws_geometry_state_init(ctx,
|
||||
job,
|
||||
wait_geom,
|
||||
&submit_info->geometry);
|
||||
|
||||
if (job->run_frag) {
|
||||
submit_info->run_frag = true;
|
||||
submit_info->barrier_frag = barrier_frag;
|
||||
|
||||
pvr_render_job_ws_fragment_state_init(ctx, job, &submit_info->fragment);
|
||||
pvr_render_job_ws_fragment_state_init(ctx,
|
||||
job,
|
||||
wait_frag,
|
||||
&submit_info->fragment);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
struct vk_sync *wait_geom,
|
||||
struct vk_sync *wait_frag,
|
||||
struct vk_sync *signal_sync_geom,
|
||||
struct vk_sync *signal_sync_frag)
|
||||
{
|
||||
|
|
@ -1745,11 +1744,8 @@ VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
|||
|
||||
pvr_render_job_ws_submit_info_init(ctx,
|
||||
job,
|
||||
barrier_geom,
|
||||
barrier_frag,
|
||||
waits,
|
||||
wait_count,
|
||||
stage_flags,
|
||||
wait_geom,
|
||||
wait_frag,
|
||||
&submit_info);
|
||||
|
||||
if (PVR_IS_DEBUG_SET(DUMP_CONTROL_STREAM)) {
|
||||
|
|
|
|||
|
|
@ -129,11 +129,8 @@ void pvr_render_target_dataset_destroy(struct pvr_rt_dataset *dataset);
|
|||
|
||||
VkResult pvr_render_job_submit(struct pvr_render_ctx *ctx,
|
||||
struct pvr_render_job *job,
|
||||
struct vk_sync *barrier_geom,
|
||||
struct vk_sync *barrier_frag,
|
||||
struct vk_sync **waits,
|
||||
uint32_t wait_count,
|
||||
uint32_t *stage_flags,
|
||||
struct vk_sync *wait_geom,
|
||||
struct vk_sync *wait_frag,
|
||||
struct vk_sync *signal_sync_geom,
|
||||
struct vk_sync *signal_sync_frag);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,37 +39,18 @@
|
|||
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,
|
||||
struct vk_sync *wait_sync,
|
||||
struct vk_sync *signal_sync)
|
||||
{
|
||||
/* Wait for transfer semaphores here before doing any transfers. */
|
||||
for (uint32_t i = 0U; i < wait_count; i++) {
|
||||
if (stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) {
|
||||
VkResult result = vk_sync_wait(&device->vk,
|
||||
waits[i],
|
||||
0U,
|
||||
VK_SYNC_WAIT_COMPLETE,
|
||||
UINT64_MAX);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
VkResult result;
|
||||
|
||||
stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (barrier) {
|
||||
VkResult result = vk_sync_wait(&device->vk,
|
||||
barrier,
|
||||
0U,
|
||||
VK_SYNC_WAIT_COMPLETE,
|
||||
UINT64_MAX);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
result = vk_sync_wait(&device->vk,
|
||||
wait_sync,
|
||||
0U,
|
||||
VK_SYNC_WAIT_COMPLETE,
|
||||
UINT64_MAX);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
list_for_each_entry_safe (struct pvr_transfer_cmd,
|
||||
transfer_cmd,
|
||||
|
|
|
|||
|
|
@ -35,10 +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,
|
||||
struct vk_sync *wait,
|
||||
struct vk_sync *signal_sync);
|
||||
|
||||
#endif /* PVR_JOB_TRANSFER_H */
|
||||
|
|
|
|||
|
|
@ -131,14 +131,8 @@ struct pvr_queue {
|
|||
struct pvr_compute_ctx *query_ctx;
|
||||
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 vk_sync *last_job_signal_sync[PVR_JOB_TYPE_MAX];
|
||||
struct vk_sync *next_job_wait_sync[PVR_JOB_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct pvr_vertex_binding {
|
||||
|
|
@ -279,6 +273,8 @@ struct pvr_device {
|
|||
VkPhysicalDeviceFeatures features;
|
||||
|
||||
struct pvr_bo_store *bo_store;
|
||||
|
||||
struct vk_sync *presignaled_sync;
|
||||
};
|
||||
|
||||
struct pvr_device_memory {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -292,12 +292,7 @@ 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;
|
||||
uint32_t *stage_flags;
|
||||
struct vk_sync *wait;
|
||||
|
||||
uint32_t cmd_count;
|
||||
struct pvr_winsys_transfer_cmd cmds[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
|
||||
|
|
@ -310,12 +305,7 @@ 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;
|
||||
uint32_t *stage_flags;
|
||||
struct vk_sync *wait;
|
||||
|
||||
/* Firmware stream buffer. This is the maximum possible size taking into
|
||||
* consideration all HW features.
|
||||
|
|
@ -354,14 +344,6 @@ 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;
|
||||
uint32_t *stage_flags;
|
||||
|
||||
struct pvr_winsys_geometry_state {
|
||||
/* Firmware stream buffer. This is the maximum possible size taking into
|
||||
* consideration all HW features.
|
||||
|
|
@ -377,6 +359,8 @@ struct pvr_winsys_render_submit_info {
|
|||
|
||||
/* Must be 0 or a combination of PVR_WINSYS_GEOM_FLAG_* flags. */
|
||||
uint32_t flags;
|
||||
|
||||
struct vk_sync *wait;
|
||||
} geometry;
|
||||
|
||||
struct pvr_winsys_fragment_state {
|
||||
|
|
@ -394,6 +378,8 @@ struct pvr_winsys_render_submit_info {
|
|||
|
||||
/* Must be 0 or a combination of PVR_WINSYS_FRAG_FLAG_* flags. */
|
||||
uint32_t flags;
|
||||
|
||||
struct vk_sync *wait;
|
||||
} fragment;
|
||||
};
|
||||
|
||||
|
|
@ -485,9 +471,9 @@ struct pvr_winsys_ops {
|
|||
struct vk_sync *signal_sync);
|
||||
|
||||
VkResult (*null_job_submit)(struct pvr_winsys *ws,
|
||||
struct vk_sync **waits,
|
||||
struct vk_sync_wait *waits,
|
||||
uint32_t wait_count,
|
||||
struct vk_sync *signal_sync);
|
||||
struct vk_sync_signal *signal_sync);
|
||||
};
|
||||
|
||||
struct pvr_winsys {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "pvr_srv.h"
|
||||
#include "pvr_srv_bo.h"
|
||||
#include "pvr_srv_bridge.h"
|
||||
#include "pvr_srv_job_common.h"
|
||||
#include "pvr_srv_job_compute.h"
|
||||
#include "pvr_srv_job_render.h"
|
||||
#include "pvr_srv_job_transfer.h"
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
#include "util/macros.h"
|
||||
#include "util/os_misc.h"
|
||||
#include "vk_log.h"
|
||||
#include "vk_sync.h"
|
||||
|
||||
/* Amount of space used to hold sync prim values (in bytes). */
|
||||
#define PVR_SRV_SYNC_PRIM_VALUE_SIZE 4U
|
||||
|
|
@ -392,6 +394,11 @@ static void pvr_srv_winsys_destroy(struct pvr_winsys *ws)
|
|||
struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws);
|
||||
int fd = srv_ws->render_fd;
|
||||
|
||||
if (srv_ws->presignaled_sync) {
|
||||
vk_sync_destroy(&srv_ws->presignaled_sync_device->vk,
|
||||
&srv_ws->presignaled_sync->base);
|
||||
}
|
||||
|
||||
pvr_srv_sync_prim_block_finish(srv_ws);
|
||||
pvr_srv_memctx_finish(srv_ws);
|
||||
vk_free(srv_ws->alloc, srv_ws);
|
||||
|
|
@ -741,3 +748,83 @@ void pvr_srv_sync_prim_free(struct pvr_srv_sync_prim *sync_prim)
|
|||
vk_free(srv_ws->alloc, sync_prim);
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult pvr_srv_create_presignaled_sync(struct pvr_device *device,
|
||||
struct pvr_srv_sync **out_sync)
|
||||
{
|
||||
struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(device->ws);
|
||||
struct vk_sync *sync;
|
||||
|
||||
int timeline_fd;
|
||||
int sync_fd;
|
||||
|
||||
VkResult result;
|
||||
|
||||
result = pvr_srv_create_timeline(srv_ws->render_fd, &timeline_fd);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
result = pvr_srv_set_timeline_sw_only(timeline_fd);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_close_timeline;
|
||||
|
||||
result = pvr_srv_create_sw_fence(timeline_fd, &sync_fd, NULL);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_close_timeline;
|
||||
|
||||
result = pvr_srv_sw_sync_timeline_increment(timeline_fd, NULL);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_close_sw_fence;
|
||||
|
||||
result = vk_sync_create(&device->vk,
|
||||
&device->pdevice->ws->syncobj_type,
|
||||
0U,
|
||||
0UL,
|
||||
&sync);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_close_sw_fence;
|
||||
|
||||
result = vk_sync_import_sync_file(&device->vk, sync, sync_fd);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_destroy_sync;
|
||||
|
||||
*out_sync = to_srv_sync(sync);
|
||||
(*out_sync)->signaled = true;
|
||||
|
||||
close(timeline_fd);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_destroy_sync:
|
||||
vk_sync_destroy(&device->vk, sync);
|
||||
|
||||
err_close_sw_fence:
|
||||
close(sync_fd);
|
||||
|
||||
err_close_timeline:
|
||||
close(timeline_fd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_sync_get_presignaled_sync(struct pvr_device *device,
|
||||
struct pvr_srv_sync **out_sync)
|
||||
{
|
||||
struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(device->ws);
|
||||
VkResult result;
|
||||
|
||||
if (!srv_ws->presignaled_sync) {
|
||||
result =
|
||||
pvr_srv_create_presignaled_sync(device, &srv_ws->presignaled_sync);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
srv_ws->presignaled_sync_device = device;
|
||||
}
|
||||
|
||||
assert(device == srv_ws->presignaled_sync_device);
|
||||
|
||||
*out_sync = srv_ws->presignaled_sync;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <pthread.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "pvr_srv_sync.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/vma.h"
|
||||
|
|
@ -71,6 +72,9 @@ struct pvr_srv_winsys {
|
|||
int master_fd;
|
||||
int render_fd;
|
||||
|
||||
struct pvr_device *presignaled_sync_device;
|
||||
struct pvr_srv_sync *presignaled_sync;
|
||||
|
||||
const VkAllocationCallbacks *alloc;
|
||||
|
||||
/* Packed bvnc */
|
||||
|
|
@ -130,4 +134,7 @@ pvr_srv_sync_prim_get_fw_addr(const struct pvr_srv_sync_prim *const sync_prim)
|
|||
return sync_prim->srv_ws->sync_block_fw_addr + sync_prim->offset;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_sync_get_presignaled_sync(struct pvr_device *device,
|
||||
struct pvr_srv_sync **out_sync);
|
||||
|
||||
#endif /* PVR_SRV_H */
|
||||
|
|
|
|||
|
|
@ -87,6 +87,76 @@ VkResult pvr_srv_init_module(int fd, enum pvr_srvkm_module_type module)
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_set_timeline_sw_only(int sw_timeline_fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(sw_timeline_fd >= 0);
|
||||
|
||||
ret = drmIoctl(sw_timeline_fd, DRM_IOCTL_SRVKM_SYNC_FORCE_SW_ONLY_CMD, NULL);
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
return vk_errorf(
|
||||
NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"DRM_IOCTL_SRVKM_SYNC_FORCE_SW_ONLY_CMD failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_create_sw_fence(int sw_timeline_fd,
|
||||
int *new_fence_fd,
|
||||
uint64_t *sync_pt_idx)
|
||||
{
|
||||
struct drm_srvkm_sw_sync_create_fence_data data = { .name[0] = '\0' };
|
||||
int ret;
|
||||
|
||||
assert(sw_timeline_fd >= 0);
|
||||
assert(new_fence_fd != NULL);
|
||||
|
||||
ret =
|
||||
drmIoctl(sw_timeline_fd, DRM_IOCTL_SRVKM_SW_SYNC_CREATE_FENCE_CMD, &data);
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
return vk_errorf(
|
||||
NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"DRM_IOCTL_SRVKM_SW_SYNC_CREATE_FENCE_CMD failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
*new_fence_fd = data.fence;
|
||||
if (sync_pt_idx)
|
||||
*sync_pt_idx = data.sync_pt_idx;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_sw_sync_timeline_increment(int sw_timeline_fd,
|
||||
uint64_t *sync_pt_idx)
|
||||
{
|
||||
struct drm_srvkm_sw_timeline_advance_data data = { 0 };
|
||||
int ret;
|
||||
|
||||
assert(sw_timeline_fd >= 0);
|
||||
|
||||
ret = drmIoctl(sw_timeline_fd, DRM_IOCTL_SRVKM_SW_SYNC_INC_CMD, &data);
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
return vk_errorf(NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"DRM_IOCTL_SRVKM_SW_SYNC_INC_CMD failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
if (sync_pt_idx)
|
||||
*sync_pt_idx = data.sync_pt_idx;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult pvr_srv_connection_create(int fd, uint64_t *const bvnc_out)
|
||||
{
|
||||
struct pvr_srv_bridge_connect_cmd cmd = {
|
||||
|
|
|
|||
|
|
@ -98,11 +98,28 @@
|
|||
* These defines must be prefixed with "DRM_".
|
||||
*/
|
||||
#define DRM_SRVKM_CMD 0U /* PVR Services command. */
|
||||
|
||||
/* PVR Sync commands */
|
||||
#define DRM_SRVKM_SYNC_FORCE_SW_ONLY_CMD 2U
|
||||
|
||||
/* PVR Software Sync commands */
|
||||
#define DRM_SRVKM_SW_SYNC_CREATE_FENCE_CMD 3U
|
||||
#define DRM_SRVKM_SW_SYNC_INC_CMD 4U
|
||||
|
||||
/* PVR Services Render Device Init command */
|
||||
#define DRM_SRVKM_INIT 5U /* PVR Services Render Device Init command. */
|
||||
|
||||
/* These defines must be prefixed with "DRM_IOCTL_". */
|
||||
#define DRM_IOCTL_SRVKM_CMD \
|
||||
DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_CMD, struct drm_srvkm_cmd)
|
||||
#define DRM_IOCTL_SRVKM_SYNC_FORCE_SW_ONLY_CMD \
|
||||
DRM_IO(DRM_COMMAND_BASE + DRM_SRVKM_SYNC_FORCE_SW_ONLY_CMD)
|
||||
#define DRM_IOCTL_SRVKM_SW_SYNC_CREATE_FENCE_CMD \
|
||||
DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_SW_SYNC_CREATE_FENCE_CMD, \
|
||||
struct drm_srvkm_sw_sync_create_fence_data)
|
||||
#define DRM_IOCTL_SRVKM_SW_SYNC_INC_CMD \
|
||||
DRM_IOR(DRM_COMMAND_BASE + DRM_SRVKM_SW_SYNC_INC_CMD, \
|
||||
struct drm_srvkm_sw_timeline_advance_data)
|
||||
#define DRM_IOCTL_SRVKM_INIT \
|
||||
DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_INIT, struct drm_srvkm_init_data)
|
||||
|
||||
|
|
@ -815,6 +832,17 @@ struct drm_srvkm_init_data {
|
|||
uint32_t init_module;
|
||||
};
|
||||
|
||||
struct drm_srvkm_sw_sync_create_fence_data {
|
||||
char name[32];
|
||||
__s32 fence;
|
||||
__u32 pad;
|
||||
__u64 sync_pt_idx;
|
||||
};
|
||||
|
||||
struct drm_srvkm_sw_timeline_advance_data {
|
||||
__u64 sync_pt_idx;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
DRM helper enum
|
||||
******************************************************************************/
|
||||
|
|
@ -830,6 +858,15 @@ enum pvr_srvkm_module_type {
|
|||
|
||||
VkResult pvr_srv_init_module(int fd, enum pvr_srvkm_module_type module);
|
||||
|
||||
VkResult pvr_srv_set_timeline_sw_only(int sw_timeline_fd);
|
||||
|
||||
VkResult pvr_srv_create_sw_fence(int sw_timeline_fd,
|
||||
int *new_fence_fd,
|
||||
uint64_t *sync_pt_idx);
|
||||
|
||||
VkResult pvr_srv_sw_sync_timeline_increment(int sw_timeline_fd,
|
||||
uint64_t *sync_pt_idx);
|
||||
|
||||
/******************************************************************************
|
||||
Bridge function prototypes
|
||||
******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
|
@ -38,7 +40,6 @@
|
|||
#include "pvr_srv_job_compute.h"
|
||||
#include "pvr_srv_sync.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/macros.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_log.h"
|
||||
|
|
@ -242,34 +243,16 @@ VkResult pvr_srv_winsys_compute_submit(
|
|||
|
||||
pvr_srv_compute_cmd_init(submit_info, &compute_cmd, dev_info);
|
||||
|
||||
for (uint32_t i = 0U; i < submit_info->wait_count; i++) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->waits[i]);
|
||||
int ret;
|
||||
|
||||
if (!submit_info->waits[i] || srv_wait_sync->fd < 0)
|
||||
continue;
|
||||
|
||||
if (submit_info->stage_flags[i] & PVR_PIPELINE_STAGE_COMPUTE_BIT) {
|
||||
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;
|
||||
}
|
||||
|
||||
submit_info->stage_flags[i] &= ~PVR_PIPELINE_STAGE_COMPUTE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->barrier);
|
||||
if (submit_info->wait) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->wait);
|
||||
|
||||
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;
|
||||
in_fd = dup(srv_wait_sync->fd);
|
||||
if (in_fd == -1) {
|
||||
return vk_errorf(NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"dup called on wait sync failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,22 +35,29 @@
|
|||
#include "vk_sync.h"
|
||||
|
||||
VkResult pvr_srv_winsys_null_job_submit(struct pvr_winsys *ws,
|
||||
struct vk_sync **waits,
|
||||
struct vk_sync_wait *waits,
|
||||
uint32_t wait_count,
|
||||
struct vk_sync *signal_sync)
|
||||
struct vk_sync_signal *signal)
|
||||
{
|
||||
struct pvr_srv_sync *srv_signal_sync = to_srv_sync(signal_sync);
|
||||
int fd = -1;
|
||||
|
||||
assert(signal_sync);
|
||||
/* Services doesn't support timeline syncs.
|
||||
* Timeline syncs should be emulated by the Vulkan runtime and converted
|
||||
* to binary syncs before this point.
|
||||
*/
|
||||
assert((signal->signal_value == 0) &&
|
||||
!(signal->sync->flags & VK_SYNC_IS_TIMELINE));
|
||||
|
||||
for (uint32_t i = 0; i < wait_count; i++) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(waits[i]);
|
||||
for (uint32_t wait_idx = 0; wait_idx < wait_count; wait_idx++) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(waits[wait_idx].sync);
|
||||
int ret;
|
||||
|
||||
if (!waits[i] || srv_wait_sync->fd < 0)
|
||||
if (srv_wait_sync->fd < 0)
|
||||
continue;
|
||||
|
||||
assert((waits[wait_idx].wait_value == 0) &&
|
||||
!(waits[wait_idx].sync->flags & VK_SYNC_IS_TIMELINE));
|
||||
|
||||
ret = sync_accumulate("", &fd, srv_wait_sync->fd);
|
||||
if (ret) {
|
||||
if (fd >= 0)
|
||||
|
|
@ -60,7 +67,7 @@ VkResult pvr_srv_winsys_null_job_submit(struct pvr_winsys *ws,
|
|||
}
|
||||
}
|
||||
|
||||
pvr_srv_set_sync_payload(srv_signal_sync, fd);
|
||||
pvr_srv_set_sync_payload(to_srv_sync(signal->sync), fd);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
|
||||
struct pvr_winsys;
|
||||
struct vk_sync;
|
||||
struct vk_sync_wait;
|
||||
struct vk_sync_signal;
|
||||
|
||||
VkResult pvr_srv_winsys_null_job_submit(struct pvr_winsys *ws,
|
||||
struct vk_sync **waits,
|
||||
struct vk_sync_wait *waits,
|
||||
uint32_t wait_count,
|
||||
struct vk_sync *signal_sync);
|
||||
struct vk_sync_signal *signal_sync);
|
||||
|
||||
#endif /* PVR_SRV_JOB_NULL_H */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
|
@ -42,7 +43,6 @@
|
|||
#include "pvr_srv_sync.h"
|
||||
#include "pvr_types.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/log.h"
|
||||
#include "util/macros.h"
|
||||
#include "vk_alloc.h"
|
||||
|
|
@ -700,60 +700,32 @@ VkResult pvr_srv_winsys_render_submit(
|
|||
pvr_srv_geometry_cmd_init(submit_info, sync_prim, &geom_cmd, dev_info);
|
||||
pvr_srv_fragment_cmd_init(submit_info, &frag_cmd, dev_info);
|
||||
|
||||
for (uint32_t i = 0U; i < submit_info->wait_count; i++) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->waits[i]);
|
||||
int ret;
|
||||
|
||||
if (!submit_info->waits[i] || srv_wait_sync->fd < 0)
|
||||
continue;
|
||||
|
||||
if (submit_info->stage_flags[i] & PVR_PIPELINE_STAGE_GEOM_BIT) {
|
||||
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;
|
||||
}
|
||||
|
||||
submit_info->stage_flags[i] &= ~PVR_PIPELINE_STAGE_GEOM_BIT;
|
||||
}
|
||||
|
||||
if (submit_info->stage_flags[i] & PVR_PIPELINE_STAGE_FRAG_BIT) {
|
||||
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;
|
||||
}
|
||||
|
||||
submit_info->stage_flags[i] &= ~PVR_PIPELINE_STAGE_FRAG_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier_geom) {
|
||||
if (submit_info->geometry.wait) {
|
||||
struct pvr_srv_sync *srv_wait_sync =
|
||||
to_srv_sync(submit_info->barrier_geom);
|
||||
to_srv_sync(submit_info->geometry.wait);
|
||||
|
||||
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;
|
||||
in_geom_fd = dup(srv_wait_sync->fd);
|
||||
if (in_geom_fd == -1) {
|
||||
return vk_errorf(NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"dup called on wait sync failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier_frag) {
|
||||
if (submit_info->fragment.wait) {
|
||||
struct pvr_srv_sync *srv_wait_sync =
|
||||
to_srv_sync(submit_info->barrier_frag);
|
||||
to_srv_sync(submit_info->fragment.wait);
|
||||
|
||||
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;
|
||||
in_frag_fd = dup(srv_wait_sync->fd);
|
||||
if (in_frag_fd == -1) {
|
||||
return vk_errorf(NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"dup called on wait sync failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
|
@ -37,7 +39,6 @@
|
|||
#include "pvr_srv_job_transfer.h"
|
||||
#include "pvr_srv_sync.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/macros.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_log.h"
|
||||
|
|
@ -271,34 +272,16 @@ VkResult pvr_srv_winsys_transfer_submit(
|
|||
cmds_ptr_arr[i] = &transfer_cmds[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0U; i < submit_info->wait_count; i++) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->waits[i]);
|
||||
int ret;
|
||||
|
||||
if (!submit_info->waits[i] || srv_wait_sync->fd < 0)
|
||||
continue;
|
||||
|
||||
if (submit_info->stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) {
|
||||
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;
|
||||
}
|
||||
|
||||
submit_info->stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (submit_info->barrier) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->barrier);
|
||||
if (submit_info->wait) {
|
||||
struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->wait);
|
||||
|
||||
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;
|
||||
in_fd = dup(srv_wait_sync->fd);
|
||||
if (in_fd == -1) {
|
||||
return vk_errorf(NULL,
|
||||
VK_ERROR_OUT_OF_HOST_MEMORY,
|
||||
"dup called on wait sync failed, Errno: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,13 +287,20 @@ static VkResult pvr_srv_sync_export_sync_file(struct vk_device *device,
|
|||
int *sync_file)
|
||||
{
|
||||
struct pvr_srv_sync *srv_sync = to_srv_sync(sync);
|
||||
VkResult result;
|
||||
int fd;
|
||||
|
||||
if (srv_sync->fd < 0) {
|
||||
*sync_file = -1;
|
||||
return VK_SUCCESS;
|
||||
struct pvr_device *driver_device =
|
||||
container_of(device, struct pvr_device, vk);
|
||||
|
||||
result = pvr_srv_sync_get_presignaled_sync(driver_device, &srv_sync);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
assert(srv_sync->fd >= 0);
|
||||
|
||||
fd = dup(srv_sync->fd);
|
||||
if (fd < 0)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue