mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
venus: emulate a second graphics queue on Android
Starting from Android 14 (Android U), framework HWUI has required a second graphics queue to avoid racing between webview and skiavk. For non-Android, we leave the second queue emulation behind a debug option. Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30985>
This commit is contained in:
parent
d92f9c3d51
commit
d0e02df3a6
6 changed files with 66 additions and 5 deletions
|
|
@ -32,6 +32,7 @@ static const struct debug_control vn_debug_options[] = {
|
|||
{ "cache", VN_DEBUG_CACHE },
|
||||
{ "no_sparse", VN_DEBUG_NO_SPARSE },
|
||||
{ "no_gpl", VN_DEBUG_NO_GPL },
|
||||
{ "second_queue", VN_DEBUG_SECOND_QUEUE },
|
||||
{ NULL, 0 },
|
||||
/* clang-format on */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ enum vn_debug {
|
|||
VN_DEBUG_CACHE = 1ull << 6,
|
||||
VN_DEBUG_NO_SPARSE = 1ull << 7,
|
||||
VN_DEBUG_NO_GPL = 1ull << 8,
|
||||
VN_DEBUG_SECOND_QUEUE = 1ull << 9,
|
||||
};
|
||||
|
||||
enum vn_perf {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ static VkResult
|
|||
vn_queue_init(struct vn_device *dev,
|
||||
struct vn_queue *queue,
|
||||
const VkDeviceQueueCreateInfo *queue_info,
|
||||
uint32_t queue_index)
|
||||
uint32_t queue_index,
|
||||
struct vn_queue *shared_queue)
|
||||
{
|
||||
VkResult result =
|
||||
vn_queue_base_init(&queue->base, &dev->base, queue_info, queue_index);
|
||||
|
|
@ -49,6 +50,16 @@ vn_queue_init(struct vn_device *dev,
|
|||
|
||||
vn_cached_storage_init(&queue->storage, &dev->base.base.alloc);
|
||||
|
||||
if (dev->physical_device->emulate_second_queue ==
|
||||
queue_info->queueFamilyIndex &&
|
||||
shared_queue != NULL) {
|
||||
assert(queue_index > 0);
|
||||
queue->emulated = true;
|
||||
queue->base.id = shared_queue->base.id;
|
||||
queue->ring_idx = shared_queue->ring_idx;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
const int ring_idx = vn_instance_acquire_ring_idx(dev->instance);
|
||||
if (ring_idx < 0) {
|
||||
vn_log(dev->instance, "failed binding VkQueue to renderer timeline");
|
||||
|
|
@ -92,13 +103,15 @@ vn_device_init_queues(struct vn_device *dev,
|
|||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
count = 0;
|
||||
struct vn_queue *shared_queue = NULL;
|
||||
for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
|
||||
VkResult result;
|
||||
|
||||
const VkDeviceQueueCreateInfo *queue_info =
|
||||
&create_info->pQueueCreateInfos[i];
|
||||
for (uint32_t j = 0; j < queue_info->queueCount; j++) {
|
||||
result = vn_queue_init(dev, &queues[count], queue_info, j);
|
||||
result =
|
||||
vn_queue_init(dev, &queues[count], queue_info, j, shared_queue);
|
||||
if (result != VK_SUCCESS) {
|
||||
for (uint32_t k = 0; k < count; k++)
|
||||
vn_queue_fini(&queues[k]);
|
||||
|
|
@ -107,7 +120,7 @@ vn_device_init_queues(struct vn_device *dev,
|
|||
return result;
|
||||
}
|
||||
|
||||
count++;
|
||||
shared_queue = &queues[count++];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,8 +483,25 @@ vn_device_init(struct vn_device *dev,
|
|||
if (group && group->physicalDeviceCount)
|
||||
dev->device_mask = (1 << group->physicalDeviceCount) - 1;
|
||||
|
||||
VkDeviceCreateInfo final_create_info = *create_info;
|
||||
STACK_ARRAY(VkDeviceQueueCreateInfo, queue_infos,
|
||||
create_info->queueCreateInfoCount);
|
||||
for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
|
||||
const VkDeviceQueueCreateInfo *queue_info =
|
||||
&create_info->pQueueCreateInfos[i];
|
||||
if (queue_info->queueFamilyIndex ==
|
||||
physical_dev->emulate_second_queue &&
|
||||
queue_info->queueCount == 2) {
|
||||
typed_memcpy(queue_infos, create_info->pQueueCreateInfos,
|
||||
create_info->queueCreateInfoCount);
|
||||
final_create_info.pQueueCreateInfos = queue_infos;
|
||||
queue_infos[i].queueCount = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = vn_call_vkCreateDevice(dev->primary_ring, physical_dev_handle,
|
||||
create_info, NULL, &dev_handle);
|
||||
&final_create_info, NULL, &dev_handle);
|
||||
STACK_ARRAY_FINISH(queue_infos);
|
||||
|
||||
/* free the fixed extensions here since no longer needed below */
|
||||
if (create_info == &local_create_info)
|
||||
|
|
@ -612,7 +642,8 @@ vn_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator)
|
|||
* are still bound to the queues in the renderer.
|
||||
*/
|
||||
for (uint32_t i = 0; i < dev->queue_count; i++) {
|
||||
vn_instance_release_ring_idx(dev->instance, dev->queues[i].ring_idx);
|
||||
if (!dev->queues[i].emulated)
|
||||
vn_instance_release_ring_idx(dev->instance, dev->queues[i].ring_idx);
|
||||
}
|
||||
|
||||
vk_free(alloc, dev->queues);
|
||||
|
|
|
|||
|
|
@ -678,6 +678,27 @@ vn_physical_device_init_queue_family_properties(
|
|||
vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(
|
||||
ring, vn_physical_device_to_handle(physical_dev), &count, props);
|
||||
|
||||
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 34
|
||||
/* Starting from Android 14 (Android U), framework HWUI has required a
|
||||
* second graphics queue to avoid racing between webview and skiavk.
|
||||
*/
|
||||
static const bool require_second_queue = true;
|
||||
#else
|
||||
const bool require_second_queue = VN_DEBUG(SECOND_QUEUE);
|
||||
#endif
|
||||
physical_dev->emulate_second_queue = -1;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (props[i].queueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
if (require_second_queue &&
|
||||
props[i].queueFamilyProperties.queueCount < 2) {
|
||||
props[i].queueFamilyProperties.queueCount = 2;
|
||||
physical_dev->emulate_second_queue = i;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter out queue families that exclusively support sparse binding as
|
||||
* we need additional support for submitting feedback commands
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@ struct vn_physical_device {
|
|||
VkQueueFamilyProperties2 *queue_family_properties;
|
||||
uint32_t queue_family_count;
|
||||
bool sparse_binding_disabled;
|
||||
/* Track the queue family index to emulate a second queue. -1 means no
|
||||
* emulation is needed.
|
||||
*/
|
||||
int emulate_second_queue;
|
||||
|
||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
struct vn_queue {
|
||||
struct vn_queue_base base;
|
||||
|
||||
/* emulated queue shares base queue id and ring_idx with another queue */
|
||||
bool emulated;
|
||||
|
||||
/* only used if renderer supports multiple timelines */
|
||||
uint32_t ring_idx;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue