[dxbc] Set float control bits as necessary

This commit is contained in:
Philip Rebohle 2021-01-28 15:54:36 +01:00
parent 849fb329ec
commit f5fa7a9099
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 77 additions and 2 deletions

View File

@ -235,6 +235,9 @@ namespace dxvk {
case DxbcProgramType::PixelShader: this->emitPsFinalize(); break;
case DxbcProgramType::ComputeShader: this->emitCsFinalize(); break;
}
// Emit float control mode if the extension is supported
this->emitFloatControl();
// Declare the entry point, we now have all the
// information we need, including the interfaces
@ -7467,7 +7470,32 @@ namespace dxvk {
return varId;
}
void DxbcCompiler::emitFloatControl() {
DxbcFloatControlFlags flags = m_moduleInfo.options.floatControl;
if (flags.isClear())
return;
const uint32_t width32 = 32;
const uint32_t width64 = 64;
m_module.enableExtension("SPV_KHR_float_controls");
if (flags.test(DxbcFloatControlFlag::DenormFlushToZero32))
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeDenormFlushToZero, 1, &width32);
if (flags.test(DxbcFloatControlFlag::DenormPreserve64))
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeDenormPreserve, 1, &width64);
if (flags.test(DxbcFloatControlFlag::PreserveNan32))
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeSignedZeroInfNanPreserve, 1, &width32);
if (flags.test(DxbcFloatControlFlag::PreserveNan64))
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeSignedZeroInfNanPreserve, 1, &width64);
}
uint32_t DxbcCompiler::emitNewVariable(const DxbcRegisterInfo& info) {
const uint32_t ptrTypeId = this->getPointerTypeId(info);
return m_module.newVar(ptrTypeId, info.sclass);

View File

@ -1173,6 +1173,8 @@ namespace dxvk {
uint32_t emitSamplePosArray();
void emitFloatControl();
///////////////////////////////
// Variable definition methods
uint32_t emitNewVariable(

View File

@ -57,6 +57,19 @@ namespace dxvk {
// Apply shader-related options
applyTristate(useSubgroupOpsForEarlyDiscard, device->config().useEarlyDiscard);
// Figure out float control flags to match D3D11 rules
if (devInfo.khrShaderFloatControls.shaderSignedZeroInfNanPreserveFloat32)
floatControl.set(DxbcFloatControlFlag::PreserveNan32);
if (devInfo.khrShaderFloatControls.shaderSignedZeroInfNanPreserveFloat64)
floatControl.set(DxbcFloatControlFlag::PreserveNan64);
if (devInfo.khrShaderFloatControls.denormBehaviorIndependence != VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE) {
if (devInfo.khrShaderFloatControls.shaderDenormFlushToZeroFloat32)
floatControl.set(DxbcFloatControlFlag::DenormFlushToZero32);
if (devInfo.khrShaderFloatControls.shaderDenormPreserveFloat64)
floatControl.set(DxbcFloatControlFlag::DenormPreserve64);
}
}
}

View File

@ -5,7 +5,16 @@
namespace dxvk {
struct D3D11Options;
enum class DxbcFloatControlFlag : uint32_t {
DenormFlushToZero32,
DenormPreserve64,
PreserveNan32,
PreserveNan64,
};
using DxbcFloatControlFlags = Flags<DxbcFloatControlFlag>;
struct DxbcOptions {
DxbcOptions();
DxbcOptions(const Rc<DxvkDevice>& device, const D3D11Options& options);
@ -48,6 +57,9 @@ namespace dxvk {
/// Insert memory barriers after TGSM stoes
bool forceTgsmBarriers = false;
/// Float control flags
DxbcFloatControlFlags floatControl;
/// Minimum storage buffer alignment
VkDeviceSize minSsboAlignment = 0;
};

View File

@ -93,6 +93,20 @@ namespace dxvk {
}
void SpirvModule::setExecutionMode(
uint32_t entryPointId,
spv::ExecutionMode executionMode,
uint32_t argCount,
const uint32_t* args) {
m_execModeInfo.putIns (spv::OpExecutionMode, 3 + argCount);
m_execModeInfo.putWord(entryPointId);
m_execModeInfo.putWord(executionMode);
for (uint32_t i = 0; i < argCount; i++)
m_execModeInfo.putWord(args[i]);
}
void SpirvModule::setInvocations(
uint32_t entryPointId,
uint32_t invocations) {

View File

@ -86,6 +86,12 @@ namespace dxvk {
uint32_t entryPointId,
spv::ExecutionMode executionMode);
void setExecutionMode(
uint32_t entryPointId,
spv::ExecutionMode executionMode,
uint32_t argCount,
const uint32_t* args);
void setInvocations(
uint32_t entryPointId,
uint32_t invocations);