mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-07 16:54:14 +01:00
[dxbc] Make DxbcOptions a set of flags
This allows for game-specific workarounds and driver-specific workarounds to be applied in an easier fashion.
This commit is contained in:
parent
cfcca11fc5
commit
e53cb72e39
@ -86,7 +86,8 @@ namespace dxvk {
|
|||||||
m_dxvkDevice (pDxgiDevice->GetDXVKDevice()),
|
m_dxvkDevice (pDxgiDevice->GetDXVKDevice()),
|
||||||
m_dxvkAdapter (m_dxvkDevice->adapter()),
|
m_dxvkAdapter (m_dxvkDevice->adapter()),
|
||||||
m_d3d11Options (D3D11GetAppOptions(env::getExeName())),
|
m_d3d11Options (D3D11GetAppOptions(env::getExeName())),
|
||||||
m_dxbcOptions (m_dxvkDevice) {
|
m_dxbcOptions (getDxbcAppOptions(env::getExeName()) |
|
||||||
|
getDxbcDeviceOptions(m_dxvkDevice)) {
|
||||||
Com<IDXGIAdapter> adapter;
|
Com<IDXGIAdapter> adapter;
|
||||||
|
|
||||||
if (FAILED(pDxgiDevice->GetAdapter(&adapter))
|
if (FAILED(pDxgiDevice->GetAdapter(&adapter))
|
||||||
|
@ -769,7 +769,7 @@ namespace dxvk {
|
|||||||
const bool isUav = ins.op == DxbcOpcode::DclUavTyped;
|
const bool isUav = ins.op == DxbcOpcode::DclUavTyped;
|
||||||
|
|
||||||
if (isUav) {
|
if (isUav) {
|
||||||
if (m_options.useStorageImageReadWithoutFormat)
|
if (m_options.test(DxbcOption::UseStorageImageReadWithoutFormat))
|
||||||
m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
||||||
m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
||||||
}
|
}
|
||||||
@ -846,7 +846,7 @@ namespace dxvk {
|
|||||||
if (isUav) {
|
if (isUav) {
|
||||||
if ((m_analysis->uavInfos[registerId].accessAtomicOp)
|
if ((m_analysis->uavInfos[registerId].accessAtomicOp)
|
||||||
|| (m_analysis->uavInfos[registerId].accessTypedLoad
|
|| (m_analysis->uavInfos[registerId].accessTypedLoad
|
||||||
&& !m_options.useStorageImageReadWithoutFormat))
|
&& !m_options.test(DxbcOption::UseStorageImageReadWithoutFormat)))
|
||||||
imageFormat = getScalarImageFormat(sampledType);
|
imageFormat = getScalarImageFormat(sampledType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1391,13 +1391,13 @@ namespace dxvk {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DxbcOpcode::Max:
|
case DxbcOpcode::Max:
|
||||||
dst.id = m_options.useSimpleMinMaxClamp
|
dst.id = m_options.test(DxbcOption::UseSimpleMinMaxClamp)
|
||||||
? m_module.opFMax(typeId, src.at(0).id, src.at(1).id)
|
? m_module.opFMax(typeId, src.at(0).id, src.at(1).id)
|
||||||
: m_module.opNMax(typeId, src.at(0).id, src.at(1).id);
|
: m_module.opNMax(typeId, src.at(0).id, src.at(1).id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DxbcOpcode::Min:
|
case DxbcOpcode::Min:
|
||||||
dst.id = m_options.useSimpleMinMaxClamp
|
dst.id = m_options.test(DxbcOption::UseSimpleMinMaxClamp)
|
||||||
? m_module.opFMin(typeId, src.at(0).id, src.at(1).id)
|
? m_module.opFMin(typeId, src.at(0).id, src.at(1).id)
|
||||||
: m_module.opNMin(typeId, src.at(0).id, src.at(1).id);
|
: m_module.opNMin(typeId, src.at(0).id, src.at(1).id);
|
||||||
break;
|
break;
|
||||||
@ -2952,7 +2952,7 @@ namespace dxvk {
|
|||||||
DxbcRegMask(true, false, false, false))
|
DxbcRegMask(true, false, false, false))
|
||||||
: DxbcRegisterValue();
|
: DxbcRegisterValue();
|
||||||
|
|
||||||
if (isDepthCompare && m_options.addExtraDrefCoordComponent && coord.type.ccount < 4)
|
if (isDepthCompare && m_options.test(DxbcOption::AddExtraDrefCoordComponent) && coord.type.ccount < 4)
|
||||||
coord = emitRegisterConcat(coord, referenceValue);
|
coord = emitRegisterConcat(coord, referenceValue);
|
||||||
|
|
||||||
// Determine the sampled image type based on the opcode.
|
// Determine the sampled image type based on the opcode.
|
||||||
@ -3064,7 +3064,7 @@ namespace dxvk {
|
|||||||
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
||||||
: DxbcRegisterValue();
|
: DxbcRegisterValue();
|
||||||
|
|
||||||
if (isDepthCompare && m_options.addExtraDrefCoordComponent && coord.type.ccount < 4)
|
if (isDepthCompare && m_options.test(DxbcOption::AddExtraDrefCoordComponent) && coord.type.ccount < 4)
|
||||||
coord = emitRegisterConcat(coord, referenceValue);
|
coord = emitRegisterConcat(coord, referenceValue);
|
||||||
|
|
||||||
// Load explicit gradients for sample operations that require them
|
// Load explicit gradients for sample operations that require them
|
||||||
@ -3952,7 +3952,7 @@ namespace dxvk {
|
|||||||
const DxbcRegisterValue vec0 = emitBuildConstVecf32(0.0f, 0.0f, 0.0f, 0.0f, mask);
|
const DxbcRegisterValue vec0 = emitBuildConstVecf32(0.0f, 0.0f, 0.0f, 0.0f, mask);
|
||||||
const DxbcRegisterValue vec1 = emitBuildConstVecf32(1.0f, 1.0f, 1.0f, 1.0f, mask);
|
const DxbcRegisterValue vec1 = emitBuildConstVecf32(1.0f, 1.0f, 1.0f, 1.0f, mask);
|
||||||
|
|
||||||
value.id = m_options.useSimpleMinMaxClamp
|
value.id = m_options.test(DxbcOption::UseSimpleMinMaxClamp)
|
||||||
? m_module.opFClamp(typeId, value.id, vec0.id, vec1.id)
|
? m_module.opFClamp(typeId, value.id, vec0.id, vec1.id)
|
||||||
: m_module.opNClamp(typeId, value.id, vec0.id, vec1.id);
|
: m_module.opNClamp(typeId, value.id, vec0.id, vec1.id);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,41 @@
|
|||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "dxbc_options.h"
|
#include "dxbc_options.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxbcOptions::DxbcOptions(const Rc<DxvkDevice>& device) {
|
const static std::unordered_map<std::string, DxbcOptions> g_dxbcAppOptions = {{
|
||||||
|
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
DxbcOptions getDxbcAppOptions(const std::string& appName) {
|
||||||
|
auto appOptions = g_dxbcAppOptions.find(appName);
|
||||||
|
|
||||||
|
return appOptions != g_dxbcAppOptions.end()
|
||||||
|
? appOptions->second
|
||||||
|
: DxbcOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcOptions getDxbcDeviceOptions(const Rc<DxvkDevice>& device) {
|
||||||
|
DxbcOptions flags;
|
||||||
|
|
||||||
const VkPhysicalDeviceProperties devProps = device->adapter()->deviceProperties();
|
const VkPhysicalDeviceProperties devProps = device->adapter()->deviceProperties();
|
||||||
const VkPhysicalDeviceFeatures devFeatures = device->features();
|
const VkPhysicalDeviceFeatures devFeatures = device->features();
|
||||||
|
|
||||||
// Apply driver-specific workarounds
|
|
||||||
const DxvkGpuVendor vendor = static_cast<DxvkGpuVendor>(devProps.vendorID);
|
const DxvkGpuVendor vendor = static_cast<DxvkGpuVendor>(devProps.vendorID);
|
||||||
|
|
||||||
if (vendor == DxvkGpuVendor::Nvidia) {
|
if (vendor == DxvkGpuVendor::Nvidia) {
|
||||||
// Older versions of the driver expect the
|
flags.set(
|
||||||
// coordinate vector to have an extra component
|
DxbcOption::AddExtraDrefCoordComponent,
|
||||||
this->addExtraDrefCoordComponent = true;
|
DxbcOption::UseSimpleMinMaxClamp);
|
||||||
|
|
||||||
// From vkd3d: NMin/NMax/NClamp may crash the driver.
|
|
||||||
this->useSimpleMinMaxClamp = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable certain features if they are supported by the device
|
if (devFeatures.shaderStorageImageReadWithoutFormat)
|
||||||
this->useStorageImageReadWithoutFormat = devFeatures.shaderStorageImageReadWithoutFormat;
|
flags.set(DxbcOption::UseStorageImageReadWithoutFormat);
|
||||||
|
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,26 +4,37 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
/**
|
enum class DxbcOption : uint64_t {
|
||||||
* \brief DXBC compiler options
|
/// Use the ShaderImageReadWithoutFormat capability.
|
||||||
*
|
/// Enabled by default on GPUs which support this.
|
||||||
* Defines driver- or device-specific options,
|
UseStorageImageReadWithoutFormat,
|
||||||
* which are mostly workarounds for driver bugs.
|
|
||||||
*/
|
|
||||||
struct DxbcOptions {
|
|
||||||
DxbcOptions() { }
|
|
||||||
DxbcOptions(
|
|
||||||
const Rc<DxvkDevice>& device);
|
|
||||||
|
|
||||||
/// Add extra component to dref coordinate vector
|
|
||||||
bool addExtraDrefCoordComponent = false;
|
|
||||||
|
|
||||||
/// Use Fmin/Fmax instead of Nmin/Nmax.
|
|
||||||
bool useSimpleMinMaxClamp = false;
|
|
||||||
|
|
||||||
/// If \c false, image read operations can only be performed
|
/// Adds an extra component to the depth reference
|
||||||
/// on storage images with a scalar 32-bit image formats.
|
/// vector for depth-compare operations. Workaround
|
||||||
bool useStorageImageReadWithoutFormat = false;
|
/// for bugs in Nvidia drivers prior to 396.18.
|
||||||
|
AddExtraDrefCoordComponent,
|
||||||
|
|
||||||
|
/// Use FMin/FMax/FClamp instead of NMin/NMax/NClamp.
|
||||||
|
/// Workaround for bugs in older Nvidia drivers.
|
||||||
|
UseSimpleMinMaxClamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using DxbcOptions = Flags<DxbcOption>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gets app-specific DXBC options
|
||||||
|
*
|
||||||
|
* \param [in] appName Application name
|
||||||
|
* \returns DXBC options for this application
|
||||||
|
*/
|
||||||
|
DxbcOptions getDxbcAppOptions(const std::string& appName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Gets device-specific options
|
||||||
|
*
|
||||||
|
* \param [in] device The device
|
||||||
|
* \returns Device options
|
||||||
|
*/
|
||||||
|
DxbcOptions getDxbcDeviceOptions(const Rc<DxvkDevice>& device);
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user