mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 05:52:11 +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_dxvkAdapter (m_dxvkDevice->adapter()),
|
||||
m_d3d11Options (D3D11GetAppOptions(env::getExeName())),
|
||||
m_dxbcOptions (m_dxvkDevice) {
|
||||
m_dxbcOptions (getDxbcAppOptions(env::getExeName()) |
|
||||
getDxbcDeviceOptions(m_dxvkDevice)) {
|
||||
Com<IDXGIAdapter> adapter;
|
||||
|
||||
if (FAILED(pDxgiDevice->GetAdapter(&adapter))
|
||||
|
@ -769,7 +769,7 @@ namespace dxvk {
|
||||
const bool isUav = ins.op == DxbcOpcode::DclUavTyped;
|
||||
|
||||
if (isUav) {
|
||||
if (m_options.useStorageImageReadWithoutFormat)
|
||||
if (m_options.test(DxbcOption::UseStorageImageReadWithoutFormat))
|
||||
m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
||||
m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
||||
}
|
||||
@ -846,7 +846,7 @@ namespace dxvk {
|
||||
if (isUav) {
|
||||
if ((m_analysis->uavInfos[registerId].accessAtomicOp)
|
||||
|| (m_analysis->uavInfos[registerId].accessTypedLoad
|
||||
&& !m_options.useStorageImageReadWithoutFormat))
|
||||
&& !m_options.test(DxbcOption::UseStorageImageReadWithoutFormat)))
|
||||
imageFormat = getScalarImageFormat(sampledType);
|
||||
}
|
||||
|
||||
@ -1391,13 +1391,13 @@ namespace dxvk {
|
||||
break;
|
||||
|
||||
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.opNMax(typeId, src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
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.opNMin(typeId, src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
@ -2952,7 +2952,7 @@ namespace dxvk {
|
||||
DxbcRegMask(true, false, false, false))
|
||||
: 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);
|
||||
|
||||
// Determine the sampled image type based on the opcode.
|
||||
@ -3064,7 +3064,7 @@ namespace dxvk {
|
||||
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
||||
: 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);
|
||||
|
||||
// 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 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.opNClamp(typeId, value.id, vec0.id, vec1.id);
|
||||
}
|
||||
|
@ -1,25 +1,41 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "dxbc_options.h"
|
||||
|
||||
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 VkPhysicalDeviceFeatures devFeatures = device->features();
|
||||
|
||||
// Apply driver-specific workarounds
|
||||
const DxvkGpuVendor vendor = static_cast<DxvkGpuVendor>(devProps.vendorID);
|
||||
|
||||
if (vendor == DxvkGpuVendor::Nvidia) {
|
||||
// Older versions of the driver expect the
|
||||
// coordinate vector to have an extra component
|
||||
this->addExtraDrefCoordComponent = true;
|
||||
|
||||
// From vkd3d: NMin/NMax/NClamp may crash the driver.
|
||||
this->useSimpleMinMaxClamp = true;
|
||||
flags.set(
|
||||
DxbcOption::AddExtraDrefCoordComponent,
|
||||
DxbcOption::UseSimpleMinMaxClamp);
|
||||
}
|
||||
|
||||
// Enable certain features if they are supported by the device
|
||||
this->useStorageImageReadWithoutFormat = devFeatures.shaderStorageImageReadWithoutFormat;
|
||||
if (devFeatures.shaderStorageImageReadWithoutFormat)
|
||||
flags.set(DxbcOption::UseStorageImageReadWithoutFormat);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
}
|
@ -4,26 +4,37 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC compiler options
|
||||
*
|
||||
* Defines driver- or device-specific options,
|
||||
* 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;
|
||||
enum class DxbcOption : uint64_t {
|
||||
/// Use the ShaderImageReadWithoutFormat capability.
|
||||
/// Enabled by default on GPUs which support this.
|
||||
UseStorageImageReadWithoutFormat,
|
||||
|
||||
/// If \c false, image read operations can only be performed
|
||||
/// on storage images with a scalar 32-bit image formats.
|
||||
bool useStorageImageReadWithoutFormat = false;
|
||||
/// Adds an extra component to the depth reference
|
||||
/// vector for depth-compare operations. Workaround
|
||||
/// 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