1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 22:29:15 +01:00

[d3d9] Consolidate shader const related fields

This commit is contained in:
Robin Kertels 2025-03-09 16:21:02 +01:00
parent 3f7460931a
commit 2e95eac8a1
No known key found for this signature in database
GPG Key ID: 3824904F14D40757
3 changed files with 54 additions and 56 deletions

View File

@ -2,12 +2,11 @@
#include "d3d9_caps.h" #include "d3d9_caps.h"
#include "d3d9_constant_buffer.h" #include "d3d9_constant_buffer.h"
#include "d3d9_constant_layout.h"
#include "../dxvk/dxvk_buffer.h"
#include "../dxso/dxso_isgn.h" #include "../dxso/dxso_isgn.h"
#include "../util/util_math.h"
#include "../util/util_vector.h" #include "../util/util_vector.h"
#include <cstdint> #include <cstdint>
@ -45,10 +44,14 @@ namespace dxvk {
}; };
struct D3D9ConstantSets { struct D3D9ConstantSets {
D3D9ConstantLayout layout;
D3D9SwvpConstantBuffers swvp; D3D9SwvpConstantBuffers swvp;
D3D9ConstantBuffer buffer; D3D9ConstantBuffer buffer;
DxsoShaderMetaInfo meta = {}; DxsoShaderMetaInfo meta = {};
bool dirty = true; bool dirty = true;
uint32_t maxChangedConstF = 0;
uint32_t maxChangedConstI = 0;
uint32_t maxChangedConstB = 0;
}; };
} }

View File

@ -99,26 +99,29 @@ namespace dxvk {
// Also check the required alignments. // Also check the required alignments.
const bool supportsRobustness2 = m_dxvkDevice->features().extRobustness2.robustBufferAccess2; const bool supportsRobustness2 = m_dxvkDevice->features().extRobustness2.robustBufferAccess2;
bool useRobustConstantAccess = supportsRobustness2; bool useRobustConstantAccess = supportsRobustness2;
D3D9ConstantSets& vsConstSet = m_consts[DxsoProgramType::VertexShader];
D3D9ConstantSets& psConstSet = m_consts[DxsoProgramType::PixelShader];
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;
if (canSWVP) { if (canSWVP) {
const uint32_t floatBufferAlignment = m_dxsoOptions.vertexFloatConstantBufferAsSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment; const uint32_t floatBufferAlignment = m_dxsoOptions.vertexFloatConstantBufferAsSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment;
useRobustConstantAccess &= m_vsLayout.floatSize() % floatBufferAlignment == 0;
useRobustConstantAccess &= m_vsLayout.intSize() % m_robustUBOAlignment == 0; useRobustConstantAccess &= vsConstSet.layout.floatSize() % floatBufferAlignment == 0;
useRobustConstantAccess &= m_vsLayout.bitmaskSize() % m_robustUBOAlignment == 0; useRobustConstantAccess &= vsConstSet.layout.intSize() % m_robustUBOAlignment == 0;
useRobustConstantAccess &= vsConstSet.layout.bitmaskSize() % m_robustUBOAlignment == 0;
} else { } else {
useRobustConstantAccess &= m_vsLayout.totalSize() % m_robustUBOAlignment == 0; useRobustConstantAccess &= vsConstSet.layout.totalSize() % m_robustUBOAlignment == 0;
} }
useRobustConstantAccess &= m_psLayout.totalSize() % m_robustUBOAlignment == 0; useRobustConstantAccess &= psConstSet.layout.totalSize() % m_robustUBOAlignment == 0;
} }
if (!useRobustConstantAccess) { if (!useRobustConstantAccess) {
// Disable optimized constant copies, we always have to copy all constants. // Disable optimized constant copies, we always have to copy all constants.
m_vsFloatConstsCount = m_vsLayout.floatCount; vsConstSet.maxChangedConstF = vsConstSet.layout.floatCount;
m_vsIntConstsCount = m_vsLayout.intCount; vsConstSet.maxChangedConstI = vsConstSet.layout.intCount;
m_vsBoolConstsCount = m_vsLayout.boolCount; vsConstSet.maxChangedConstB = vsConstSet.layout.boolCount;
m_psFloatConstsCount = m_psLayout.floatCount; psConstSet.maxChangedConstF = psConstSet.layout.floatCount;
if (supportsRobustness2) { if (supportsRobustness2) {
Logger::warn("Disabling robust constant buffer access because of alignment."); Logger::warn("Disabling robust constant buffer access because of alignment.");
@ -4593,15 +4596,17 @@ namespace dxvk {
void D3D9DeviceEx::DetermineConstantLayouts(bool canSWVP) { void D3D9DeviceEx::DetermineConstantLayouts(bool canSWVP) {
m_vsLayout.floatCount = canSWVP ? caps::MaxFloatConstantsSoftware : caps::MaxFloatConstantsVS; D3D9ConstantSets& vsConstSet = m_consts[DxsoProgramType::VertexShader];
m_vsLayout.intCount = canSWVP ? caps::MaxOtherConstantsSoftware : caps::MaxOtherConstants; vsConstSet.layout.floatCount = canSWVP ? caps::MaxFloatConstantsSoftware : caps::MaxFloatConstantsVS;
m_vsLayout.boolCount = canSWVP ? caps::MaxOtherConstantsSoftware : caps::MaxOtherConstants; vsConstSet.layout.intCount = canSWVP ? caps::MaxOtherConstantsSoftware : caps::MaxOtherConstants;
m_vsLayout.bitmaskCount = align(m_vsLayout.boolCount, 32) / 32; vsConstSet.layout.boolCount = canSWVP ? caps::MaxOtherConstantsSoftware : caps::MaxOtherConstants;
vsConstSet.layout.bitmaskCount = align(vsConstSet.layout.boolCount, 32) / 32;
m_psLayout.floatCount = caps::MaxFloatConstantsPS; D3D9ConstantSets& psConstSet = m_consts[DxsoProgramType::PixelShader];
m_psLayout.intCount = caps::MaxOtherConstants; psConstSet.layout.floatCount = caps::MaxFloatConstantsPS;
m_psLayout.boolCount = caps::MaxOtherConstants; psConstSet.layout.intCount = caps::MaxOtherConstants;
m_psLayout.bitmaskCount = align(m_psLayout.boolCount, 32) / 32; psConstSet.layout.boolCount = caps::MaxOtherConstants;
psConstSet.layout.bitmaskCount = align(psConstSet.layout.boolCount, 32) / 32;
} }
@ -5868,7 +5873,7 @@ namespace dxvk {
constSet.dirty = false; constSet.dirty = false;
uint32_t floatCount = m_vsFloatConstsCount; uint32_t floatCount = constSet.maxChangedConstF;
if (constSet.meta.needsConstantCopies) { if (constSet.meta.needsConstantCopies) {
// If the shader requires us to preserve shader defined constants, // If the shader requires us to preserve shader defined constants,
// we copy those over. We need to adjust the amount of used floats accordingly. // we copy those over. We need to adjust the amount of used floats accordingly.
@ -5880,8 +5885,8 @@ namespace dxvk {
// Calculate data sizes for each constant type. // Calculate data sizes for each constant type.
const uint32_t floatDataSize = floatCount * sizeof(Vector4); const uint32_t floatDataSize = floatCount * sizeof(Vector4);
const uint32_t intDataSize = std::min(constSet.meta.maxConstIndexI, m_vsIntConstsCount) * sizeof(Vector4i); const uint32_t intDataSize = std::min(constSet.meta.maxConstIndexI, constSet.maxChangedConstI) * sizeof(Vector4i);
const uint32_t boolDataSize = divCeil(std::min(constSet.meta.maxConstIndexB, m_vsBoolConstsCount), 32u) * uint32_t(sizeof(uint32_t)); const uint32_t boolDataSize = divCeil(std::min(constSet.meta.maxConstIndexB, constSet.maxChangedConstB), 32u) * uint32_t(sizeof(uint32_t));
// Max copy source size is 8192 * 16 => always aligned to any plausible value // Max copy source size is 8192 * 16 => always aligned to any plausible value
// => we won't copy out of bounds // => we won't copy out of bounds
@ -5936,7 +5941,7 @@ namespace dxvk {
constSet.dirty = false; constSet.dirty = false;
uint32_t floatCount = ShaderStage == DxsoProgramType::VertexShader ? m_vsFloatConstsCount : m_psFloatConstsCount; uint32_t floatCount = constSet.maxChangedConstF;
if (constSet.meta.needsConstantCopies) { if (constSet.meta.needsConstantCopies) {
// If the shader requires us to preserve shader defined constants, // If the shader requires us to preserve shader defined constants,
// we copy those over. We need to adjust the amount of used floats accordingly. // we copy those over. We need to adjust the amount of used floats accordingly.
@ -5983,11 +5988,11 @@ namespace dxvk {
void D3D9DeviceEx::UploadConstants() { void D3D9DeviceEx::UploadConstants() {
if constexpr (ShaderStage == DxsoProgramTypes::VertexShader) { if constexpr (ShaderStage == DxsoProgramTypes::VertexShader) {
if (CanSWVP()) if (CanSWVP())
return UploadSoftwareConstantSet(m_state.vsConsts.get(), m_vsLayout); return UploadSoftwareConstantSet(m_state.vsConsts.get(), m_consts[ShaderStage].layout);
else else
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts.get(), m_vsLayout, m_state.vertexShader); return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts.get(), m_consts[ShaderStage].layout, m_state.vertexShader);
} else { } else {
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts.get(), m_psLayout, m_state.pixelShader); return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts.get(), m_consts[ShaderStage].layout, m_state.pixelShader);
} }
} }
@ -7743,29 +7748,29 @@ namespace dxvk {
pConstantData, pConstantData,
Count); Count);
if constexpr (ProgramType == DxsoProgramType::VertexShader) { D3D9ConstantSets& constSet = m_consts[ProgramType];
if constexpr (ConstantType == D3D9ConstantType::Float) {
m_vsFloatConstsCount = std::max(m_vsFloatConstsCount, StartRegister + Count); if constexpr (ConstantType == D3D9ConstantType::Float) {
} else if constexpr (ConstantType == D3D9ConstantType::Int) { constSet.maxChangedConstF = std::max(constSet.maxChangedConstF, StartRegister + Count);
m_vsIntConstsCount = std::max(m_vsIntConstsCount, StartRegister + Count); } else if constexpr (ConstantType == D3D9ConstantType::Int && ProgramType == DxsoProgramType::VertexShader) {
} else /* if constexpr (ConstantType == D3D9ConstantType::Bool) */ { // We only track changed int constants for vertex shaders (and it's only used when the device uses the SWVP UBO layout).
m_vsBoolConstsCount = std::max(m_vsBoolConstsCount, StartRegister + Count); // Pixel shaders (and vertex shaders on HWVP devices) always copy all int constants into the same UBO as the float constants
} constSet.maxChangedConstI = std::max(constSet.maxChangedConstI, StartRegister + Count);
} else { } else if constexpr (ConstantType == D3D9ConstantType::Bool && ProgramType == DxsoProgramType::VertexShader) {
if constexpr (ConstantType == D3D9ConstantType::Float) { // We only track changed bool constants for vertex shaders (and it's only used when the device uses the SWVP UBO layout).
m_psFloatConstsCount = std::max(m_psFloatConstsCount, StartRegister + Count); // Pixel shaders (and vertex shaders on HWVP devices) always put all bool constants into a single spec constant.
} constSet.maxChangedConstB = std::max(constSet.maxChangedConstB, StartRegister + Count);
} }
if constexpr (ConstantType != D3D9ConstantType::Bool) { if constexpr (ConstantType != D3D9ConstantType::Bool) {
uint32_t maxCount = ConstantType == D3D9ConstantType::Float uint32_t maxCount = ConstantType == D3D9ConstantType::Float
? m_consts[ProgramType].meta.maxConstIndexF ? constSet.meta.maxConstIndexF
: m_consts[ProgramType].meta.maxConstIndexI; : constSet.meta.maxConstIndexI;
m_consts[ProgramType].dirty |= StartRegister < maxCount; constSet.dirty |= StartRegister < maxCount;
} else if constexpr (ProgramType == DxsoProgramType::VertexShader) { } else if constexpr (ProgramType == DxsoProgramType::VertexShader) {
if (unlikely(CanSWVP())) { if (unlikely(CanSWVP())) {
m_consts[DxsoProgramType::VertexShader].dirty |= StartRegister < m_consts[ProgramType].meta.maxConstIndexB; constSet.dirty |= StartRegister < constSet.meta.maxConstIndexB;
} }
} }

View File

@ -1051,8 +1051,8 @@ namespace dxvk {
VkImageLayout OldLayout, VkImageLayout OldLayout,
VkImageLayout NewLayout); VkImageLayout NewLayout);
const D3D9ConstantLayout& GetVertexConstantLayout() { return m_vsLayout; } const D3D9ConstantLayout& GetVertexConstantLayout() { return m_consts[DxsoProgramType::VertexShader].layout; }
const D3D9ConstantLayout& GetPixelConstantLayout() { return m_psLayout; } const D3D9ConstantLayout& GetPixelConstantLayout() { return m_consts[DxsoProgramType::PixelShader].layout; }
void ResetState(D3DPRESENT_PARAMETERS* pPresentationParameters); void ResetState(D3DPRESENT_PARAMETERS* pPresentationParameters);
HRESULT ResetSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode); HRESULT ResetSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
@ -1283,8 +1283,7 @@ namespace dxvk {
template <DxsoProgramType ProgramType, template <DxsoProgramType ProgramType,
D3D9ConstantType ConstantType> D3D9ConstantType ConstantType>
inline uint32_t DetermineHardwareRegCount() const { inline uint32_t DetermineHardwareRegCount() const {
const auto& layout = ProgramType == DxsoProgramType::VertexShader const auto& layout = m_consts[ProgramType].layout;
? m_vsLayout : m_psLayout;
switch (ConstantType) { switch (ConstantType) {
default: default:
@ -1582,15 +1581,6 @@ namespace dxvk {
uint32_t m_robustSSBOAlignment = 1; uint32_t m_robustSSBOAlignment = 1;
uint32_t m_robustUBOAlignment = 1; uint32_t m_robustUBOAlignment = 1;
uint32_t m_vsFloatConstsCount = 0;
uint32_t m_vsIntConstsCount = 0;
uint32_t m_vsBoolConstsCount = 0;
uint32_t m_psFloatConstsCount = 0;
VkDeviceSize m_boundVSConstantsBufferSize = 0;
VkDeviceSize m_boundPSConstantsBufferSize = 0;
D3D9ConstantLayout m_vsLayout;
D3D9ConstantLayout m_psLayout;
D3D9ConstantSets m_consts[DxsoProgramTypes::Count]; D3D9ConstantSets m_consts[DxsoProgramTypes::Count];
D3D9UserDefinedAnnotation* m_annotation = nullptr; D3D9UserDefinedAnnotation* m_annotation = nullptr;