mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 13:50:11 +01:00
zink: deduplicate VkDevice and VkInstance
it's illegal to mix and match objects between different VkDevices even if the creation params are identical, and this can cause issues on some drivers Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33204>
This commit is contained in:
parent
a1333d60e9
commit
015eda4a41
5 changed files with 105 additions and 37 deletions
|
|
@ -585,7 +585,7 @@ zink_get_physical_device_info(struct zink_screen *screen)
|
||||||
%endif
|
%endif
|
||||||
%endfor
|
%endfor
|
||||||
|
|
||||||
if (screen->vk_version < VK_MAKE_VERSION(1,2,0) && screen->instance_info.have_KHR_external_memory_capabilities) {
|
if (screen->vk_version < VK_MAKE_VERSION(1,2,0) && screen->instance_info->have_KHR_external_memory_capabilities) {
|
||||||
info->deviceid_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
info->deviceid_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
||||||
info->deviceid_props.pNext = props.pNext;
|
info->deviceid_props.pNext = props.pNext;
|
||||||
props.pNext = &info->deviceid_props;
|
props.pNext = &info->deviceid_props;
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ struct zink_instance_info {
|
||||||
%endfor
|
%endfor
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
VkInstance
|
||||||
zink_create_instance(struct zink_screen *screen);
|
zink_create_instance(struct zink_screen *screen, struct zink_instance_info *instance_info);
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_verify_instance_extensions(struct zink_screen *screen);
|
zink_verify_instance_extensions(struct zink_screen *screen);
|
||||||
|
|
@ -128,11 +128,9 @@ impl_code = """
|
||||||
#include "zink_instance.h"
|
#include "zink_instance.h"
|
||||||
#include "zink_screen.h"
|
#include "zink_screen.h"
|
||||||
|
|
||||||
bool
|
VkInstance
|
||||||
zink_create_instance(struct zink_screen *screen)
|
zink_create_instance(struct zink_screen *screen, struct zink_instance_info *instance_info)
|
||||||
{
|
{
|
||||||
struct zink_instance_info *instance_info = &screen->instance_info;
|
|
||||||
|
|
||||||
/* reserve one slot for MoltenVK */
|
/* reserve one slot for MoltenVK */
|
||||||
const char *layers[${len(layers) + 1}] = {0};
|
const char *layers[${len(layers) + 1}] = {0};
|
||||||
uint32_t num_layers = 0;
|
uint32_t num_layers = 0;
|
||||||
|
|
@ -266,14 +264,14 @@ zink_create_instance(struct zink_screen *screen)
|
||||||
GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, CreateInstance);
|
GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, CreateInstance);
|
||||||
assert(vk_CreateInstance);
|
assert(vk_CreateInstance);
|
||||||
|
|
||||||
VkResult err = vk_CreateInstance(&ici, NULL, &screen->instance);
|
VkInstance instance;
|
||||||
|
VkResult err = vk_CreateInstance(&ici, NULL, &instance);
|
||||||
if (err != VK_SUCCESS) {
|
if (err != VK_SUCCESS) {
|
||||||
if (!screen->driver_name_is_inferred)
|
if (!screen->driver_name_is_inferred)
|
||||||
mesa_loge("ZINK: vkCreateInstance failed (%s)", vk_Result_to_str(err));
|
mesa_loge("ZINK: vkCreateInstance failed (%s)", vk_Result_to_str(err));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -284,7 +282,7 @@ zink_verify_instance_extensions(struct zink_screen *screen)
|
||||||
%if ext.platform_guard:
|
%if ext.platform_guard:
|
||||||
#ifdef ${ext.platform_guard}
|
#ifdef ${ext.platform_guard}
|
||||||
%endif
|
%endif
|
||||||
if (screen->instance_info.have_${ext.name_with_vendor()}) {
|
if (screen->instance_info->have_${ext.name_with_vendor()}) {
|
||||||
%for cmd in registry.get_registry_entry(ext.name).instance_commands:
|
%for cmd in registry.get_registry_entry(ext.name).instance_commands:
|
||||||
if (!screen->vk.${cmd.lstrip("vk")}) {
|
if (!screen->vk.${cmd.lstrip("vk")}) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
||||||
|
|
@ -2440,7 +2440,7 @@ overwrite:
|
||||||
// This is a known limitation of MoltenVK.
|
// This is a known limitation of MoltenVK.
|
||||||
// See https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/MoltenVK_Runtime_UserGuide.md#known-moltenvk-limitations
|
// See https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/MoltenVK_Runtime_UserGuide.md#known-moltenvk-limitations
|
||||||
|
|
||||||
|| screen->instance_info.have_MVK_moltenvk
|
|| screen->instance_info->have_MVK_moltenvk
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
VkDeviceSize size = box->width;
|
VkDeviceSize size = box->width;
|
||||||
|
|
@ -3230,7 +3230,7 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
|
||||||
if (screen->info.have_EXT_external_memory_host) {
|
if (screen->info.have_EXT_external_memory_host) {
|
||||||
pscreen->resource_from_user_memory = zink_resource_from_user_memory;
|
pscreen->resource_from_user_memory = zink_resource_from_user_memory;
|
||||||
}
|
}
|
||||||
if (screen->instance_info.have_KHR_external_memory_capabilities) {
|
if (screen->instance_info->have_KHR_external_memory_capabilities) {
|
||||||
pscreen->memobj_create_from_handle = zink_memobj_create_from_handle;
|
pscreen->memobj_create_from_handle = zink_memobj_create_from_handle;
|
||||||
pscreen->memobj_destroy = zink_memobj_destroy;
|
pscreen->memobj_destroy = zink_memobj_destroy;
|
||||||
pscreen->resource_from_memobj = zink_resource_from_memobj;
|
pscreen->resource_from_memobj = zink_resource_from_memobj;
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,21 @@ DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descr
|
||||||
|
|
||||||
enum zink_descriptor_mode zink_descriptor_mode;
|
enum zink_descriptor_mode zink_descriptor_mode;
|
||||||
|
|
||||||
|
struct zink_device {
|
||||||
|
unsigned refcount;
|
||||||
|
VkPhysicalDevice pdev;
|
||||||
|
VkDevice dev;
|
||||||
|
struct zink_device_info *info;
|
||||||
|
};
|
||||||
|
|
||||||
|
static simple_mtx_t device_lock = SIMPLE_MTX_INITIALIZER;
|
||||||
|
static struct set device_table;
|
||||||
|
|
||||||
|
static simple_mtx_t instance_lock = SIMPLE_MTX_INITIALIZER;
|
||||||
|
static struct zink_instance_info instance_info;
|
||||||
|
static unsigned instance_refcount;
|
||||||
|
static VkInstance instance;
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
zink_get_vendor(struct pipe_screen *pscreen)
|
zink_get_vendor(struct pipe_screen *pscreen)
|
||||||
{
|
{
|
||||||
|
|
@ -793,14 +808,14 @@ zink_init_screen_caps(struct zink_screen *screen)
|
||||||
caps->fbfetch_coherent = screen->info.have_EXT_rasterization_order_attachment_access;
|
caps->fbfetch_coherent = screen->info.have_EXT_rasterization_order_attachment_access;
|
||||||
|
|
||||||
caps->memobj =
|
caps->memobj =
|
||||||
screen->instance_info.have_KHR_external_memory_capabilities &&
|
screen->instance_info->have_KHR_external_memory_capabilities &&
|
||||||
(screen->info.have_KHR_external_memory_fd ||
|
(screen->info.have_KHR_external_memory_fd ||
|
||||||
screen->info.have_KHR_external_memory_win32);
|
screen->info.have_KHR_external_memory_win32);
|
||||||
caps->fence_signal =
|
caps->fence_signal =
|
||||||
screen->info.have_KHR_external_semaphore_fd ||
|
screen->info.have_KHR_external_semaphore_fd ||
|
||||||
screen->info.have_KHR_external_semaphore_win32;
|
screen->info.have_KHR_external_semaphore_win32;
|
||||||
caps->native_fence_fd =
|
caps->native_fence_fd =
|
||||||
screen->instance_info.have_KHR_external_semaphore_capabilities &&
|
screen->instance_info->have_KHR_external_semaphore_capabilities &&
|
||||||
screen->info.have_KHR_external_semaphore_fd;
|
screen->info.have_KHR_external_semaphore_fd;
|
||||||
caps->resource_from_user_memory = screen->info.have_EXT_external_memory_host;
|
caps->resource_from_user_memory = screen->info.have_EXT_external_memory_host;
|
||||||
|
|
||||||
|
|
@ -1175,7 +1190,7 @@ zink_init_screen_caps(struct zink_screen *screen)
|
||||||
|
|
||||||
caps->post_depth_coverage = screen->info.have_EXT_post_depth_coverage;
|
caps->post_depth_coverage = screen->info.have_EXT_post_depth_coverage;
|
||||||
|
|
||||||
caps->string_marker = screen->instance_info.have_EXT_debug_utils;
|
caps->string_marker = screen->instance_info->have_EXT_debug_utils;
|
||||||
|
|
||||||
caps->min_line_width =
|
caps->min_line_width =
|
||||||
caps->min_line_width_aa =
|
caps->min_line_width_aa =
|
||||||
|
|
@ -1550,11 +1565,31 @@ zink_destroy_screen(struct pipe_screen *pscreen)
|
||||||
if (screen->bindless_layout)
|
if (screen->bindless_layout)
|
||||||
VKSCR(DestroyDescriptorSetLayout)(screen->dev, screen->bindless_layout, NULL);
|
VKSCR(DestroyDescriptorSetLayout)(screen->dev, screen->bindless_layout, NULL);
|
||||||
|
|
||||||
if (screen->dev)
|
if (screen->dev) {
|
||||||
VKSCR(DestroyDevice)(screen->dev, NULL);
|
simple_mtx_lock(&device_lock);
|
||||||
|
set_foreach(&device_table, entry) {
|
||||||
|
struct zink_device *zdev = (void*)entry->key;
|
||||||
|
if (zdev->pdev == screen->pdev) {
|
||||||
|
zdev->refcount--;
|
||||||
|
if (!zdev->refcount) {
|
||||||
|
VKSCR(DestroyDevice)(zdev->dev, NULL);
|
||||||
|
_mesa_set_remove(&device_table, entry);
|
||||||
|
free(zdev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!device_table.entries) {
|
||||||
|
ralloc_free(device_table.table);
|
||||||
|
device_table.table = NULL;
|
||||||
|
}
|
||||||
|
simple_mtx_unlock(&device_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (screen->instance)
|
simple_mtx_lock(&instance_lock);
|
||||||
VKSCR(DestroyInstance)(screen->instance, NULL);
|
if (screen->instance && --instance_refcount == 0)
|
||||||
|
VKSCR(DestroyInstance)(instance, NULL);
|
||||||
|
simple_mtx_unlock(&instance_lock);
|
||||||
|
|
||||||
util_idalloc_mt_fini(&screen->buffer_ids);
|
util_idalloc_mt_fini(&screen->buffer_ids);
|
||||||
|
|
||||||
|
|
@ -1705,7 +1740,7 @@ choose_pdev(struct zink_screen *screen, int64_t dev_major, int64_t dev_minor, ui
|
||||||
screen->info.device_version = screen->info.props.apiVersion;
|
screen->info.device_version = screen->info.props.apiVersion;
|
||||||
|
|
||||||
/* runtime version is the lesser of the instance version and device version */
|
/* runtime version is the lesser of the instance version and device version */
|
||||||
screen->vk_version = MIN2(screen->info.device_version, screen->instance_info.loader_version);
|
screen->vk_version = MIN2(screen->info.device_version, screen->instance_info->loader_version);
|
||||||
|
|
||||||
/* calculate SPIR-V version based on VK version */
|
/* calculate SPIR-V version based on VK version */
|
||||||
if (screen->vk_version >= VK_MAKE_VERSION(1, 3, 0))
|
if (screen->vk_version >= VK_MAKE_VERSION(1, 3, 0))
|
||||||
|
|
@ -2008,7 +2043,7 @@ zink_internal_setup_moltenvk(struct zink_screen *screen)
|
||||||
// disable unless we can get MoltenVK to confirm it is supported
|
// disable unless we can get MoltenVK to confirm it is supported
|
||||||
screen->have_dynamic_state_vertex_input_binding_stride = false;
|
screen->have_dynamic_state_vertex_input_binding_stride = false;
|
||||||
|
|
||||||
if (!screen->instance_info.have_MVK_moltenvk)
|
if (!screen->instance_info->have_MVK_moltenvk)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetMoltenVKConfigurationMVK);
|
GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetMoltenVKConfigurationMVK);
|
||||||
|
|
@ -2648,10 +2683,40 @@ hack_it_up:
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkDevice
|
static VkDevice
|
||||||
zink_create_logical_device(struct zink_screen *screen)
|
get_device(struct zink_screen *screen, VkDeviceCreateInfo *dci)
|
||||||
{
|
{
|
||||||
VkDevice dev = VK_NULL_HANDLE;
|
VkDevice dev = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
simple_mtx_lock(&device_lock);
|
||||||
|
|
||||||
|
if (!device_table.table)
|
||||||
|
_mesa_set_init(&device_table, NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
|
||||||
|
|
||||||
|
set_foreach(&device_table, entry) {
|
||||||
|
struct zink_device *zdev = (void*)entry->key;
|
||||||
|
if (zdev->pdev != screen->pdev)
|
||||||
|
continue;
|
||||||
|
zdev->refcount++;
|
||||||
|
simple_mtx_unlock(&device_lock);
|
||||||
|
return zdev->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult result = VKSCR(CreateDevice)(screen->pdev, dci, NULL, &dev);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
mesa_loge("ZINK: vkCreateDevice failed (%s)", vk_Result_to_str(result));
|
||||||
|
|
||||||
|
struct zink_device *zdev = malloc(sizeof(struct zink_device));
|
||||||
|
zdev->refcount = 1;
|
||||||
|
zdev->pdev = screen->pdev;
|
||||||
|
zdev->dev = dev;
|
||||||
|
_mesa_set_add(&device_table, zdev);
|
||||||
|
simple_mtx_unlock(&device_lock);
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkDevice
|
||||||
|
zink_create_logical_device(struct zink_screen *screen)
|
||||||
|
{
|
||||||
VkDeviceQueueCreateInfo qci[2] = {0};
|
VkDeviceQueueCreateInfo qci[2] = {0};
|
||||||
uint32_t queues[3] = {
|
uint32_t queues[3] = {
|
||||||
screen->gfx_queue,
|
screen->gfx_queue,
|
||||||
|
|
@ -2685,11 +2750,7 @@ zink_create_logical_device(struct zink_screen *screen)
|
||||||
dci.ppEnabledExtensionNames = screen->info.extensions;
|
dci.ppEnabledExtensionNames = screen->info.extensions;
|
||||||
dci.enabledExtensionCount = screen->info.num_extensions;
|
dci.enabledExtensionCount = screen->info.num_extensions;
|
||||||
|
|
||||||
VkResult result = VKSCR(CreateDevice)(screen->pdev, &dci, NULL, &dev);
|
return get_device(screen, &dci);
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
mesa_loge("ZINK: vkCreateDevice failed (%s)", vk_Result_to_str(result));
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -3258,7 +3319,6 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->instance_info.loader_version = zink_get_loader_version(screen);
|
|
||||||
if (config) {
|
if (config) {
|
||||||
driParseConfigFiles(config->options, config->options_info, 0, "zink",
|
driParseConfigFiles(config->options, config->options_info, 0, "zink",
|
||||||
NULL, NULL, NULL, 0, NULL, 0);
|
NULL, NULL, NULL, 0, NULL, 0);
|
||||||
|
|
@ -3268,12 +3328,22 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
|
||||||
screen->driconf.zink_shader_object_enable = driQueryOptionb(config->options, "zink_shader_object_enable");
|
screen->driconf.zink_shader_object_enable = driQueryOptionb(config->options, "zink_shader_object_enable");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zink_create_instance(screen))
|
simple_mtx_lock(&instance_lock);
|
||||||
|
if (++instance_refcount == 1) {
|
||||||
|
instance_info.loader_version = zink_get_loader_version(screen);
|
||||||
|
instance = zink_create_instance(screen, &instance_info);
|
||||||
|
if (!instance)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
} else {
|
||||||
|
assert(instance);
|
||||||
|
}
|
||||||
|
screen->instance = instance;
|
||||||
|
screen->instance_info = &instance_info;
|
||||||
|
simple_mtx_unlock(&instance_lock);
|
||||||
|
|
||||||
if (zink_debug & ZINK_DEBUG_VALIDATION) {
|
if (zink_debug & ZINK_DEBUG_VALIDATION) {
|
||||||
if (!screen->instance_info.have_layer_KHRONOS_validation &&
|
if (!screen->instance_info->have_layer_KHRONOS_validation &&
|
||||||
!screen->instance_info.have_layer_LUNARG_standard_validation) {
|
!screen->instance_info->have_layer_LUNARG_standard_validation) {
|
||||||
if (!screen->driver_name_is_inferred)
|
if (!screen->driver_name_is_inferred)
|
||||||
mesa_loge("Failed to load validation layer");
|
mesa_loge("Failed to load validation layer");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -3289,7 +3359,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
|
||||||
|
|
||||||
zink_verify_instance_extensions(screen);
|
zink_verify_instance_extensions(screen);
|
||||||
|
|
||||||
if (screen->instance_info.have_EXT_debug_utils &&
|
if (screen->instance_info->have_EXT_debug_utils &&
|
||||||
(zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen)) {
|
(zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen)) {
|
||||||
if (!screen->driver_name_is_inferred)
|
if (!screen->driver_name_is_inferred)
|
||||||
debug_printf("ZINK: failed to setup debug utils\n");
|
debug_printf("ZINK: failed to setup debug utils\n");
|
||||||
|
|
@ -3438,7 +3508,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
|
||||||
util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state);
|
util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state);
|
||||||
|
|
||||||
screen->base.get_name = zink_get_name;
|
screen->base.get_name = zink_get_name;
|
||||||
if (screen->instance_info.have_KHR_external_memory_capabilities) {
|
if (screen->instance_info->have_KHR_external_memory_capabilities) {
|
||||||
screen->base.get_device_uuid = zink_get_device_uuid;
|
screen->base.get_device_uuid = zink_get_device_uuid;
|
||||||
screen->base.get_driver_uuid = zink_get_driver_uuid;
|
screen->base.get_driver_uuid = zink_get_driver_uuid;
|
||||||
}
|
}
|
||||||
|
|
@ -3650,7 +3720,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
|
||||||
init_optimal_keys(screen);
|
init_optimal_keys(screen);
|
||||||
|
|
||||||
screen->screen_id = p_atomic_inc_return(&num_screens);
|
screen->screen_id = p_atomic_inc_return(&num_screens);
|
||||||
zink_tracing = screen->instance_info.have_EXT_debug_utils &&
|
zink_tracing = screen->instance_info->have_EXT_debug_utils &&
|
||||||
(u_trace_is_enabled(U_TRACE_TYPE_PERFETTO) || u_trace_is_enabled(U_TRACE_TYPE_MARKERS));
|
(u_trace_is_enabled(U_TRACE_TYPE_PERFETTO) || u_trace_is_enabled(U_TRACE_TYPE_MARKERS));
|
||||||
|
|
||||||
screen->frame_marker_emitted = zink_screen_debug_marker_begin(screen, "frame");
|
screen->frame_marker_emitted = zink_screen_debug_marker_begin(screen, "frame");
|
||||||
|
|
|
||||||
|
|
@ -1461,7 +1461,7 @@ struct zink_screen {
|
||||||
uint64_t mapped_vram;
|
uint64_t mapped_vram;
|
||||||
|
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
struct zink_instance_info instance_info;
|
const struct zink_instance_info *instance_info;
|
||||||
|
|
||||||
struct hash_table *debug_mem_sizes;
|
struct hash_table *debug_mem_sizes;
|
||||||
simple_mtx_t debug_mem_lock;
|
simple_mtx_t debug_mem_lock;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue