1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[d3d9] Remap texture stage state types onto our own enum

Fits us nicely into a dword for captures while not exclusing D3DTSS_CONSTANT
This commit is contained in:
Joshua Ashton 2020-01-22 23:51:57 +00:00
parent a1cad25a51
commit 7d0ddc4b3b
7 changed files with 138 additions and 91 deletions

View File

@ -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<D3D9SharedPS*>(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<float>(m_state.textureStages[i][D3DTSS_BUMPENVMAT00]);
data->Stages[i].BumpEnvMat[1][0] = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVMAT01]);
data->Stages[i].BumpEnvMat[0][1] = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVMAT10]);
data->Stages[i].BumpEnvMat[1][1] = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVMAT11]);
data->Stages[i].BumpEnvMat[0][0] = bit::cast<float>(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT00]);
data->Stages[i].BumpEnvMat[1][0] = bit::cast<float>(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT01]);
data->Stages[i].BumpEnvMat[0][1] = bit::cast<float>(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT10]);
data->Stages[i].BumpEnvMat[1][1] = bit::cast<float>(m_state.textureStages[i][DXVK_TSS_BUMPENVMAT11]);
data->Stages[i].BumpEnvLScale = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVLSCALE]);
data->Stages[i].BumpEnvLOffset = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVLOFFSET]);
data->Stages[i].BumpEnvLScale = bit::cast<float>(m_state.textureStages[i][DXVK_TSS_BUMPENVLSCALE]);
data->Stages[i].BumpEnvLOffset = bit::cast<float>(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<DWORD>(0.0f);
stage[D3DTSS_BUMPENVMAT01] = bit::cast<DWORD>(0.0f);
stage[D3DTSS_BUMPENVMAT10] = bit::cast<DWORD>(0.0f);
stage[D3DTSS_BUMPENVMAT11] = bit::cast<DWORD>(0.0f);
stage[D3DTSS_TEXCOORDINDEX] = i;
stage[D3DTSS_BUMPENVLSCALE] = bit::cast<DWORD>(0.0f);
stage[D3DTSS_BUMPENVLOFFSET] = bit::cast<DWORD>(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<DWORD>(0.0f);
stage[DXVK_TSS_BUMPENVMAT01] = bit::cast<DWORD>(0.0f);
stage[DXVK_TSS_BUMPENVMAT10] = bit::cast<DWORD>(0.0f);
stage[DXVK_TSS_BUMPENVMAT11] = bit::cast<DWORD>(0.0f);
stage[DXVK_TSS_TEXCOORDINDEX] = i;
stage[DXVK_TSS_BUMPENVLSCALE] = bit::cast<DWORD>(0.0f);
stage[DXVK_TSS_BUMPENVLOFFSET] = bit::cast<DWORD>(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);

View File

@ -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();
}

View File

@ -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);

View File

@ -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');

View File

@ -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);

View File

@ -47,7 +47,7 @@ namespace dxvk {
bit::bitset<caps::MaxTransforms> transforms;
bit::bitset<caps::TextureStageCount> textureStages;
std::array<
bit::bitset<D3DTSS_CONSTANT>,
bit::bitset<TextureStageStateCount>,
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]);
}
}
}

View File

@ -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);
}
}