From cc38035841692780883f9cec274617108c57670c Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Tue, 16 Apr 2019 18:18:50 +1000 Subject: vo_gpu: d3d11: use the SPIRV-Cross C API directly When the D3D11 backend was first written, SPIRV-Cross only had a C++ API and no guarantee of API or ABI stability, so instead of using SPIRV-Cross directly, mpv used an unofficial C wrapper called crossc. Now that KhronosGroup/SPIRV-Cross#611 is resolved, SPIRV-Cross has an official C API that can be used instead, so remove crossc and use SPIRV-Cross directly. --- video/out/d3d11/ra_d3d11.c | 86 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 19 deletions(-) (limited to 'video/out') diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c index 98c2d7d418..df9b3c0095 100644 --- a/video/out/d3d11/ra_d3d11.c +++ b/video/out/d3d11/ra_d3d11.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "common/msg.h" #include "osdep/io.h" @@ -1255,19 +1255,23 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type, struct ra_d3d11 *p = ra->priv; struct spirv_compiler *spirv = p->spirv; void *ta_ctx = talloc_new(NULL); - crossc_compiler *cross = NULL; + spvc_result sc_res = SPVC_SUCCESS; + spvc_context sc_ctx = NULL; + spvc_parsed_ir sc_ir = NULL; + spvc_compiler sc_compiler = NULL; + spvc_compiler_options sc_opts = NULL; const char *hlsl = NULL; ID3DBlob *errors = NULL; bool success = false; HRESULT hr; - int cross_shader_model; + int sc_shader_model; if (p->fl >= D3D_FEATURE_LEVEL_11_0) { - cross_shader_model = 50; + sc_shader_model = 50; } else if (p->fl >= D3D_FEATURE_LEVEL_10_1) { - cross_shader_model = 41; + sc_shader_model = 41; } else { - cross_shader_model = 40; + sc_shader_model = 40; } int64_t start_us = mp_time_us(); @@ -1278,17 +1282,42 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type, int64_t shaderc_us = mp_time_us(); - cross = crossc_hlsl_create((uint32_t*)spv_module.start, - spv_module.len / sizeof(uint32_t)); + sc_res = spvc_context_create(&sc_ctx); + if (sc_res != SPVC_SUCCESS) + goto done; + + sc_res = spvc_context_parse_spirv(sc_ctx, (SpvId *)spv_module.start, + spv_module.len / sizeof(SpvId), &sc_ir); + if (sc_res != SPVC_SUCCESS) + goto done; - crossc_hlsl_set_shader_model(cross, cross_shader_model); - crossc_set_flip_vert_y(cross, type == GLSL_SHADER_VERTEX); + sc_res = spvc_context_create_compiler(sc_ctx, SPVC_BACKEND_HLSL, sc_ir, + SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, + &sc_compiler); + if (sc_res != SPVC_SUCCESS) + goto done; - hlsl = crossc_compile(cross); - if (!hlsl) { - MP_ERR(ra, "SPIRV-Cross failed: %s\n", crossc_strerror(cross)); + sc_res = spvc_compiler_create_compiler_options(sc_compiler, &sc_opts); + if (sc_res != SPVC_SUCCESS) goto done; + sc_res = spvc_compiler_options_set_uint(sc_opts, + SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL, sc_shader_model); + if (sc_res != SPVC_SUCCESS) + goto done; + if (type == GLSL_SHADER_VERTEX) { + // FLIP_VERTEX_Y is only valid for vertex shaders + sc_res = spvc_compiler_options_set_bool(sc_opts, + SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, SPVC_TRUE); + if (sc_res != SPVC_SUCCESS) + goto done; } + sc_res = spvc_compiler_install_compiler_options(sc_compiler, sc_opts); + if (sc_res != SPVC_SUCCESS) + goto done; + + sc_res = spvc_compiler_compile(sc_compiler, &hlsl); + if (sc_res != SPVC_SUCCESS) + goto done; int64_t cross_us = mp_time_us(); @@ -1312,7 +1341,11 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type, d3dcompile_us - cross_us); success = true; -done:; +done: + if (sc_res != SPVC_SUCCESS) { + MP_MSG(ra, MSGL_ERR, "SPIRV-Cross failed: %s\n", + spvc_context_get_last_error_string(sc_ctx)); + } int level = success ? MSGL_DEBUG : MSGL_ERR; MP_MSG(ra, level, "GLSL source:\n"); mp_log_source(ra->log, level, glsl); @@ -1321,7 +1354,8 @@ done:; mp_log_source(ra->log, level, hlsl); } SAFE_RELEASE(errors); - crossc_destroy(cross); + if (sc_ctx) + spvc_context_destroy(sc_ctx); talloc_free(ta_ctx); return success; } @@ -1418,14 +1452,16 @@ static size_t vbuf_upload(struct ra *ra, void *data, size_t size) } static const char cache_magic[4] = "RD11"; -static const int cache_version = 2; +static const int cache_version = 3; struct cache_header { char magic[sizeof(cache_magic)]; int cache_version; char compiler[SPIRV_NAME_MAX_LEN]; int spv_compiler_version; - uint32_t cross_version; + unsigned spvc_compiler_major; + unsigned spvc_compiler_minor; + unsigned spvc_compiler_patch; struct dll_version d3d_compiler_version; int feature_level; size_t vert_bytecode_len; @@ -1449,6 +1485,9 @@ static void load_cached_program(struct ra *ra, struct cache_header *header = (struct cache_header *)cache.start; cache = bstr_cut(cache, sizeof(*header)); + unsigned spvc_major, spvc_minor, spvc_patch; + spvc_get_version(&spvc_major, &spvc_minor, &spvc_patch); + if (strncmp(header->magic, cache_magic, sizeof(cache_magic)) != 0) return; if (header->cache_version != cache_version) @@ -1457,7 +1496,11 @@ static void load_cached_program(struct ra *ra, return; if (header->spv_compiler_version != spirv->compiler_version) return; - if (header->cross_version != crossc_version()) + if (header->spvc_compiler_major != spvc_major) + return; + if (header->spvc_compiler_minor != spvc_minor) + return; + if (header->spvc_compiler_patch != spvc_patch) return; if (!dll_version_equal(header->d3d_compiler_version, p->d3d_compiler_ver)) return; @@ -1491,10 +1534,15 @@ static void save_cached_program(struct ra *ra, struct ra_renderpass *pass, struct ra_d3d11 *p = ra->priv; struct spirv_compiler *spirv = p->spirv; + unsigned spvc_major, spvc_minor, spvc_patch; + spvc_get_version(&spvc_major, &spvc_minor, &spvc_patch); + struct cache_header header = { .cache_version = cache_version, .spv_compiler_version = p->spirv->compiler_version, - .cross_version = crossc_version(), + .spvc_compiler_major = spvc_major, + .spvc_compiler_minor = spvc_minor, + .spvc_compiler_patch = spvc_patch, .d3d_compiler_version = p->d3d_compiler_ver, .feature_level = p->fl, .vert_bytecode_len = vert_bc.len, -- cgit v1.2.3