diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c index 19b94ed55e..394f99c70b 100644 --- a/video/out/d3d11/ra_d3d11.c +++ b/video/out/d3d11/ra_d3d11.c @@ -20,6 +20,13 @@ #define D3D11_1_UAV_SLOT_COUNT (64) #endif +struct dll_version { + uint16_t major; + uint16_t minor; + uint16_t build; + uint16_t revision; +}; + struct ra_d3d11 { struct spirv_compiler *spirv; @@ -29,6 +36,8 @@ struct ra_d3d11 { ID3D11DeviceContext1 *ctx1; pD3DCompile D3DCompile; + struct dll_version d3d_compiler_ver; + // Debug interfaces (--gpu-debug) ID3D11Debug *debug; ID3D11InfoQueue *iqueue; @@ -172,6 +181,14 @@ static struct d3d_fmt formats[] = { { "bgra8", 4, 4, { 8, 8, 8, 8}, DXFMT(B8G8R8A8, UNORM), .unordered = false }, }; +static bool dll_version_equal(struct dll_version a, struct dll_version b) +{ + return a.major == b.major && + a.minor == b.minor && + a.build == b.build && + a.revision == b.revision; +} + static DXGI_FORMAT fmt_to_dxgi(const struct ra_format *fmt) { struct d3d_fmt *d3d = fmt->priv; @@ -1346,13 +1363,15 @@ 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 = 1; +static const int cache_version = 2; struct cache_header { char magic[sizeof(cache_magic)]; int cache_version; char compiler[SPIRV_NAME_MAX_LEN]; - int compiler_version; + int spv_compiler_version; + uint32_t cross_version; + struct dll_version d3d_compiler_version; int feature_level; size_t vert_bytecode_len; size_t frag_bytecode_len; @@ -1381,7 +1400,11 @@ static void load_cached_program(struct ra *ra, return; if (strncmp(header->compiler, spirv->name, sizeof(header->compiler)) != 0) return; - if (header->compiler_version != spirv->compiler_version) + if (header->spv_compiler_version != spirv->compiler_version) + return; + if (header->cross_version != crossc_version()) + return; + if (!dll_version_equal(header->d3d_compiler_version, p->d3d_compiler_ver)) return; if (header->feature_level != p->fl) return; @@ -1415,7 +1438,9 @@ static void save_cached_program(struct ra *ra, struct ra_renderpass *pass, struct cache_header header = { .cache_version = cache_version, - .compiler_version = p->spirv->compiler_version, + .spv_compiler_version = p->spirv->compiler_version, + .cross_version = crossc_version(), + .d3d_compiler_version = p->d3d_compiler_ver, .feature_level = p->fl, .vert_bytecode_len = vert_bc.len, .frag_bytecode_len = frag_bc.len, @@ -2085,6 +2110,41 @@ static void init_debug_layer(struct ra *ra) ID3D11InfoQueue_PushStorageFilter(p->iqueue, &filter); } +static struct dll_version get_dll_version(HMODULE dll) +{ + void *ctx = talloc_new(NULL); + struct dll_version ret = { 0 }; + + HRSRC rsrc = FindResourceW(dll, MAKEINTRESOURCEW(VS_VERSION_INFO), + MAKEINTRESOURCEW(VS_FILE_INFO)); + if (!rsrc) + goto done; + DWORD size = SizeofResource(dll, rsrc); + HGLOBAL res = LoadResource(dll, rsrc); + if (!res) + goto done; + void *ptr = LockResource(res); + if (!ptr) + goto done; + void *copy = talloc_memdup(ctx, ptr, size); + + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + if (!VerQueryValueW(copy, L"\\", (void**)&ffi, &ffi_len)) + goto done; + if (ffi_len < sizeof(*ffi)) + goto done; + + ret.major = HIWORD(ffi->dwFileVersionMS); + ret.minor = LOWORD(ffi->dwFileVersionMS); + ret.build = HIWORD(ffi->dwFileVersionLS); + ret.revision = LOWORD(ffi->dwFileVersionLS); + +done: + talloc_free(ctx); + return ret; +} + static bool load_d3d_compiler(struct ra *ra) { struct ra_d3d11 *p = ra->priv; @@ -2108,6 +2168,8 @@ static bool load_d3d_compiler(struct ra *ra) if (!d3dcompiler) return false; + p->d3d_compiler_ver = get_dll_version(d3dcompiler); + p->D3DCompile = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); if (!p->D3DCompile) return false; @@ -2219,6 +2281,10 @@ struct ra *ra_d3d11_create(ID3D11Device *dev, struct mp_log *log, goto error; } + MP_VERBOSE(ra, "D3DCompiler version: %u.%u.%u.%u\n", + p->d3d_compiler_ver.major, p->d3d_compiler_ver.minor, + p->d3d_compiler_ver.build, p->d3d_compiler_ver.revision); + setup_formats(ra); // The rasterizer state never changes, so set it up here diff --git a/wscript b/wscript index 50cbccf2ce..de0a02ec5b 100644 --- a/wscript +++ b/wscript @@ -176,7 +176,7 @@ main_dependencies = [ 'name': 'win32-desktop', 'desc': 'win32 desktop APIs', 'deps': '(os-win32 || os-cygwin) && !uwp', - 'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi']), + 'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi', 'version']), }, { 'name': '--win32-internal-pthreads', 'desc': 'internal pthread wrapper for win32 (Vista+)',