static info_t get_info(int adapter_index, IDXGIAdapter* adapter) { struct ctx_t { DXGI_ADAPTER_DESC adapter_desc; info_t adapter_info; }; ctx_t ctx; adapter->GetDesc(&ctx.adapter_desc); // There's a new adapter called teh Basic Render Driver that is not a video driver, so // it won't show up with enumerate_video_drivers, so handle it explicitly here. if (ctx.adapter_desc.VendorId == 0x1414 && ctx.adapter_desc.DeviceId == 0x8c) // Microsoft Basic Render Driver { ctx.adapter_info.description = "Microsoft Basic Render Driver"; ctx.adapter_info.plugnplay_id = "Microsoft Basic Render Driver"; ctx.adapter_info.version = version_t(1,0); ctx.adapter_info.vendor = vendor::microsoft; ctx.adapter_info.feature_level = version_t(11,1); } else { detail::enumerate_video_drivers([](const info_t& info, void* user)->bool { auto& ctx = *(ctx_t*)user; char vendor[128]; char device[128]; snprintf(vendor, "VEN_%X", ctx.adapter_desc.VendorId); snprintf(device, "DEV_%04X", ctx.adapter_desc.DeviceId); if (strstr(info.plugnplay_id, vendor) && strstr(info.plugnplay_id, device)) { ctx.adapter_info = info; return false; } return true; }, &ctx); } *(int*)&ctx.adapter_info.id = adapter_index; D3D_FEATURE_LEVEL FeatureLevel; // Note that the out-device is null, thus this isn't that expensive a call if (SUCCEEDED(D3D11CreateDevice( adapter , D3D_DRIVER_TYPE_UNKNOWN , nullptr , 0 // D3D11_CREATE_DEVICE_DEBUG // squelches a _com_error warning , nullptr , 0 , D3D11_SDK_VERSION , nullptr , &FeatureLevel , nullptr))) ctx.adapter_info.feature_level = version_t((FeatureLevel>>12) & 0xff, (FeatureLevel>>8) & 0xf); return ctx.adapter_info; }
version_t minimum_version(const vendor& v) { switch (v) { case vendor::nvidia: return version_t(oNVVER_MAJOR, oNVVER_MINOR); case vendor::amd: return version_t(oAMDVER_MAJOR, oAMDVER_MINOR); default: break; } return version_t(); }
info_t find(const int2& virtual_desktop_position, const version_t& min_version, bool exact_version) { ref<IDXGIFactory> Factory; oV(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&Factory)); const bool LookForOutput = all(virtual_desktop_position != int2(oDEFAULT, oDEFAULT)); int adapter_index = 0; ref<IDXGIAdapter> adapter; while (DXGI_ERROR_NOT_FOUND != Factory->EnumAdapters(adapter_index, &adapter)) { adapter::info_t adapter_info = get_info(adapter_index, adapter); version_t required_version = min_version; if (required_version == version_t()) required_version = minimum_version(adapter_info.vendor); ref<IDXGIOutput> output; if (LookForOutput) { int o = 0; while (DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(o, &output)) { DXGI_OUTPUT_DESC od; output->GetDesc(&od); if (virtual_desktop_position.x >= od.DesktopCoordinates.left && virtual_desktop_position.x <= od.DesktopCoordinates.right && virtual_desktop_position.y >= od.DesktopCoordinates.top && virtual_desktop_position.y <= od.DesktopCoordinates.bottom) { sstring StrAdd, StrReq; to_string(StrReq, required_version); to_string(StrAdd, adapter_info.version); if (exact_version) oCheck(adapter_info.version == required_version, std::errc::no_such_device, "Exact video driver version %s required, but current driver is %s", StrReq.c_str(), StrAdd.c_str()); else oCheck(adapter_info.version >= required_version, std::errc::no_such_device, "Video driver version %s or newer required, but current driver is %s", StrReq.c_str(), StrAdd.c_str()); return adapter_info; } o++; output = nullptr; } } else if ((exact_version && adapter_info.version == required_version) || (!exact_version && adapter_info.version >= required_version)) return adapter_info; adapter_index++; adapter = nullptr; } sstring StrReq; to_string(StrReq, min_version); if (LookForOutput) oThrow(std::errc::no_such_device, "no adapter found for the specified virtual desktop coordinates that also matches the %s driver version %s", exact_version ? "exact" : "minimum", StrReq.c_str()); else oThrow(std::errc::no_such_device, "no adapter found matching the %s driver version %s", exact_version ? "exact" : "minimum", StrReq.c_str()); }
static version_t zero() { return version_t(nil_uuid(), state_timestamp_t::zero()); }
/** * Resolve the TPA assembly locations */ bool deps_resolver_t::resolve_tpa_list( pal::string_t* output, std::unordered_set<pal::string_t>* breadcrumb, bool ignore_missing_assemblies) { const std::vector<deps_entry_t> empty(0); name_to_resolved_asset_map_t items; auto process_entry = [&](const pal::string_t& deps_dir, const deps_entry_t& entry, int fx_level) -> bool { if (breadcrumb != nullptr && entry.is_serviceable) { breadcrumb->insert(entry.library_name + _X(",") + entry.library_version); breadcrumb->insert(entry.library_name); } // Ignore placeholders if (ends_with(entry.asset.relative_path, _X("/_._"), false)) { return true; } trace::info(_X("Processing TPA for deps entry [%s, %s, %s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str()); pal::string_t resolved_path; name_to_resolved_asset_map_t::iterator existing = items.find(entry.asset.name); if (existing == items.end()) { if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path)) { deps_resolved_asset_t resolved_asset(entry.asset, resolved_path); add_tpa_asset(resolved_asset, &items); return true; } return report_missing_assembly_in_manifest(entry, ignore_missing_assemblies); } else { // Verify the extension is the same as the previous verified entry if (get_deps_filename(entry.asset.relative_path) != get_filename(existing->second.resolved_path)) { trace::error( DuplicateAssemblyWithDifferentExtensionMessage.c_str(), entry.deps_file.c_str(), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str(), existing->second.resolved_path.c_str()); return false; } deps_resolved_asset_t* existing_entry = &existing->second; // If deps entry is same or newer than existing, then see if it should be replaced if (entry.asset.assembly_version > existing_entry->asset.assembly_version || (entry.asset.assembly_version == existing_entry->asset.assembly_version && entry.asset.file_version >= existing_entry->asset.file_version)) { if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path)) { // If the path is the same, then no need to replace if (resolved_path != existing_entry->resolved_path) { trace::verbose(_X("Replacing deps entry [%s, AssemblyVersion:%s, FileVersion:%s] with [%s, AssemblyVersion:%s, FileVersion:%s]"), existing_entry->resolved_path.c_str(), existing_entry->asset.assembly_version.as_str().c_str(), existing_entry->asset.file_version.as_str().c_str(), resolved_path.c_str(), entry.asset.assembly_version.as_str().c_str(), entry.asset.file_version.as_str().c_str()); existing_entry = nullptr; items.erase(existing); deps_asset_t asset(entry.asset.name, entry.asset.relative_path, entry.asset.assembly_version, entry.asset.file_version); deps_resolved_asset_t resolved_asset(asset, resolved_path); add_tpa_asset(resolved_asset, &items); } } else if (fx_level != 0) { // The framework is missing a newer package, so this is an error. // For compat, it is not an error for the app; this can occur for the main application assembly when using --depsfile // and the app assembly does not exist with the deps file. return report_missing_assembly_in_manifest(entry); } } return true; } }; // We do not support self-contained in a libhost scenario since in the self-contained scenario, // we cannot determine what assemblies are framework assemblies, and what assemblies are app-local assemblies. if (m_host_mode != host_mode_t::libhost) { // First add managed assembly to the TPA. // TODO: Remove: the deps should contain the managed DLL. // Workaround for: csc.deps.json doesn't have the csc.dll deps_asset_t asset(get_filename_without_ext(m_managed_app), get_filename(m_managed_app), version_t(), version_t()); deps_resolved_asset_t resolved_asset(asset, m_managed_app); add_tpa_asset(resolved_asset, &items); // Add the app's entries const auto& deps_entries = get_deps().get_entries(deps_entry_t::asset_types::runtime); for (const auto& entry : deps_entries) { if (!process_entry(m_app_dir, entry, 0)) { return false; } } // If the deps file wasn't present or has missing entries, then // add the app local assemblies to the TPA. This is only valid // in non-libhost scenarios (e.g. comhost). if (!get_deps().exists()) { // Obtain the local assemblies in the app dir. get_dir_assemblies(m_app_dir, _X("local"), &items); } } // There should be no additional deps files in a libhost scenario. // See comments during additional deps.json resolution. assert(m_additional_deps.empty() || m_host_mode != host_mode_t::libhost); // If additional deps files were specified that need to be treated as part of the // application, then add them to the mix as well. for (const auto& additional_deps : m_additional_deps) { auto additional_deps_entries = additional_deps->get_entries(deps_entry_t::asset_types::runtime); for (auto entry : additional_deps_entries) { if (!process_entry(m_app_dir, entry, 0)) { return false; } } } // Probe FX deps entries after app assemblies are added. for (int i = 1; i < m_fx_definitions.size(); ++i) { const auto& deps_entries = m_is_framework_dependent ? m_fx_definitions[i]->get_deps().get_entries(deps_entry_t::asset_types::runtime) : empty; for (const auto& entry : deps_entries) { if (!process_entry(m_fx_definitions[i]->get_dir(), entry, i)) { return false; } } } // Convert the paths into a string and return it for (const auto& item : items) { // Workaround for CoreFX not being able to resolve sym links. pal::string_t real_asset_path = item.second.resolved_path; pal::realpath(&real_asset_path); output->append(real_asset_path); output->push_back(PATH_SEPARATOR); } return true; }
version_t CSharedMemoryClient::sMGetVersion() { return version_t(0, 1); }