From 258487370fd840b018a404225277d74f74899c59 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 13 Sep 2017 03:09:48 +0200 Subject: vo_gpu: vulkan: generalize SPIR-V compiler In addition to the built-in nvidia compiler, we now also support a backend based on libshaderc. shaderc is sort of like glslang except it has a C API and is available as a dynamic library. The generated SPIR-V is now cached alongside the VkPipeline in the cached_program. We use a special cache header to ensure validity of this cache before passing it blindly to the vulkan implementation, since passing invalid SPIR-V can cause all sorts of nasty things. It's also designed to self-invalidate if the compiler gets better, by offering a catch-all `int compiler_version` that implementations can use as a cache invalidation marker. --- video/out/vulkan/utils.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'video/out/vulkan/utils.c') diff --git a/video/out/vulkan/utils.c b/video/out/vulkan/utils.c index 43e446bc36..659da9159a 100644 --- a/video/out/vulkan/utils.c +++ b/video/out/vulkan/utils.c @@ -1,5 +1,6 @@ #include +#include "video/out/gpu/spirv.h" #include "utils.h" #include "malloc.h" @@ -445,13 +446,12 @@ error: bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts) { assert(vk->physd); - - VkQueueFamilyProperties *qfs = NULL; - int qfnum; + void *tmp = talloc_new(NULL); // Enumerate the queue families and find suitable families for each task + int qfnum; vkGetPhysicalDeviceQueueFamilyProperties(vk->physd, &qfnum, NULL); - qfs = talloc_array(NULL, VkQueueFamilyProperties, qfnum); + VkQueueFamilyProperties *qfs = talloc_array(tmp, VkQueueFamilyProperties, qfnum); vkGetPhysicalDeviceQueueFamilyProperties(vk->physd, &qfnum, qfs); MP_VERBOSE(vk, "Queue families supported by device:\n"); @@ -503,20 +503,24 @@ bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts) .pQueuePriorities = priorities, }; - static const char *exts[] = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_NV_GLSL_SHADER_EXTENSION_NAME, - }; + const char **exts = NULL; + int num_exts = 0; + MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_SWAPCHAIN_EXTENSION_NAME); + if (vk->spirv->required_ext) + MP_TARRAY_APPEND(tmp, exts, num_exts, vk->spirv->required_ext); VkDeviceCreateInfo dinfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .queueCreateInfoCount = 1, .pQueueCreateInfos = &qinfo, .ppEnabledExtensionNames = exts, - .enabledExtensionCount = MP_ARRAY_SIZE(exts), + .enabledExtensionCount = num_exts, }; - MP_VERBOSE(vk, "Creating vulkan device...\n"); + MP_VERBOSE(vk, "Creating vulkan device with extensions:\n"); + for (int i = 0; i < num_exts; i++) + MP_VERBOSE(vk, " %s\n", exts[i]); + VK(vkCreateDevice(vk->physd, &dinfo, MPVK_ALLOCATOR, &vk->dev)); vk_malloc_init(vk); @@ -525,12 +529,12 @@ bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts) if (!vk_cmdpool_init(vk, qinfo, qfs[idx], &vk->pool)) goto error; - talloc_free(qfs); + talloc_free(tmp); return true; error: MP_ERR(vk, "Failed creating logical device!\n"); - talloc_free(qfs); + talloc_free(tmp); return false; } -- cgit v1.2.3