anv: Split dispatch tables into device and instance

There's no reason why we need generate trampoline functions for instance
functions or carry N copies of the instance dispatch table around for
every hardware generation.  Splitting the tables and being more
conservative shaves about 34K off .text and about 4K off .data when
built with clang.

Before splitting dispatch tables:

   text	   data	    bss	    dec	    hex	filename
3224305	 286216	   8960	3519481	 35b3f9	_install/lib64/libvulkan_intel.so

After splitting dispatch tables:

   text	   data	    bss	    dec	    hex	filename
3190325	 282232	   8960	3481517	 351fad	_install/lib64/libvulkan_intel.so

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
Jason Ekstrand
2018-10-13 12:16:14 -05:00
parent 18cc65edf8
commit ae18c53ba6
3 changed files with 232 additions and 93 deletions

View File

@@ -637,14 +637,28 @@ VkResult anv_CreateInstance(
/* Vulkan requires that entrypoints for extensions which have not been
* enabled must not be advertised.
*/
if (!anv_entrypoint_is_enabled(i, instance->app_info.api_version,
&instance->enabled_extensions, NULL)) {
if (!anv_instance_entrypoint_is_enabled(i, instance->app_info.api_version,
&instance->enabled_extensions)) {
instance->dispatch.entrypoints[i] = NULL;
} else if (anv_dispatch_table.entrypoints[i] != NULL) {
instance->dispatch.entrypoints[i] = anv_dispatch_table.entrypoints[i];
} else {
instance->dispatch.entrypoints[i] =
anv_tramp_dispatch_table.entrypoints[i];
anv_instance_dispatch_table.entrypoints[i];
}
}
for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) {
/* Vulkan requires that entrypoints for extensions which have not been
* enabled must not be advertised.
*/
if (!anv_device_entrypoint_is_enabled(i, instance->app_info.api_version,
&instance->enabled_extensions, NULL)) {
instance->device_dispatch.entrypoints[i] = NULL;
} else if (anv_device_dispatch_table.entrypoints[i] != NULL) {
instance->device_dispatch.entrypoints[i] =
anv_device_dispatch_table.entrypoints[i];
} else {
instance->device_dispatch.entrypoints[i] =
anv_tramp_device_dispatch_table.entrypoints[i];
}
}
@@ -1349,11 +1363,15 @@ PFN_vkVoidFunction anv_GetInstanceProcAddr(
if (instance == NULL)
return NULL;
int idx = anv_get_entrypoint_index(pName);
if (idx < 0)
return NULL;
int idx = anv_get_instance_entrypoint_index(pName);
if (idx >= 0)
return instance->dispatch.entrypoints[idx];
return instance->dispatch.entrypoints[idx];
idx = anv_get_device_entrypoint_index(pName);
if (idx >= 0)
return instance->device_dispatch.entrypoints[idx];
return NULL;
}
/* With version 1+ of the loader interface the ICD should expose
@@ -1381,7 +1399,7 @@ PFN_vkVoidFunction anv_GetDeviceProcAddr(
if (!device || !pName)
return NULL;
int idx = anv_get_entrypoint_index(pName);
int idx = anv_get_device_entrypoint_index(pName);
if (idx < 0)
return NULL;
@@ -1531,25 +1549,25 @@ VkResult anv_EnumerateDeviceExtensionProperties(
static void
anv_device_init_dispatch(struct anv_device *device)
{
const struct anv_dispatch_table *genX_table;
const struct anv_device_dispatch_table *genX_table;
switch (device->info.gen) {
case 11:
genX_table = &gen11_dispatch_table;
genX_table = &gen11_device_dispatch_table;
break;
case 10:
genX_table = &gen10_dispatch_table;
genX_table = &gen10_device_dispatch_table;
break;
case 9:
genX_table = &gen9_dispatch_table;
genX_table = &gen9_device_dispatch_table;
break;
case 8:
genX_table = &gen8_dispatch_table;
genX_table = &gen8_device_dispatch_table;
break;
case 7:
if (device->info.is_haswell)
genX_table = &gen75_dispatch_table;
genX_table = &gen75_device_dispatch_table;
else
genX_table = &gen7_dispatch_table;
genX_table = &gen7_device_dispatch_table;
break;
default:
unreachable("unsupported gen\n");
@@ -1559,14 +1577,15 @@ anv_device_init_dispatch(struct anv_device *device)
/* Vulkan requires that entrypoints for extensions which have not been
* enabled must not be advertised.
*/
if (!anv_entrypoint_is_enabled(i, device->instance->app_info.api_version,
&device->instance->enabled_extensions,
&device->enabled_extensions)) {
if (!anv_device_entrypoint_is_enabled(i, device->instance->app_info.api_version,
&device->instance->enabled_extensions,
&device->enabled_extensions)) {
device->dispatch.entrypoints[i] = NULL;
} else if (genX_table->entrypoints[i]) {
device->dispatch.entrypoints[i] = genX_table->entrypoints[i];
} else {
device->dispatch.entrypoints[i] = anv_dispatch_table.entrypoints[i];
device->dispatch.entrypoints[i] =
anv_device_dispatch_table.entrypoints[i];
}
}
}