Skip to content

Commit

Permalink
[dxbc] Set float control bits as necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
doitsujin committed Jan 28, 2021
1 parent 849fb32 commit f5fa7a9
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 2 deletions.
30 changes: 29 additions & 1 deletion src/dxbc/dxbc_compiler.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/dxbc/dxbc_compiler.h
Expand Up @@ -1173,6 +1173,8 @@ namespace dxvk {

uint32_t emitSamplePosArray();

void emitFloatControl();

///////////////////////////////
// Variable definition methods
uint32_t emitNewVariable(
Expand Down
13 changes: 13 additions & 0 deletions src/dxbc/dxbc_options.cpp
Expand Up @@ -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);
}
}

}
14 changes: 13 additions & 1 deletion src/dxbc/dxbc_options.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
};
Expand Down
14 changes: 14 additions & 0 deletions src/spirv/spirv_module.cpp
Expand Up @@ -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) {
Expand Down
6 changes: 6 additions & 0 deletions src/spirv/spirv_module.h
Expand Up @@ -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);
Expand Down

0 comments on commit f5fa7a9

Please sign in to comment.