diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 4126055213a..0049fa08e3d 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -355,7 +355,9 @@ static VkResult pvr_physical_device_init(struct pvr_physical_device *pdevice, goto err_vk_free_master_path; } - ret = pdevice->ws->ops->device_info_init(pdevice->ws, &pdevice->dev_info); + ret = pdevice->ws->ops->device_info_init(pdevice->ws, + &pdevice->dev_info, + &pdevice->dev_runtime_info); if (ret) { result = VK_ERROR_INITIALIZATION_FAILED; goto err_pvr_winsys_destroy; diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 2eaf159f2f5..08a21422b8c 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -201,6 +201,10 @@ struct pvr_physical_device { struct pvr_winsys *ws; struct pvr_device_info dev_info; + struct pvr_device_runtime_info { + uint32_t core_count; + } dev_runtime_info; + VkPhysicalDeviceMemoryProperties memory; uint8_t pipeline_cache_uuid[VK_UUID_SIZE]; diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index a7d724f76c3..19e9a010978 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -40,6 +40,7 @@ #include "util/vma.h" struct pvr_device_info; +struct pvr_device_runtime_info; /* device virtual address */ typedef struct pvr_dev_addr { @@ -357,7 +358,8 @@ struct pvr_winsys_render_submit_info { struct pvr_winsys_ops { void (*destroy)(struct pvr_winsys *ws); int (*device_info_init)(struct pvr_winsys *ws, - struct pvr_device_info *dev_info); + struct pvr_device_info *dev_info, + struct pvr_device_runtime_info *runtime_info); void (*get_heaps_info)(struct pvr_winsys *ws, struct pvr_winsys_heaps *heaps); diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c index 3d12ae3e7b8..646ffc67d66 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c @@ -328,10 +328,13 @@ static void pvr_srv_winsys_destroy(struct pvr_winsys *ws) pvr_srv_connection_destroy(fd); } -static int pvr_srv_winsys_device_info_init(struct pvr_winsys *ws, - struct pvr_device_info *dev_info) +static int +pvr_srv_winsys_device_info_init(struct pvr_winsys *ws, + struct pvr_device_info *dev_info, + struct pvr_device_runtime_info *runtime_info) { struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); + VkResult result; int ret; ret = pvr_device_info_init(dev_info, srv_ws->bvnc); @@ -344,6 +347,17 @@ static int pvr_srv_winsys_device_info_init(struct pvr_winsys *ws, return ret; } + if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) { + result = pvr_srv_get_multicore_info(srv_ws->render_fd, + 0, + NULL, + &runtime_info->core_count); + if (result != VK_SUCCESS) + return -ENODEV; + } else { + runtime_info->core_count = 1; + } + return 0; } diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c index 064cf8f82ee..4fe434cee9d 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c @@ -125,6 +125,42 @@ void pvr_srv_connection_destroy(int fd) } } +VkResult pvr_srv_get_multicore_info(int fd, + uint32_t caps_size, + uint64_t *caps, + uint32_t *num_cores) +{ + struct pvr_srv_bridge_getmulticoreinfo_cmd cmd = { + .caps = caps, + .caps_size = caps_size, + }; + + struct pvr_srv_bridge_getmulticoreinfo_ret ret = { + .caps = caps, + .error = PVR_SRV_ERROR_BRIDGE_CALL_FAILED, + }; + + int result; + + result = pvr_srv_bridge_call(fd, + PVR_SRV_BRIDGE_SRVCORE, + PVR_SRV_BRIDGE_SRVCORE_GETMULTICOREINFO, + &cmd, + sizeof(cmd), + &ret, + sizeof(ret)); + if (result || ret.error != PVR_SRV_OK) { + return vk_bridge_err(VK_ERROR_INITIALIZATION_FAILED, + "PVR_SRV_BRIDGE_SRVCORE_GETMULTICOREINFO", + ret); + } + + if (!num_cores) + *num_cores = ret.num_cores; + + return VK_SUCCESS; +} + VkResult pvr_srv_alloc_sync_primitive_block(int fd, void **const handle_out, void **const pmr_out, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h index fa829888759..3ea2a4b8e5e 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h @@ -40,6 +40,7 @@ #define PVR_SRV_BRIDGE_SRVCORE_CONNECT 0UL #define PVR_SRV_BRIDGE_SRVCORE_DISCONNECT 1UL +#define PVR_SRV_BRIDGE_SRVCORE_GETMULTICOREINFO 12U #define PVR_SRV_BRIDGE_SYNC 2UL @@ -175,6 +176,21 @@ struct pvr_srv_bridge_disconnect_ret { enum pvr_srv_error error; } PACKED; +/****************************************************************************** + PVR_SRV_BRIDGE_SRVCORE_GETMULTICOREINFO structs + ******************************************************************************/ + +struct pvr_srv_bridge_getmulticoreinfo_cmd { + uint64_t *caps; + uint32_t caps_size; +} PACKED; + +struct pvr_srv_bridge_getmulticoreinfo_ret { + uint64_t *caps; + enum pvr_srv_error error; + uint32_t num_cores; +} PACKED; + /****************************************************************************** PVR_SRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK struct ******************************************************************************/ @@ -711,6 +727,11 @@ struct drm_srvkm_cmd { VkResult pvr_srv_connection_create(int fd, uint64_t *const bvnc_out); void pvr_srv_connection_destroy(int fd); +VkResult pvr_srv_get_multicore_info(int fd, + uint32_t caps_size, + uint64_t *caps, + uint32_t *num_cores); + VkResult pvr_srv_alloc_sync_primitive_block(int fd, void **const handle_out, void **const pmr_out,