mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-23 01:54:22 +01:00
[d3d9+dxso] Rely on robustness for unset HW VS & PS constants
This commit is contained in:
parent
869f75895c
commit
530f87f158
@ -78,22 +78,28 @@ namespace dxvk {
|
|||||||
m_dxsoOptions = DxsoOptions(this, m_d3d9Options);
|
m_dxsoOptions = DxsoOptions(this, m_d3d9Options);
|
||||||
|
|
||||||
const bool supportsRobustness2 = m_dxvkDevice->features().extRobustness2.robustBufferAccess2;
|
const bool supportsRobustness2 = m_dxvkDevice->features().extRobustness2.robustBufferAccess2;
|
||||||
bool useRobustConstantAccess = canSWVP && supportsRobustness2;
|
bool useRobustConstantAccess = supportsRobustness2;
|
||||||
if (useRobustConstantAccess) {
|
if (useRobustConstantAccess) {
|
||||||
m_robustSSBOAlignment = m_dxvkDevice->properties().extRobustness2.robustStorageBufferAccessSizeAlignment;
|
m_robustSSBOAlignment = m_dxvkDevice->properties().extRobustness2.robustStorageBufferAccessSizeAlignment;
|
||||||
m_robustUBOAlignment = m_dxvkDevice->properties().extRobustness2.robustUniformBufferAccessSizeAlignment;
|
m_robustUBOAlignment = m_dxvkDevice->properties().extRobustness2.robustUniformBufferAccessSizeAlignment;
|
||||||
const uint32_t floatBufferAlignment = m_dxsoOptions.vertexFloatConstantBufferAsSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment;
|
if (canSWVP) {
|
||||||
useRobustConstantAccess &= m_vsLayout.floatSize() % floatBufferAlignment == 0;
|
const uint32_t floatBufferAlignment = m_dxsoOptions.vertexFloatConstantBufferAsSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment;
|
||||||
useRobustConstantAccess &= m_vsLayout.intSize() % m_robustUBOAlignment == 0;
|
useRobustConstantAccess &= m_vsLayout.floatSize() % floatBufferAlignment == 0;
|
||||||
useRobustConstantAccess &= m_vsLayout.bitmaskSize() % m_robustUBOAlignment == 0;
|
useRobustConstantAccess &= m_vsLayout.intSize() % m_robustUBOAlignment == 0;
|
||||||
|
useRobustConstantAccess &= m_vsLayout.bitmaskSize() % m_robustUBOAlignment == 0;
|
||||||
|
} else {
|
||||||
|
useRobustConstantAccess &= m_vsLayout.totalSize() % m_robustUBOAlignment == 0;
|
||||||
|
}
|
||||||
|
useRobustConstantAccess &= m_psLayout.totalSize() % m_robustUBOAlignment == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!useRobustConstantAccess) {
|
if (!useRobustConstantAccess) {
|
||||||
m_vsFloatConstsCount = m_vsLayout.floatCount;
|
m_vsFloatConstsCount = m_vsLayout.floatCount;
|
||||||
m_vsIntConstsCount = m_vsLayout.intCount;
|
m_vsIntConstsCount = m_vsLayout.intCount;
|
||||||
m_vsBoolConstsCount = m_vsLayout.boolCount;
|
m_vsBoolConstsCount = m_vsLayout.boolCount;
|
||||||
|
m_psFloatConstsCount = m_psLayout.floatCount;
|
||||||
|
|
||||||
if (supportsRobustness2 && canSWVP) {
|
if (supportsRobustness2) {
|
||||||
Logger::warn("Disabling robust constant buffer access because of alignment.");
|
Logger::warn("Disabling robust constant buffer access because of alignment.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4836,6 +4842,11 @@ namespace dxvk {
|
|||||||
DxvkBufferSlice(cBuffer, 0, cBuffer->info().size));
|
DxvkBufferSlice(cBuffer, 0, cBuffer->info().size));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (ShaderStage == DxsoProgramType::PixelShader)
|
||||||
|
m_boundPSConstantsBufferSize = buffer->info().size;
|
||||||
|
else
|
||||||
|
m_boundVSConstantsBufferSize = buffer->info().size;
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4954,7 +4965,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
|
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
|
||||||
inline void D3D9DeviceEx::UploadConstantSet(const SoftwareLayoutType& Src, const ShaderType& Shader) {
|
inline void D3D9DeviceEx::UploadConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout, const ShaderType& Shader) {
|
||||||
|
/*
|
||||||
|
* We just copy the float constants that have been set by the application and rely on robustness
|
||||||
|
* to return 0 on OOB reads.
|
||||||
|
*/
|
||||||
D3D9ConstantSets& constSet = m_consts[ShaderStage];
|
D3D9ConstantSets& constSet = m_consts[ShaderStage];
|
||||||
|
|
||||||
if (!constSet.dirty)
|
if (!constSet.dirty)
|
||||||
@ -4962,6 +4977,29 @@ namespace dxvk {
|
|||||||
|
|
||||||
constSet.dirty = false;
|
constSet.dirty = false;
|
||||||
|
|
||||||
|
const uint32_t floatCount = ShaderStage == DxsoProgramType::VertexShader ? m_vsFloatConstsCount : m_psFloatConstsCount;
|
||||||
|
|
||||||
|
const uint32_t intRange = caps::MaxOtherConstants * sizeof(Vector4i);
|
||||||
|
const uint32_t intDataSize = constSet.meta.maxConstIndexI * sizeof(Vector4i);
|
||||||
|
uint32_t floatDataSize = std::min(constSet.meta.maxConstIndexF, floatCount) * sizeof(Vector4);
|
||||||
|
const uint32_t minSize = std::max(m_robustUBOAlignment, 64u); // Make sure we do not recreate the buffer because the new one has to be a tiny bit larger
|
||||||
|
const uint32_t bufferSize = std::max(floatDataSize + intRange, minSize);
|
||||||
|
floatDataSize = bufferSize - intRange; // Read additional floats for padding so we don't end up with garbage data
|
||||||
|
|
||||||
|
VkDeviceSize& boundConstantBufferSize = ShaderStage == DxsoProgramType::VertexShader ? m_boundVSConstantsBufferSize : m_boundPSConstantsBufferSize;
|
||||||
|
if (boundConstantBufferSize != bufferSize) {
|
||||||
|
constexpr uint32_t slotId = computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, 0);
|
||||||
|
EmitCs([
|
||||||
|
cBuffer = constSet.buffer,
|
||||||
|
cSlotId = slotId,
|
||||||
|
cSize = bufferSize
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->bindResourceBuffer(cSlotId,
|
||||||
|
DxvkBufferSlice(cBuffer, 0, cSize));
|
||||||
|
});
|
||||||
|
boundConstantBufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
DxvkBufferSliceHandle slice = constSet.buffer->allocSlice();
|
DxvkBufferSliceHandle slice = constSet.buffer->allocSlice();
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
@ -4973,18 +5011,20 @@ namespace dxvk {
|
|||||||
|
|
||||||
auto* dst = reinterpret_cast<HardwareLayoutType*>(slice.mapPtr);
|
auto* dst = reinterpret_cast<HardwareLayoutType*>(slice.mapPtr);
|
||||||
|
|
||||||
if (constSet.meta.maxConstIndexF)
|
if (constSet.meta.maxConstIndexI != 0)
|
||||||
std::memcpy(dst->fConsts, Src.fConsts, constSet.meta.maxConstIndexF * sizeof(Vector4));
|
std::memcpy(dst->iConsts, Src.iConsts, intDataSize);
|
||||||
if (constSet.meta.maxConstIndexI)
|
if (constSet.meta.maxConstIndexF != 0)
|
||||||
std::memcpy(dst->iConsts, Src.iConsts, constSet.meta.maxConstIndexI * sizeof(Vector4i));
|
std::memcpy(dst->fConsts, Src.fConsts, floatDataSize);
|
||||||
|
|
||||||
if (constSet.meta.needsConstantCopies) {
|
if (constSet.meta.needsConstantCopies) {
|
||||||
Vector4* data = reinterpret_cast<Vector4*>(dst->fConsts);
|
Vector4* data = reinterpret_cast<Vector4*>(dst->fConsts);
|
||||||
|
|
||||||
auto& shaderConsts = GetCommonShader(Shader)->GetConstants();
|
auto& shaderConsts = GetCommonShader(Shader)->GetConstants();
|
||||||
|
|
||||||
for (const auto& constant : shaderConsts)
|
for (const auto& constant : shaderConsts) {
|
||||||
data[constant.uboIdx] = *reinterpret_cast<const Vector4*>(constant.float32);
|
if (constant.uboIdx < constSet.meta.maxConstIndexF)
|
||||||
|
data[constant.uboIdx] = *reinterpret_cast<const Vector4*>(constant.float32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4995,9 +5035,9 @@ namespace dxvk {
|
|||||||
if (CanSWVP())
|
if (CanSWVP())
|
||||||
return UploadSoftwareConstantSet(m_state.vsConsts, m_vsLayout);
|
return UploadSoftwareConstantSet(m_state.vsConsts, m_vsLayout);
|
||||||
else
|
else
|
||||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts, m_state.vertexShader);
|
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts, m_vsLayout, m_state.vertexShader);
|
||||||
} else {
|
} else {
|
||||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts, m_state.pixelShader);
|
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts, m_psLayout, m_state.pixelShader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6392,6 +6432,10 @@ namespace dxvk {
|
|||||||
} else /* if constexpr (ConstantType == D3D9ConstantType::Bool) */ {
|
} else /* if constexpr (ConstantType == D3D9ConstantType::Bool) */ {
|
||||||
m_vsBoolConstsCount = std::max(m_vsBoolConstsCount, StartRegister + Count);
|
m_vsBoolConstsCount = std::max(m_vsBoolConstsCount, StartRegister + Count);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if constexpr (ConstantType == D3D9ConstantType::Float) {
|
||||||
|
m_psFloatConstsCount = std::max(m_psFloatConstsCount, StartRegister + Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (ConstantType != D3D9ConstantType::Bool) {
|
if constexpr (ConstantType != D3D9ConstantType::Bool) {
|
||||||
|
@ -811,16 +811,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
void BindAlphaTestState();
|
void BindAlphaTestState();
|
||||||
|
|
||||||
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
|
|
||||||
inline void UploadHardwareConstantSet(void* pData, const SoftwareLayoutType& Src, const ShaderType& Shader);
|
|
||||||
|
|
||||||
template <typename SoftwareLayoutType>
|
template <typename SoftwareLayoutType>
|
||||||
inline void UploadSoftwareConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout);
|
inline void UploadSoftwareConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout);
|
||||||
|
|
||||||
inline void CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc<DxvkBuffer>& dstBuffer, const void* src, uint32_t copySize, bool useSSBO);
|
inline void CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc<DxvkBuffer>& dstBuffer, const void* src, uint32_t copySize, bool useSSBO);
|
||||||
|
|
||||||
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
|
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
|
||||||
inline void UploadConstantSet(const SoftwareLayoutType& Src, const ShaderType& Shader);
|
inline void UploadConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout, const ShaderType& Shader);
|
||||||
|
|
||||||
template <DxsoProgramType ShaderStage>
|
template <DxsoProgramType ShaderStage>
|
||||||
void UploadConstants();
|
void UploadConstants();
|
||||||
@ -1231,6 +1228,9 @@ namespace dxvk {
|
|||||||
uint32_t m_vsFloatConstsCount = 0;
|
uint32_t m_vsFloatConstsCount = 0;
|
||||||
uint32_t m_vsIntConstsCount = 0;
|
uint32_t m_vsIntConstsCount = 0;
|
||||||
uint32_t m_vsBoolConstsCount = 0;
|
uint32_t m_vsBoolConstsCount = 0;
|
||||||
|
uint32_t m_psFloatConstsCount = 0;
|
||||||
|
VkDeviceSize m_boundVSConstantsBufferSize = 0;
|
||||||
|
VkDeviceSize m_boundPSConstantsBufferSize = 0;
|
||||||
|
|
||||||
D3D9ConstantLayout m_vsLayout;
|
D3D9ConstantLayout m_vsLayout;
|
||||||
D3D9ConstantLayout m_psLayout;
|
D3D9ConstantLayout m_psLayout;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user