mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9] Refactor state blocks to allocate dynamically.
This commit is contained in:
parent
8ecd1b3b6b
commit
996acbe3f2
@ -5145,9 +5145,9 @@ namespace dxvk {
|
||||
if (CanSWVP())
|
||||
return UploadSoftwareConstantSet(m_state.vsConsts, m_vsLayout);
|
||||
else
|
||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts, m_vsLayout, m_state.vertexShader);
|
||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsVSHardware>(m_state.vsConsts.get(), m_vsLayout, m_state.vertexShader);
|
||||
} else {
|
||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts, m_psLayout, m_state.pixelShader);
|
||||
return UploadConstantSet<ShaderStage, D3D9ShaderConstantsPS> (m_state.psConsts.get(), m_psLayout, m_state.pixelShader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6255,7 +6255,7 @@ namespace dxvk {
|
||||
|
||||
if (likely(!CanSWVP())) {
|
||||
UpdateVertexBoolSpec(
|
||||
m_state.vsConsts.bConsts[0] &
|
||||
m_state.vsConsts->bConsts[0] &
|
||||
m_consts[DxsoProgramType::VertexShader].meta.boolConstantMask);
|
||||
} else
|
||||
UpdateVertexBoolSpec(0);
|
||||
@ -6283,7 +6283,7 @@ namespace dxvk {
|
||||
UpdatePixelShaderSamplerSpec(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers...
|
||||
|
||||
UpdatePixelBoolSpec(
|
||||
m_state.psConsts.bConsts[0] &
|
||||
m_state.psConsts->bConsts[0] &
|
||||
m_consts[DxsoProgramType::PixelShader].meta.boolConstantMask);
|
||||
}
|
||||
else {
|
||||
@ -6524,16 +6524,16 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D9DeviceEx::SetVertexBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) {
|
||||
m_state.vsConsts.bConsts[idx] &= ~mask;
|
||||
m_state.vsConsts.bConsts[idx] |= bits & mask;
|
||||
m_state.vsConsts->bConsts[idx] &= ~mask;
|
||||
m_state.vsConsts->bConsts[idx] |= bits & mask;
|
||||
|
||||
m_consts[DxsoProgramTypes::VertexShader].dirty = true;
|
||||
}
|
||||
|
||||
|
||||
void D3D9DeviceEx::SetPixelBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) {
|
||||
m_state.psConsts.bConsts[idx] &= ~mask;
|
||||
m_state.psConsts.bConsts[idx] |= bits & mask;
|
||||
m_state.psConsts->bConsts[idx] &= ~mask;
|
||||
m_state.psConsts->bConsts[idx] |= bits & mask;
|
||||
|
||||
m_consts[DxsoProgramTypes::PixelShader].dirty = true;
|
||||
}
|
||||
@ -7244,11 +7244,11 @@ namespace dxvk {
|
||||
for (uint32_t i = 0; i < caps::MaxStreams; i++)
|
||||
m_state.streamFreq[i] = 1;
|
||||
|
||||
for (uint32_t i = 0; i < m_state.textures.size(); i++)
|
||||
for (uint32_t i = 0; i < m_state.textures->size(); i++)
|
||||
SetStateTexture(i, nullptr);
|
||||
|
||||
EmitCs([
|
||||
cSize = m_state.textures.size()
|
||||
cSize = m_state.textures->size()
|
||||
](DxvkContext* ctx) {
|
||||
VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
@ -7263,7 +7263,7 @@ namespace dxvk {
|
||||
m_depthTextures = 0;
|
||||
m_cubeTextures = 0;
|
||||
|
||||
auto& ss = m_state.samplerStates;
|
||||
auto& ss = m_state.samplerStates.get();
|
||||
for (uint32_t i = 0; i < ss.size(); i++) {
|
||||
auto& state = ss[i];
|
||||
state[D3DSAMP_ADDRESSU] = D3DTADDRESS_WRAP;
|
||||
|
@ -1093,13 +1093,13 @@ namespace dxvk {
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
if constexpr (ConstantType == D3D9ConstantType::Float) {
|
||||
const float* source = set.fConsts[StartRegister].data;
|
||||
const float* source = set->fConsts[StartRegister].data;
|
||||
const size_t size = Count * sizeof(Vector4);
|
||||
|
||||
std::memcpy(pConstantData, source, size);
|
||||
}
|
||||
else if constexpr (ConstantType == D3D9ConstantType::Int) {
|
||||
const int* source = set.iConsts[StartRegister].data;
|
||||
const int* source = set->iConsts[StartRegister].data;
|
||||
const size_t size = Count * sizeof(Vector4i);
|
||||
|
||||
std::memcpy(pConstantData, source, size);
|
||||
@ -1112,7 +1112,7 @@ namespace dxvk {
|
||||
|
||||
const uint32_t bit = (1u << bitIdx);
|
||||
|
||||
bool constValue = set.bConsts[arrayIdx] & bit;
|
||||
bool constValue = set->bConsts[arrayIdx] & bit;
|
||||
pConstantData[i] = constValue ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -4,17 +4,25 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D9CapturableState::D3D9CapturableState() {
|
||||
for (uint32_t i = 0; i < streamFreq.size(); i++)
|
||||
streamFreq[i] = 1;
|
||||
template <template <typename T> typename ItemType>
|
||||
D3D9State<ItemType>::D3D9State() {
|
||||
for (uint32_t i = 0; i < streamFreq.size(); i++)
|
||||
streamFreq[i] = 1;
|
||||
|
||||
for (uint32_t i = 0; i < enabledLightIndices.size(); i++)
|
||||
enabledLightIndices[i] = UINT32_MAX;
|
||||
}
|
||||
for (uint32_t i = 0; i < enabledLightIndices.size(); i++)
|
||||
enabledLightIndices[i] = UINT32_MAX;
|
||||
}
|
||||
|
||||
D3D9CapturableState::~D3D9CapturableState() {
|
||||
for (uint32_t i = 0; i < textures.size(); i++)
|
||||
TextureChangePrivate(textures[i], nullptr);
|
||||
}
|
||||
|
||||
template <template <typename T> typename ItemType>
|
||||
D3D9State<ItemType>::~D3D9State() {
|
||||
if (textures) {
|
||||
for (uint32_t i = 0; i < textures->size(); i++)
|
||||
TextureChangePrivate(textures[i], nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
template struct D3D9State<dynamic_item>;
|
||||
template struct D3D9State<static_item>;
|
||||
|
||||
}
|
@ -181,51 +181,97 @@ namespace dxvk {
|
||||
0.0f // Phi
|
||||
};
|
||||
|
||||
struct D3D9CapturableState {
|
||||
D3D9CapturableState();
|
||||
template <typename T>
|
||||
class dynamic_item {
|
||||
public:
|
||||
auto& operator [] (size_t idx) { ensure(); return (*m_data)[idx]; }
|
||||
const auto& operator [] (size_t idx) const { ensure(); return (*m_data)[idx]; }
|
||||
|
||||
~D3D9CapturableState();
|
||||
T& operator=(const T& x) { ensure(); *m_data = x; return *m_data; }
|
||||
|
||||
Com<D3D9VertexDecl, false> vertexDecl;
|
||||
Com<D3D9IndexBuffer, false> indices;
|
||||
const T* operator -> () const { ensure(); return m_data.get(); }
|
||||
T* operator -> () { ensure(); return m_data.get(); }
|
||||
|
||||
std::array<DWORD, RenderStateCount> renderStates = {};
|
||||
const T* operator & () const { ensure(); return m_data.get(); }
|
||||
T* operator & () { ensure(); return m_data.get(); }
|
||||
|
||||
std::array<
|
||||
operator bool() { return m_data != nullptr; }
|
||||
operator T() { ensure(); return *m_data; }
|
||||
|
||||
void ensure() const { if (!m_data) m_data = std::make_unique<T>(); }
|
||||
|
||||
T& get() { ensure(); return *m_data; }
|
||||
private:
|
||||
mutable std::unique_ptr<T> m_data;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class static_item {
|
||||
public:
|
||||
auto& operator [] (size_t idx) { return m_data[idx]; }
|
||||
const auto& operator [] (size_t idx) const { return m_data[idx]; }
|
||||
|
||||
T& operator=(const T& x) { m_data = x; return m_data; }
|
||||
|
||||
operator bool() { return true; }
|
||||
operator T() { return m_data; }
|
||||
|
||||
const T* operator -> () const { return &m_data; }
|
||||
T* operator -> () { return &m_data; }
|
||||
|
||||
const T* operator & () const { return &m_data; }
|
||||
T* operator & () { return &m_data; }
|
||||
|
||||
T& get() { return m_data; }
|
||||
private:
|
||||
T m_data;
|
||||
};
|
||||
|
||||
template <template <typename T> typename ItemType>
|
||||
struct D3D9State {
|
||||
D3D9State();
|
||||
~D3D9State();
|
||||
|
||||
Com<D3D9VertexDecl, false> vertexDecl;
|
||||
Com<D3D9IndexBuffer, false> indices;
|
||||
|
||||
ItemType<std::array<DWORD, RenderStateCount>> renderStates = {};
|
||||
|
||||
ItemType<std::array<
|
||||
std::array<DWORD, SamplerStateCount>,
|
||||
SamplerCount> samplerStates = {};
|
||||
SamplerCount>> samplerStates = {};
|
||||
|
||||
std::array<D3D9VBO, caps::MaxStreams> vertexBuffers = {};
|
||||
ItemType<std::array<D3D9VBO, caps::MaxStreams>> vertexBuffers = {};
|
||||
|
||||
std::array<
|
||||
ItemType<std::array<
|
||||
IDirect3DBaseTexture9*,
|
||||
SamplerCount> textures = {};
|
||||
SamplerCount>> textures = {};
|
||||
|
||||
Com<D3D9VertexShader, false> vertexShader;
|
||||
Com<D3D9PixelShader, false> pixelShader;
|
||||
Com<D3D9VertexShader, false> vertexShader;
|
||||
Com<D3D9PixelShader, false> pixelShader;
|
||||
|
||||
D3DVIEWPORT9 viewport = {};
|
||||
RECT scissorRect = {};
|
||||
D3DVIEWPORT9 viewport = {};
|
||||
RECT scissorRect = {};
|
||||
|
||||
std::array<
|
||||
ItemType<std::array<
|
||||
D3D9ClipPlane,
|
||||
caps::MaxClipPlanes> clipPlanes = {};
|
||||
caps::MaxClipPlanes>> clipPlanes = {};
|
||||
|
||||
std::array<
|
||||
ItemType<std::array<
|
||||
std::array<DWORD, TextureStageStateCount>,
|
||||
caps::TextureStageCount> textureStages = {};
|
||||
caps::TextureStageCount>> textureStages = {};
|
||||
|
||||
D3D9ShaderConstantsVSSoftware vsConsts;
|
||||
D3D9ShaderConstantsPS psConsts;
|
||||
ItemType<D3D9ShaderConstantsVSSoftware> vsConsts;
|
||||
ItemType<D3D9ShaderConstantsPS> psConsts;
|
||||
|
||||
std::array<UINT, caps::MaxStreams> streamFreq = {};
|
||||
std::array<UINT, caps::MaxStreams> streamFreq = {};
|
||||
|
||||
std::array<Matrix4, caps::MaxTransforms> transforms = {};
|
||||
ItemType<std::array<Matrix4, caps::MaxTransforms>> transforms = {};
|
||||
|
||||
D3DMATERIAL9 material = {};
|
||||
ItemType<D3DMATERIAL9> material = {};
|
||||
|
||||
std::vector<std::optional<D3DLIGHT9>> lights;
|
||||
std::array<DWORD, caps::MaxEnabledLights> enabledLightIndices;
|
||||
std::vector<std::optional<D3DLIGHT9>> lights;
|
||||
std::array<DWORD, caps::MaxEnabledLights> enabledLightIndices;
|
||||
|
||||
bool IsLightEnabled(DWORD Index) const {
|
||||
const auto& indices = enabledLightIndices;
|
||||
@ -233,12 +279,16 @@ namespace dxvk {
|
||||
}
|
||||
};
|
||||
|
||||
using D3D9CapturableState = D3D9State<dynamic_item>;
|
||||
using D3D9DeviceState = D3D9State<static_item>;
|
||||
|
||||
template <
|
||||
DxsoProgramType ProgramType,
|
||||
D3D9ConstantType ConstantType,
|
||||
typename T>
|
||||
typename T,
|
||||
typename StateType>
|
||||
HRESULT UpdateStateConstants(
|
||||
D3D9CapturableState* pState,
|
||||
StateType* pState,
|
||||
UINT StartRegister,
|
||||
const T* pConstantData,
|
||||
UINT Count,
|
||||
@ -249,17 +299,17 @@ namespace dxvk {
|
||||
if (!FloatEmu) {
|
||||
size_t size = Count * sizeof(Vector4);
|
||||
|
||||
std::memcpy(set.fConsts[StartRegister].data, pConstantData, size);
|
||||
std::memcpy(set->fConsts[StartRegister].data, pConstantData, size);
|
||||
}
|
||||
else {
|
||||
for (UINT i = 0; i < Count; i++)
|
||||
set.fConsts[StartRegister + i] = replaceNaN(pConstantData + (i * 4));
|
||||
set->fConsts[StartRegister + i] = replaceNaN(pConstantData + (i * 4));
|
||||
}
|
||||
}
|
||||
else if constexpr (ConstantType == D3D9ConstantType::Int) {
|
||||
size_t size = Count * sizeof(Vector4i);
|
||||
|
||||
std::memcpy(set.iConsts[StartRegister].data, pConstantData, size);
|
||||
std::memcpy(set->iConsts[StartRegister].data, pConstantData, size);
|
||||
}
|
||||
else {
|
||||
for (uint32_t i = 0; i < Count; i++) {
|
||||
@ -269,9 +319,9 @@ namespace dxvk {
|
||||
|
||||
const uint32_t bit = 1u << bitIdx;
|
||||
|
||||
set.bConsts[arrayIdx] &= ~bit;
|
||||
set->bConsts[arrayIdx] &= ~bit;
|
||||
if (pConstantData[i])
|
||||
set.bConsts[arrayIdx] |= bit;
|
||||
set->bConsts[arrayIdx] |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +333,7 @@ namespace dxvk {
|
||||
: UpdateHelper(pState->psConsts);
|
||||
}
|
||||
|
||||
struct Direct3DState9 : public D3D9CapturableState {
|
||||
struct Direct3DState9 : public D3D9DeviceState {
|
||||
|
||||
std::array<Com<D3D9Surface, false>, caps::MaxSimultaneousRenderTargets> renderTargets;
|
||||
Com<D3D9Surface, false> depthStencil;
|
||||
|
@ -339,15 +339,15 @@ namespace dxvk {
|
||||
|
||||
|
||||
HRESULT D3D9StateBlock::SetVertexBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) {
|
||||
m_state.vsConsts.bConsts[idx] &= ~mask;
|
||||
m_state.vsConsts.bConsts[idx] |= bits & mask;
|
||||
m_state.vsConsts->bConsts[idx] &= ~mask;
|
||||
m_state.vsConsts->bConsts[idx] |= bits & mask;
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D9StateBlock::SetPixelBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) {
|
||||
m_state.psConsts.bConsts[idx] &= ~mask;
|
||||
m_state.psConsts.bConsts[idx] |= bits & mask;
|
||||
m_state.psConsts->bConsts[idx] &= ~mask;
|
||||
m_state.psConsts->bConsts[idx] |= bits & mask;
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ namespace dxvk {
|
||||
for (uint32_t consts : bit::BitMask(m_captures.vsConsts.fConsts.dword(i))) {
|
||||
uint32_t idx = i * 32 + consts;
|
||||
|
||||
dst->SetVertexShaderConstantF(idx, (float*)&src->vsConsts.fConsts[idx], 1);
|
||||
dst->SetVertexShaderConstantF(idx, (float*)&src->vsConsts->fConsts[idx], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,13 +272,13 @@ namespace dxvk {
|
||||
for (uint32_t consts : bit::BitMask(m_captures.vsConsts.iConsts.dword(i))) {
|
||||
uint32_t idx = i * 32 + consts;
|
||||
|
||||
dst->SetVertexShaderConstantI(idx, (int*)&src->vsConsts.iConsts[idx], 1);
|
||||
dst->SetVertexShaderConstantI(idx, (int*)&src->vsConsts->iConsts[idx], 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_captures.vsConsts.bConsts.any()) {
|
||||
for (uint32_t i = 0; i < m_captures.vsConsts.bConsts.dwordCount(); i++)
|
||||
dst->SetVertexBoolBitfield(i, m_captures.vsConsts.bConsts.dword(i), src->vsConsts.bConsts[i]);
|
||||
dst->SetVertexBoolBitfield(i, m_captures.vsConsts.bConsts.dword(i), src->vsConsts->bConsts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ namespace dxvk {
|
||||
for (uint32_t consts : bit::BitMask(m_captures.psConsts.fConsts.dword(i))) {
|
||||
uint32_t idx = i * 32 + consts;
|
||||
|
||||
dst->SetPixelShaderConstantF(idx, (float*)&src->psConsts.fConsts[idx], 1);
|
||||
dst->SetPixelShaderConstantF(idx, (float*)&src->psConsts->fConsts[idx], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,13 +295,13 @@ namespace dxvk {
|
||||
for (uint32_t consts : bit::BitMask(m_captures.psConsts.iConsts.dword(i))) {
|
||||
uint32_t idx = i * 32 + consts;
|
||||
|
||||
dst->SetPixelShaderConstantI(idx, (int*)&src->psConsts.iConsts[idx], 1);
|
||||
dst->SetPixelShaderConstantI(idx, (int*)&src->psConsts->iConsts[idx], 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_captures.psConsts.bConsts.any()) {
|
||||
for (uint32_t i = 0; i < m_captures.psConsts.bConsts.dwordCount(); i++)
|
||||
dst->SetPixelBoolBitfield(i, m_captures.psConsts.bConsts.dword(i), src->psConsts.bConsts[i]);
|
||||
dst->SetPixelBoolBitfield(i, m_captures.psConsts.bConsts.dword(i), src->psConsts->bConsts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +394,7 @@ namespace dxvk {
|
||||
D3D9CapturableState m_state;
|
||||
D3D9StateCaptures m_captures;
|
||||
|
||||
D3D9CapturableState* m_deviceState;
|
||||
D3D9DeviceState* m_deviceState;
|
||||
|
||||
bool m_applying = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user