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/spirv_nvidia.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 video/out/vulkan/spirv_nvidia.c (limited to 'video/out/vulkan/spirv_nvidia.c') diff --git a/video/out/vulkan/spirv_nvidia.c b/video/out/vulkan/spirv_nvidia.c new file mode 100644 index 0000000000..6cc43a5619 --- /dev/null +++ b/video/out/vulkan/spirv_nvidia.c @@ -0,0 +1,54 @@ +#include "video/out/gpu/spirv.h" + +#include "common.h" +#include "context.h" +#include "utils.h" + +static bool nv_glsl_compile(struct spirv_compiler *spirv, void *tactx, + enum glsl_shader type, const char *glsl, + struct bstr *out_spirv) +{ + // The nvidia extension literally assumes your SPIRV is in fact valid GLSL + *out_spirv = bstr0(glsl); + return true; +} + +static bool nv_glsl_init(struct ra_ctx *ctx) +{ + struct mpvk_ctx *vk = ra_vk_ctx_get(ctx); + if (!vk) + return false; + + struct spirv_compiler *spv = ctx->spirv; + spv->required_ext = VK_NV_GLSL_SHADER_EXTENSION_NAME; + spv->glsl_version = 450; // impossible to query, so hard-code it.. + spv->ra_caps = RA_CAP_NESTED_ARRAY; + + // Make sure the extension is actually available, and fail gracefully + // if it isn't + VkExtensionProperties *props = NULL; + uint32_t extnum = 0; + VK(vkEnumerateDeviceExtensionProperties(vk->physd, NULL, &extnum, NULL)); + props = talloc_array(NULL, VkExtensionProperties, extnum); + VK(vkEnumerateDeviceExtensionProperties(vk->physd, NULL, &extnum, props)); + + bool ret = true; + for (int e = 0; e < extnum; e++) { + if (strncmp(props[e].extensionName, spv->required_ext, + VK_MAX_EXTENSION_NAME_SIZE) == 0) + goto done; + } + +error: + MP_VERBOSE(ctx, "Device doesn't support VK_NV_glsl_shader, skipping..\n"); + ret = false; + +done: + talloc_free(props); + return ret; +} + +const struct spirv_compiler_fns spirv_nvidia_builtin = { + .compile_glsl = nv_glsl_compile, + .init = nv_glsl_init, +}; -- cgit v1.2.3