diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index bc5f21840..f441cf875 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2086,40 +2086,7 @@ namespace dxvk { DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { - D3D9DeviceLock lock = LockDevice(); - - if (unlikely(Stage >= caps::TextureStageCount)) - return D3DERR_INVALIDCALL; - - if (unlikely(Type >= TextureStageStateCount)) - return D3DERR_INVALIDCALL; - - if (unlikely(ShouldRecord())) - return m_recorder->SetTextureStageState(Stage, Type, Value); - - if (likely(m_state.textureStages[Stage][Type] != Value)) { - if (Type == D3DTSS_TEXTURETRANSFORMFLAGS) { - m_projectionBitfield &= ~(1 << Stage); - if (Value & D3DTTFF_PROJECTED) - m_projectionBitfield |= 1 << Stage; - } - - if ((Type >= D3DTSS_BUMPENVMAT00 && Type <= D3DTSS_BUMPENVMAT11) - || (Type == D3DTSS_BUMPENVLSCALE || Type == D3DTSS_BUMPENVLOFFSET)) - m_flags.set(D3D9DeviceFlag::DirtySharedPixelShaderData); - else if (Type == D3DTSS_TEXTURETRANSFORMFLAGS) { - // This state affects both! - m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); - m_flags.set(D3D9DeviceFlag::DirtyFFVertexShader); - } - else if (Type != D3DTSS_TEXCOORDINDEX) - m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); - else - m_flags.set(D3D9DeviceFlag::DirtyFFVertexShader); - m_state.textureStages[Stage][Type] = Value; - } - - return D3D_OK; + return SetStateTextureStageState(Stage, RemapTextureStageStateType(Type), Value); } @@ -3529,6 +3496,47 @@ namespace dxvk { } + HRESULT D3D9DeviceEx::SetStateTextureStageState( + DWORD Stage, + D3D9TextureStageStateTypes Type, + DWORD Value) { + D3D9DeviceLock lock = LockDevice(); + + if (unlikely(Stage >= caps::TextureStageCount)) + return D3DERR_INVALIDCALL; + + if (unlikely(Type >= TextureStageStateCount)) + return D3DERR_INVALIDCALL; + + if (unlikely(ShouldRecord())) + return m_recorder->SetStateTextureStageState(Stage, Type, Value); + + if (likely(m_state.textureStages[Stage][Type] != Value)) { + if (Type == DXVK_TSS_TEXTURETRANSFORMFLAGS) { + m_projectionBitfield &= ~(1 << Stage); + if (Value & D3DTTFF_PROJECTED) + m_projectionBitfield |= 1 << Stage; + } + + if ((Type >= DXVK_TSS_BUMPENVMAT00 && Type <= DXVK_TSS_BUMPENVMAT11) + || (Type == DXVK_TSS_BUMPENVLSCALE || Type == DXVK_TSS_BUMPENVLOFFSET)) + m_flags.set(D3D9DeviceFlag::DirtySharedPixelShaderData); + else if (Type == DXVK_TSS_TEXTURETRANSFORMFLAGS) { + // This state affects both! + m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); + m_flags.set(D3D9DeviceFlag::DirtyFFVertexShader); + } + else if (Type != DXVK_TSS_TEXCOORDINDEX) + m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); + else + m_flags.set(D3D9DeviceFlag::DirtyFFVertexShader); + m_state.textureStages[Stage][Type] = Value; + } + + return D3D_OK; + } + + bool D3D9DeviceEx::IsExtended() { return m_parent->IsExtended(); } @@ -5452,17 +5460,17 @@ namespace dxvk { D3D9SharedPS* data = reinterpret_cast(slice.mapPtr); for (uint32_t i = 0; i < caps::TextureStageCount; i++) { - DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][D3DTSS_CONSTANT]), data->Stages[i].Constant); + DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][DXVK_TSS_CONSTANT]), data->Stages[i].Constant); // Flip major-ness so we can get away with a nice easy // dot in the shader without complex access - data->Stages[i].BumpEnvMat[0][0] = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVMAT00]); - data->Stages[i].BumpEnvMat[1][0] = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVMAT01]); - data->Stages[i].BumpEnvMat[0][1] = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVMAT10]); - data->Stages[i].BumpEnvMat[1][1] = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVMAT11]); + data->Stages[i].BumpEnvMat[0][0] = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT00]); + data->Stages[i].BumpEnvMat[1][0] = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT01]); + data->Stages[i].BumpEnvMat[0][1] = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT10]); + data->Stages[i].BumpEnvMat[1][1] = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT11]); - data->Stages[i].BumpEnvLScale = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVLSCALE]); - data->Stages[i].BumpEnvLOffset = bit::cast(m_state.textureStages[i][D3DTSS_BUMPENVLOFFSET]); + data->Stages[i].BumpEnvLScale = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVLSCALE]); + data->Stages[i].BumpEnvLOffset = bit::cast(m_state.textureStages[i][DXVK_TSS_BUMPENVLOFFSET]); } } @@ -5832,8 +5840,8 @@ namespace dxvk { key.Data.Contents.LightCount = lightCount; for (uint32_t i = 0; i < caps::MaxTextureBlendStages; i++) { - uint32_t transformFlags = m_state.textureStages[i][D3DTSS_TEXTURETRANSFORMFLAGS] & ~(D3DTTFF_PROJECTED); - uint32_t index = m_state.textureStages[i][D3DTSS_TEXCOORDINDEX]; + uint32_t transformFlags = m_state.textureStages[i][DXVK_TSS_TEXTURETRANSFORMFLAGS] & ~(D3DTTFF_PROJECTED); + uint32_t index = m_state.textureStages[i][DXVK_TSS_TEXCOORDINDEX]; uint32_t indexFlags = (index & TCIMask) >> TCIOffset; transformFlags &= 0b111; @@ -5996,34 +6004,34 @@ namespace dxvk { auto& data = m_state.textureStages[idx]; // Subsequent stages do not occur if this is true. - if (data[D3DTSS_COLOROP] == D3DTOP_DISABLE) + if (data[DXVK_TSS_COLOROP] == D3DTOP_DISABLE) break; // If the stage is invalid (ie. no texture bound), // this and all subsequent stages get disabled. if (m_state.textures[idx] == nullptr) { - if (((data[D3DTSS_COLORARG0] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[D3DTSS_COLOROP]) & (1 << 0u))) - || ((data[D3DTSS_COLORARG1] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[D3DTSS_COLOROP]) & (1 << 1u))) - || ((data[D3DTSS_COLORARG2] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[D3DTSS_COLOROP]) & (1 << 2u)))) + if (((data[DXVK_TSS_COLORARG0] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[DXVK_TSS_COLOROP]) & (1 << 0u))) + || ((data[DXVK_TSS_COLORARG1] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[DXVK_TSS_COLOROP]) & (1 << 1u))) + || ((data[DXVK_TSS_COLORARG2] & D3DTA_SELECTMASK) == D3DTA_TEXTURE && (ArgsMask(data[DXVK_TSS_COLOROP]) & (1 << 2u)))) break; } - stage.ColorOp = data[D3DTSS_COLOROP]; - stage.AlphaOp = data[D3DTSS_ALPHAOP]; + stage.ColorOp = data[DXVK_TSS_COLOROP]; + stage.AlphaOp = data[DXVK_TSS_ALPHAOP]; - stage.ColorArg0 = data[D3DTSS_COLORARG0]; - stage.ColorArg1 = data[D3DTSS_COLORARG1]; - stage.ColorArg2 = data[D3DTSS_COLORARG2]; + stage.ColorArg0 = data[DXVK_TSS_COLORARG0]; + stage.ColorArg1 = data[DXVK_TSS_COLORARG1]; + stage.ColorArg2 = data[DXVK_TSS_COLORARG2]; - stage.AlphaArg0 = data[D3DTSS_ALPHAARG0]; - stage.AlphaArg1 = data[D3DTSS_ALPHAARG1]; - stage.AlphaArg2 = data[D3DTSS_ALPHAARG2]; + stage.AlphaArg0 = data[DXVK_TSS_ALPHAARG0]; + stage.AlphaArg1 = data[DXVK_TSS_ALPHAARG1]; + stage.AlphaArg2 = data[DXVK_TSS_ALPHAARG2]; const uint32_t samplerOffset = idx * 2; stage.Type = (m_samplerTypeBitfield >> samplerOffset) & 0xffu; - stage.ResultIsTemp = data[D3DTSS_RESULTARG] == D3DTA_TEMP; + stage.ResultIsTemp = data[DXVK_TSS_RESULTARG] == D3DTA_TEMP; - uint32_t ttff = data[D3DTSS_TEXTURETRANSFORMFLAGS]; + uint32_t ttff = data[DXVK_TSS_TEXTURETRANSFORMFLAGS]; uint32_t count = ttff & ~D3DTTFF_PROJECTED; stage.Projected = (ttff & D3DTTFF_PROJECTED) ? 1 : 0; @@ -6399,24 +6407,24 @@ namespace dxvk { for (uint32_t i = 0; i < caps::TextureStageCount; i++) { auto& stage = m_state.textureStages[i]; - stage[D3DTSS_COLOROP] = i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE; - stage[D3DTSS_COLORARG1] = D3DTA_TEXTURE; - stage[D3DTSS_COLORARG2] = D3DTA_CURRENT; - stage[D3DTSS_ALPHAOP] = i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE; - stage[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE; - stage[D3DTSS_ALPHAARG2] = D3DTA_CURRENT; - stage[D3DTSS_BUMPENVMAT00] = bit::cast(0.0f); - stage[D3DTSS_BUMPENVMAT01] = bit::cast(0.0f); - stage[D3DTSS_BUMPENVMAT10] = bit::cast(0.0f); - stage[D3DTSS_BUMPENVMAT11] = bit::cast(0.0f); - stage[D3DTSS_TEXCOORDINDEX] = i; - stage[D3DTSS_BUMPENVLSCALE] = bit::cast(0.0f); - stage[D3DTSS_BUMPENVLOFFSET] = bit::cast(0.0f); - stage[D3DTSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE; - stage[D3DTSS_COLORARG0] = D3DTA_CURRENT; - stage[D3DTSS_ALPHAARG0] = D3DTA_CURRENT; - stage[D3DTSS_RESULTARG] = D3DTA_CURRENT; - stage[D3DTSS_CONSTANT] = 0x00000000; + stage[DXVK_TSS_COLOROP] = i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE; + stage[DXVK_TSS_COLORARG1] = D3DTA_TEXTURE; + stage[DXVK_TSS_COLORARG2] = D3DTA_CURRENT; + stage[DXVK_TSS_ALPHAOP] = i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE; + stage[DXVK_TSS_ALPHAARG1] = D3DTA_TEXTURE; + stage[DXVK_TSS_ALPHAARG2] = D3DTA_CURRENT; + stage[DXVK_TSS_BUMPENVMAT00] = bit::cast(0.0f); + stage[DXVK_TSS_BUMPENVMAT01] = bit::cast(0.0f); + stage[DXVK_TSS_BUMPENVMAT10] = bit::cast(0.0f); + stage[DXVK_TSS_BUMPENVMAT11] = bit::cast(0.0f); + stage[DXVK_TSS_TEXCOORDINDEX] = i; + stage[DXVK_TSS_BUMPENVLSCALE] = bit::cast(0.0f); + stage[DXVK_TSS_BUMPENVLOFFSET] = bit::cast(0.0f); + stage[DXVK_TSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE; + stage[DXVK_TSS_COLORARG0] = D3DTA_CURRENT; + stage[DXVK_TSS_ALPHAARG0] = D3DTA_CURRENT; + stage[DXVK_TSS_RESULTARG] = D3DTA_CURRENT; + stage[DXVK_TSS_CONSTANT] = 0x00000000; } m_flags.set(D3D9DeviceFlag::DirtySharedPixelShaderData); m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 7fffa50b9..d8968657e 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -638,6 +638,11 @@ namespace dxvk { HRESULT SetStateTransform(uint32_t idx, const D3DMATRIX* pMatrix); + HRESULT SetStateTextureStageState( + DWORD Stage, + D3D9TextureStageStateTypes Type, + DWORD Value); + VkPipelineStageFlags GetEnabledShaderStages() const { return m_dxvkDevice->getShaderPipelineStages(); } diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index fbd8f7fd2..e06e187b1 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -1,6 +1,7 @@ #include "d3d9_fixed_function.h" #include "d3d9_device.h" +#include "d3d9_util.h" #include "d3d9_spec_constants.h" #include "../dxvk/dxvk_hash.h" @@ -907,21 +908,21 @@ namespace dxvk { uint32_t count = flags; switch (inputFlags) { default: - case (D3DTSS_TCI_PASSTHRU >> TCIOffset): + case (DXVK_TSS_TCI_PASSTHRU >> TCIOffset): transformed = m_vs.in.TEXCOORD[inputIndex & 0xFF]; break; - case (D3DTSS_TCI_CAMERASPACENORMAL >> TCIOffset): + case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset): transformed = outNrm; count = 4; break; - case (D3DTSS_TCI_CAMERASPACEPOSITION >> TCIOffset): + case (DXVK_TSS_TCI_CAMERASPACEPOSITION >> TCIOffset): transformed = m_module.opCompositeInsert(m_vec4Type, m_module.constf32(1.0f), vtx, 1, &wIndex); count = 4; break; - case (D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): { + case (DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): { uint32_t vtx3 = m_module.opVectorShuffle(m_vec3Type, vtx, vtx, 3, indices.data()); vtx3 = m_module.opNormalize(m_vec3Type, vtx3); @@ -937,7 +938,7 @@ namespace dxvk { break; } - case (D3DTSS_TCI_SPHEREMAP >> TCIOffset): { + case (DXVK_TSS_TCI_SPHEREMAP >> TCIOffset): { uint32_t vtx3 = m_module.opVectorShuffle(m_vec3Type, vtx, vtx, 3, indices.data()); vtx3 = m_module.opNormalize(m_vec3Type, vtx3); diff --git a/src/d3d9/d3d9_state.h b/src/d3d9/d3d9_state.h index 383ac19ce..05a78b26f 100644 --- a/src/d3d9/d3d9_state.h +++ b/src/d3d9/d3d9_state.h @@ -19,7 +19,7 @@ namespace dxvk { static constexpr uint32_t RenderStateCount = 256; static constexpr uint32_t SamplerStateCount = D3DSAMP_DMAPOFFSET + 1; static constexpr uint32_t SamplerCount = 21; - static constexpr uint32_t TextureStageStateCount = D3DTSS_CONSTANT + 1; + static constexpr uint32_t TextureStageStateCount = DXVK_TSS_COUNT; namespace hacks::PointSize { static constexpr DWORD AlphaToCoverageDisabled = MAKEFOURCC('A', '2', 'M', '0'); diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index d3072f7af..a4dd41b0a 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -158,10 +158,10 @@ namespace dxvk { } - HRESULT D3D9StateBlock::SetTextureStageState( - DWORD Stage, - D3DTEXTURESTAGESTATETYPE Type, - DWORD Value) { + HRESULT D3D9StateBlock::SetStateTextureStageState( + DWORD Stage, + D3D9TextureStageStateTypes Type, + DWORD Value) { m_state.textureStages[Stage][Type] = Value; m_captures.flags.set(D3D9CapturedStateFlag::TextureStages); diff --git a/src/d3d9/d3d9_stateblock.h b/src/d3d9/d3d9_stateblock.h index fe410be4c..53cb7dab4 100644 --- a/src/d3d9/d3d9_stateblock.h +++ b/src/d3d9/d3d9_stateblock.h @@ -47,7 +47,7 @@ namespace dxvk { bit::bitset transforms; bit::bitset textureStages; std::array< - bit::bitset, + bit::bitset, caps::TextureStageCount> textureStageStates; struct { @@ -122,10 +122,10 @@ namespace dxvk { HRESULT SetStateTransform(uint32_t idx, const D3DMATRIX* pMatrix); - HRESULT SetTextureStageState( - DWORD Stage, - D3DTEXTURESTAGESTATETYPE Type, - DWORD Value); + HRESULT SetStateTextureStageState( + DWORD Stage, + D3D9TextureStageStateTypes Type, + DWORD Value); HRESULT MultiplyStateTransform(uint32_t idx, const D3DMATRIX* pMatrix); @@ -257,7 +257,7 @@ namespace dxvk { for (uint32_t state = m_captures.textureStageStates[0].dword(0); state; state &= state - 1) { uint32_t stateIdx = bit::tzcnt(state); - dst->SetTextureStageState(stageIdx, (D3DTEXTURESTAGESTATETYPE)stateIdx, src->textureStages[stageIdx][stateIdx]); + dst->SetStateTextureStageState(stageIdx, D3D9TextureStageStateTypes(stateIdx), src->textureStages[stageIdx][stateIdx]); } } } diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index 0edd220af..034d99fe7 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -247,4 +247,37 @@ namespace dxvk { || (srcFormat == D3D9Format::A4R4G4B4 && dstFormat == D3D9Format::X4R4G4B4); } + enum D3D9TextureStageStateTypes : uint32_t + { + DXVK_TSS_COLOROP = 0, + DXVK_TSS_COLORARG1 = 1, + DXVK_TSS_COLORARG2 = 2, + DXVK_TSS_ALPHAOP = 3, + DXVK_TSS_ALPHAARG1 = 4, + DXVK_TSS_ALPHAARG2 = 5, + DXVK_TSS_BUMPENVMAT00 = 6, + DXVK_TSS_BUMPENVMAT01 = 7, + DXVK_TSS_BUMPENVMAT10 = 8, + DXVK_TSS_BUMPENVMAT11 = 9, + DXVK_TSS_TEXCOORDINDEX = 10, + DXVK_TSS_BUMPENVLSCALE = 21, + DXVK_TSS_BUMPENVLOFFSET = 22, + DXVK_TSS_TEXTURETRANSFORMFLAGS = 23, + DXVK_TSS_COLORARG0 = 24, + DXVK_TSS_ALPHAARG0 = 25, + DXVK_TSS_RESULTARG = 26, + DXVK_TSS_CONSTANT = 31, + DXVK_TSS_COUNT = 32 + }; + + constexpr uint32_t DXVK_TSS_TCI_PASSTHRU = 0x00000000; + constexpr uint32_t DXVK_TSS_TCI_CAMERASPACENORMAL = 0x00010000; + constexpr uint32_t DXVK_TSS_TCI_CAMERASPACEPOSITION = 0x00020000; + constexpr uint32_t DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR = 0x00030000; + constexpr uint32_t DXVK_TSS_TCI_SPHEREMAP = 0x00040000; + + inline D3D9TextureStageStateTypes RemapTextureStageStateType(D3DTEXTURESTAGESTATETYPE Type) { + return D3D9TextureStageStateTypes(Type - 1); + } + } \ No newline at end of file