#include "../util/util_math.h" #include "d3d9_options.h" #include "d3d9_caps.h" namespace dxvk { static int32_t parsePciId(const std::string& str) { if (str.size() != 4) return -1; int32_t id = 0; for (size_t i = 0; i < str.size(); i++) { id *= 16; if (str[i] >= '0' && str[i] <= '9') id += str[i] - '0'; else if (str[i] >= 'A' && str[i] <= 'F') id += str[i] - 'A' + 10; else if (str[i] >= 'a' && str[i] <= 'f') id += str[i] - 'a' + 10; else return -1; } return id; } D3D9Options::D3D9Options(const Rc& device, const Config& config) { const Rc adapter = device != nullptr ? device->adapter() : nullptr; // Fetch these as a string representing a hexadecimal number and parse it. this->customVendorId = parsePciId(config.getOption("d3d9.customVendorId")); this->customDeviceId = parsePciId(config.getOption("d3d9.customDeviceId")); this->customDeviceDesc = config.getOption("d3d9.customDeviceDesc"); const int32_t vendorId = this->customDeviceId != -1 ? this->customDeviceId : (adapter != nullptr ? adapter->deviceProperties().vendorID : 0); this->maxFrameLatency = config.getOption ("d3d9.maxFrameLatency", 0); this->maxFrameRate = config.getOption ("d3d9.maxFrameRate", 0); this->presentInterval = config.getOption ("d3d9.presentInterval", -1); this->shaderModel = config.getOption ("d3d9.shaderModel", 3); this->dpiAware = config.getOption ("d3d9.dpiAware", true); this->strictConstantCopies = config.getOption ("d3d9.strictConstantCopies", false); this->strictPow = config.getOption ("d3d9.strictPow", true); this->lenientClear = config.getOption ("d3d9.lenientClear", false); this->numBackBuffers = config.getOption ("d3d9.numBackBuffers", 0); this->deferSurfaceCreation = config.getOption ("d3d9.deferSurfaceCreation", false); this->samplerAnisotropy = config.getOption ("d3d9.samplerAnisotropy", -1); this->maxAvailableMemory = config.getOption ("d3d9.maxAvailableMemory", 4096); this->supportDFFormats = config.getOption ("d3d9.supportDFFormats", true); this->supportX4R4G4B4 = config.getOption ("d3d9.supportX4R4G4B4", true); this->supportD32 = config.getOption ("d3d9.supportD32", true); this->useD32forD24 = config.getOption ("d3d9.useD32forD24", false); this->disableA8RT = config.getOption ("d3d9.disableA8RT", false); this->invariantPosition = config.getOption ("d3d9.invariantPosition", true); this->memoryTrackTest = config.getOption ("d3d9.memoryTrackTest", false); this->supportVCache = config.getOption ("d3d9.supportVCache", vendorId == 0x10de); this->enableDialogMode = config.getOption ("d3d9.enableDialogMode", false); this->forceSamplerTypeSpecConstants = config.getOption ("d3d9.forceSamplerTypeSpecConstants", false); this->forceSwapchainMSAA = config.getOption ("d3d9.forceSwapchainMSAA", -1); this->forceSampleRateShading = config.getOption ("d3d9.forceSampleRateShading", false); this->forceAspectRatio = config.getOption ("d3d9.forceAspectRatio", ""); this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); this->longMad = config.getOption ("d3d9.longMad", false); this->cachedDynamicBuffers = config.getOption ("d3d9.cachedDynamicBuffers", false); this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); this->allowDirectBufferMapping = config.getOption ("d3d9.allowDirectBufferMapping", true); this->seamlessCubes = config.getOption ("d3d9.seamlessCubes", false); this->textureMemory = config.getOption ("d3d9.textureMemory", 100) << 20; this->deviceLossOnFocusLoss = config.getOption ("d3d9.deviceLossOnFocusLoss", false); this->samplerLodBias = config.getOption ("d3d9.samplerLodBias", 0.0f); this->clampNegativeLodBias = config.getOption ("d3d9.clampNegativeLodBias", false); this->countLosableResources = config.getOption ("d3d9.countLosableResources", true); // Clamp LOD bias so that people don't abuse this in unintended ways this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f); std::string floatEmulation = Config::toLower(config.getOption("d3d9.floatEmulation", "auto")); if (floatEmulation == "strict") { d3d9FloatEmulation = D3D9FloatEmulation::Strict; } else if (floatEmulation == "false") { d3d9FloatEmulation = D3D9FloatEmulation::Disabled; } else if (floatEmulation == "true") { d3d9FloatEmulation = D3D9FloatEmulation::Enabled; } else { bool hasMulz = adapter != nullptr && (adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, 0, 0) || adapter->matchesDriver(VK_DRIVER_ID_MESA_NVK, 0, 0)); d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled; } this->shaderDumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); } }