Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Joshua-Ashton/2704f6afdc57c16645342d479bcbc426 to your computer and use it in GitHub Desktop.
Save Joshua-Ashton/2704f6afdc57c16645342d479bcbc426 to your computer and use it in GitHub Desktop.
From d7610d5a65b91a00a2a7003157a7d05016ad95bb Mon Sep 17 00:00:00 2001
From: Joshua Ashton <joshua@froggi.es>
Date: Tue, 3 Dec 2019 03:52:45 +0000
Subject: [PATCH] [d3d9] Refactor fixed function keys
---
src/d3d9/d3d9_device.cpp | 50 ++++++++++-----------
src/d3d9/d3d9_fixed_function.cpp | 64 +++++++++++++--------------
src/d3d9/d3d9_fixed_function.h | 75 +++++++++++++++-----------------
3 files changed, 91 insertions(+), 98 deletions(-)
diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp
index 032e6232f..88ce52673 100644
--- a/src/d3d9/d3d9_device.cpp
+++ b/src/d3d9/d3d9_device.cpp
@@ -5713,40 +5713,40 @@ namespace dxvk {
m_flags.clr(D3D9DeviceFlag::DirtyFFVertexShader);
D3D9FFShaderKeyVS key;
- key.data.HasPositionT = hasPositionT;
- key.data.HasColor0 = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasColor0) : false;
- key.data.HasColor1 = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasColor1) : false;
- key.data.HasPointSize = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasPointSize) : false;
- key.data.HasFog = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasFog) : false;
+ key.Data.Contents.HasPositionT = hasPositionT;
+ key.Data.Contents.HasColor0 = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasColor0) : false;
+ key.Data.Contents.HasColor1 = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasColor1) : false;
+ key.Data.Contents.HasPointSize = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasPointSize) : false;
+ key.Data.Contents.HasFog = m_state.vertexDecl != nullptr ? m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasFog) : false;
- bool lighting = m_state.renderStates[D3DRS_LIGHTING] != 0 && !key.data.HasPositionT;
+ bool lighting = m_state.renderStates[D3DRS_LIGHTING] != 0 && !key.Data.Contents.HasPositionT;
bool colorVertex = m_state.renderStates[D3DRS_COLORVERTEX] != 0;
uint32_t mask = (lighting && colorVertex)
- ? (key.data.HasColor0 ? D3DMCS_COLOR1 : D3DMCS_MATERIAL)
- | (key.data.HasColor1 ? D3DMCS_COLOR2 : D3DMCS_MATERIAL)
+ ? (key.Data.Contents.HasColor0 ? D3DMCS_COLOR1 : D3DMCS_MATERIAL)
+ | (key.Data.Contents.HasColor1 ? D3DMCS_COLOR2 : D3DMCS_MATERIAL)
: 0;
- key.data.UseLighting = lighting;
- key.data.NormalizeNormals = m_state.renderStates[D3DRS_NORMALIZENORMALS];
- key.data.LocalViewer = m_state.renderStates[D3DRS_LOCALVIEWER] && lighting;
+ key.Data.Contents.UseLighting = lighting;
+ key.Data.Contents.NormalizeNormals = m_state.renderStates[D3DRS_NORMALIZENORMALS];
+ key.Data.Contents.LocalViewer = m_state.renderStates[D3DRS_LOCALVIEWER] && lighting;
- key.data.RangeFog = m_state.renderStates[D3DRS_RANGEFOGENABLE];
+ key.Data.Contents.RangeFog = m_state.renderStates[D3DRS_RANGEFOGENABLE];
- key.data.DiffuseSource = m_state.renderStates[D3DRS_DIFFUSEMATERIALSOURCE] & mask;
- key.data.AmbientSource = m_state.renderStates[D3DRS_AMBIENTMATERIALSOURCE] & mask;
- key.data.SpecularSource = m_state.renderStates[D3DRS_SPECULARMATERIALSOURCE] & mask;
- key.data.EmissiveSource = m_state.renderStates[D3DRS_EMISSIVEMATERIALSOURCE] & mask;
+ key.Data.Contents.DiffuseSource = m_state.renderStates[D3DRS_DIFFUSEMATERIALSOURCE] & mask;
+ key.Data.Contents.AmbientSource = m_state.renderStates[D3DRS_AMBIENTMATERIALSOURCE] & mask;
+ key.Data.Contents.SpecularSource = m_state.renderStates[D3DRS_SPECULARMATERIALSOURCE] & mask;
+ key.Data.Contents.EmissiveSource = m_state.renderStates[D3DRS_EMISSIVEMATERIALSOURCE] & mask;
uint32_t lightCount = 0;
- if (key.data.UseLighting) {
+ if (key.Data.Contents.UseLighting) {
for (uint32_t i = 0; i < caps::MaxEnabledLights; i++) {
if (m_state.enabledLightIndices[i] != UINT32_MAX)
lightCount++;
}
}
- key.data.LightCount = lightCount;
+ 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);
@@ -5756,12 +5756,12 @@ namespace dxvk {
transformFlags &= 0b111;
index &= 0b111;
- key.data.TransformFlags |= transformFlags << (i * 3);
- key.data.TexcoordFlags |= indexFlags << (i * 3);
- key.data.TexcoordIndices |= index << (i * 3);
+ key.Data.Contents.TransformFlags |= transformFlags << (i * 3);
+ key.Data.Contents.TexcoordFlags |= indexFlags << (i * 3);
+ key.Data.Contents.TexcoordIndices |= index << (i * 3);
}
- key.data.TexcoordDeclMask = m_state.vertexDecl != nullptr ? m_state.vertexDecl->GetTexcoordMask() : 0;
+ key.Data.Contents.TexcoordDeclMask = m_state.vertexDecl != nullptr ? m_state.vertexDecl->GetTexcoordMask() : 0;
EmitCs([
this,
@@ -5879,7 +5879,7 @@ namespace dxvk {
uint32_t idx;
for (idx = 0; idx < caps::TextureStageCount; idx++) {
- auto& stage = key.Stages[idx].data;
+ auto& stage = key.Stages[idx].Contents;
auto& data = m_state.textureStages[idx];
// Subsequent stages do not occur if this is true.
@@ -5917,7 +5917,7 @@ namespace dxvk {
stage.ProjectedCount = (ttff & D3DTTFF_PROJECTED) ? count : 0;
}
- auto& stage0 = key.Stages[0].data;
+ auto& stage0 = key.Stages[0].Contents;
if (stage0.ResultIsTemp &&
stage0.ColorOp != D3DTOP_DISABLE &&
@@ -5931,7 +5931,7 @@ namespace dxvk {
// The last stage *always* writes to current.
if (idx >= 1)
- key.Stages[idx - 1].data.ResultIsTemp = false;
+ key.Stages[idx - 1].Contents.ResultIsTemp = false;
EmitCs([
this,
diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp
index 926893b56..6c470a352 100644
--- a/src/d3d9/d3d9_fixed_function.cpp
+++ b/src/d3d9/d3d9_fixed_function.cpp
@@ -734,7 +734,7 @@ namespace dxvk {
bool diffuseOrSpec = semantic == DxsoSemantic{ DxsoUsage::Color, 0 }
|| semantic == DxsoSemantic{ DxsoUsage::Color, 1 };
- if (diffuseOrSpec && m_fsKey.Stages[0].data.GlobalFlatShade)
+ if (diffuseOrSpec && m_fsKey.Stages[0].Contents.GlobalFlatShade)
m_module.decorate(ptr, spv::DecorationFlat);
std::string name = str::format(input ? "in_" : "out_", semantic.usage, semantic.usageIndex);
@@ -760,7 +760,7 @@ namespace dxvk {
const uint32_t wIndex = 3;
- if (!m_vsKey.data.HasPositionT) {
+ if (!m_vsKey.Data.Contents.HasPositionT) {
uint32_t wv = m_vs.constants.worldview;
uint32_t nrmMtx = m_vs.constants.normal;
@@ -774,7 +774,7 @@ namespace dxvk {
normal = m_module.opMatrixTimesVector(m_vec3Type, nrmMtx, normal);
// Some games rely no normals not being normal.
- if (m_vsKey.data.NormalizeNormals) {
+ if (m_vsKey.Data.Contents.NormalizeNormals) {
uint32_t bool_t = m_module.defBoolType();
uint32_t bool3_t = m_module.defVectorType(bool_t, 3);
@@ -820,14 +820,14 @@ namespace dxvk {
m_module.opStore(m_vs.out.NORMAL, outNrm);
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
- uint32_t inputIndex = (m_vsKey.data.TexcoordIndices >> (i * 3)) & 0b111;
- uint32_t inputFlags = (m_vsKey.data.TexcoordFlags >> (i * 3)) & 0b111;
+ uint32_t inputIndex = (m_vsKey.Data.Contents.TexcoordIndices >> (i * 3)) & 0b111;
+ uint32_t inputFlags = (m_vsKey.Data.Contents.TexcoordFlags >> (i * 3)) & 0b111;
uint32_t transformed;
const uint32_t wIndex = 3;
- uint32_t flags = (m_vsKey.data.TransformFlags >> (i * 3)) & 0b111;
+ uint32_t flags = (m_vsKey.Data.Contents.TransformFlags >> (i * 3)) & 0b111;
uint32_t count = flags;
switch (inputFlags) {
default:
@@ -888,7 +888,7 @@ namespace dxvk {
uint32_t type = flags;
if (type != D3DTTFF_DISABLE) {
- if (!m_vsKey.data.HasPositionT) {
+ if (!m_vsKey.Data.Contents.HasPositionT) {
for (uint32_t j = count; j < 4; j++) {
// If we're outside the component count of the vertex decl for this texcoord then we pad with zeroes.
// Otherwise, pad with ones.
@@ -896,7 +896,7 @@ namespace dxvk {
// Very weird quirk in order to get texcoord transforms to work like they do in native.
// In future, maybe we could sort this out properly by chopping matrices of different sizes, but thats
// a project for another day.
- uint32_t texcoordCount = (m_vsKey.data.TexcoordDeclMask >> (3 * inputIndex)) & 0x7;
+ uint32_t texcoordCount = (m_vsKey.Data.Contents.TexcoordDeclMask >> (3 * inputIndex)) & 0x7;
uint32_t value = j > texcoordCount ? m_module.constf32(0) : m_module.constf32(1);
transformed = m_module.opCompositeInsert(m_vec4Type, value, transformed, 1, &j);
}
@@ -915,7 +915,7 @@ namespace dxvk {
m_module.opStore(m_vs.out.TEXCOORD[i], transformed);
}
- if (m_vsKey.data.UseLighting) {
+ if (m_vsKey.Data.Contents.UseLighting) {
auto PickSource = [&](uint32_t Source, uint32_t Material) {
if (Source == D3DMCS_MATERIAL)
return Material;
@@ -929,7 +929,7 @@ namespace dxvk {
uint32_t specularValue = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 0.0f);
uint32_t ambientValue = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 0.0f);
- for (uint32_t i = 0; i < m_vsKey.data.LightCount; i++) {
+ for (uint32_t i = 0; i < m_vsKey.Data.Contents.LightCount; i++) {
uint32_t light_ptr_t = m_module.defPointerType(m_vs.lightType, spv::StorageClassUniform);
uint32_t indexVal = m_module.constu32(VSConstLight0 + i);
@@ -1010,7 +1010,7 @@ namespace dxvk {
uint32_t diffuseness = m_module.opFMul(m_floatType, hitDot, atten);
uint32_t mid;
- if (m_vsKey.data.LocalViewer) {
+ if (m_vsKey.Data.Contents.LocalViewer) {
mid = m_module.opNormalize(m_vec3Type, vtx3);
mid = m_module.opFSub(m_vec3Type, hitDir, mid);
}
@@ -1035,10 +1035,10 @@ namespace dxvk {
specularValue = m_module.opFAdd(m_vec4Type, specularValue, lightSpecular);
}
- uint32_t mat_diffuse = PickSource(m_vsKey.data.DiffuseSource, m_vs.constants.materialDiffuse);
- uint32_t mat_ambient = PickSource(m_vsKey.data.AmbientSource, m_vs.constants.materialAmbient);
- uint32_t mat_emissive = PickSource(m_vsKey.data.EmissiveSource, m_vs.constants.materialEmissive);
- uint32_t mat_specular = PickSource(m_vsKey.data.SpecularSource, m_vs.constants.materialSpecular);
+ uint32_t mat_diffuse = PickSource(m_vsKey.Data.Contents.DiffuseSource, m_vs.constants.materialDiffuse);
+ uint32_t mat_ambient = PickSource(m_vsKey.Data.Contents.AmbientSource, m_vs.constants.materialAmbient);
+ uint32_t mat_emissive = PickSource(m_vsKey.Data.Contents.EmissiveSource, m_vs.constants.materialEmissive);
+ uint32_t mat_specular = PickSource(m_vsKey.Data.Contents.SpecularSource, m_vs.constants.materialSpecular);
std::array<uint32_t, 4> alphaSwizzle = {0, 1, 2, 7};
uint32_t finalColor0 = m_module.opFFma(m_vec4Type, mat_ambient, m_vs.constants.globalAmbient, mat_emissive);
@@ -1067,10 +1067,10 @@ namespace dxvk {
D3D9FogContext fogCtx;
fogCtx.IsPixel = false;
- fogCtx.RangeFog = m_vsKey.data.RangeFog;
+ fogCtx.RangeFog = m_vsKey.Data.Contents.RangeFog;
fogCtx.RenderState = m_rsBlock;
fogCtx.vPos = vtx;
- fogCtx.HasFogInput = m_vsKey.data.HasFog;
+ fogCtx.HasFogInput = m_vsKey.Data.Contents.HasFog;
fogCtx.vFog = m_vs.in.FOG;
fogCtx.oColor = 0;
m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_module, fogCtx));
@@ -1314,14 +1314,14 @@ namespace dxvk {
for (uint32_t i = 0; i < caps::TextureStageCount; i++)
m_vs.in.TEXCOORD[i] = declareIO(true, DxsoSemantic{ DxsoUsage::Texcoord, i });
- if (m_vsKey.data.HasColor0)
+ if (m_vsKey.Data.Contents.HasColor0)
m_vs.in.COLOR[0] = declareIO(true, DxsoSemantic{ DxsoUsage::Color, 0 });
else {
m_vs.in.COLOR[0] = m_module.constvec4f32(1.0f, 1.0f, 1.0f, 1.0f);
m_isgn.elemCount++;
}
- if (m_vsKey.data.HasColor1)
+ if (m_vsKey.Data.Contents.HasColor1)
m_vs.in.COLOR[1] = declareIO(true, DxsoSemantic{ DxsoUsage::Color, 1 });
else {
m_vs.in.COLOR[1] = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 0.0f);
@@ -1346,7 +1346,7 @@ namespace dxvk {
m_vs.in.FOG = declareIO(true, DxsoSemantic{ DxsoUsage::Fog, 0 });
m_vs.out.FOG = declareIO(false, DxsoSemantic{ DxsoUsage::Fog, 0 });
- if (m_vsKey.data.HasPointSize)
+ if (m_vsKey.Data.Contents.HasPointSize)
m_vs.in.POINTSIZE = declareIO(true, DxsoSemantic{ DxsoUsage::PointSize, 0 });
}
@@ -1365,7 +1365,7 @@ namespace dxvk {
uint32_t texture = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f);
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
- const auto& stage = m_fsKey.Stages[i].data;
+ const auto& stage = m_fsKey.Stages[i].Contents;
bool processedTexture = false;
@@ -1378,7 +1378,7 @@ namespace dxvk {
// Add one for the texcoord count
// if we need to include the divider
- if (m_fsKey.Stages[i].data.Projected)
+ if (m_fsKey.Stages[i].Contents.Projected)
texcoordCnt++;
std::array<uint32_t, 4> indices = { 0, 1, 2, 3 };
@@ -1388,19 +1388,19 @@ namespace dxvk {
texcoord = m_module.opVectorShuffle(texcoord_t,
texcoord, texcoord, texcoordCnt, indices.data());
- uint32_t projIdx = m_fsKey.Stages[i].data.ProjectedCount;
+ uint32_t projIdx = m_fsKey.Stages[i].Contents.ProjectedCount;
if (projIdx == 0)
projIdx = texcoordCnt;
else
projIdx--;
- if (m_fsKey.Stages[i].data.Projected) {
+ if (m_fsKey.Stages[i].Contents.Projected) {
uint32_t projValue = m_module.opCompositeExtract(m_floatType, m_ps.in.TEXCOORD[i], 1, &projIdx);
uint32_t insertIdx = texcoordCnt - 1;
texcoord = m_module.opCompositeInsert(texcoord_t, projValue, texcoord, 1, &insertIdx);
}
- if (m_fsKey.Stages[i].data.Projected)
+ if (m_fsKey.Stages[i].Contents.Projected)
texture = m_module.opImageSampleProjImplicitLod(m_vec4Type, imageVarId, texcoord, imageOperands);
else
texture = m_module.opImageSampleImplicitLod(m_vec4Type, imageVarId, texcoord, imageOperands);
@@ -1690,7 +1690,7 @@ namespace dxvk {
}
}
- if (m_fsKey.Stages[0].data.GlobalSpecularEnable) {
+ if (m_fsKey.Stages[0].Contents.GlobalSpecularEnable) {
uint32_t specular = m_module.opFMul(m_vec4Type, m_ps.in.COLOR[1], m_module.constvec4f32(1.0f, 1.0f, 1.0f, 0.0f));
current = m_module.opFAdd(m_vec4Type, current, specular);
@@ -1790,7 +1790,7 @@ namespace dxvk {
// Samplers
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
auto& sampler = m_ps.samplers[i];
- D3DRESOURCETYPE type = D3DRESOURCETYPE(m_fsKey.Stages[i].data.Type + D3DRTYPE_TEXTURE);
+ D3DRESOURCETYPE type = D3DRESOURCETYPE(m_fsKey.Stages[i].Contents.Type + D3DRTYPE_TEXTURE);
spv::Dim dimensionality;
VkImageViewType viewType;
@@ -2072,10 +2072,8 @@ namespace dxvk {
std::hash<uint32_t> uint32hash;
- state.add(uint32hash(key.primitive.a));
- state.add(uint32hash(key.primitive.b));
- state.add(uint32hash(key.primitive.c));
- state.add(uint32hash(key.primitive.d));
+ for (uint32_t i = 0; i < countof(key.Data.Primitive); i++)
+ state.add(uint32hash(key.Data.Primitive[i]));
return state;
}
@@ -2087,8 +2085,8 @@ namespace dxvk {
std::hash<uint32_t> uint32hash;
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
- state.add(uint32hash(key.Stages[i].primitive.a));
- state.add(uint32hash(key.Stages[i].primitive.b));
+ for (uint32_t j = 0; j < countof(key.Stages[i].Primitive); j++)
+ state.add(uint32hash(key.Stages[i].Primitive[j]));
}
return state;
diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h
index 50dc060fe..746961638 100644
--- a/src/d3d9/d3d9_fixed_function.h
+++ b/src/d3d9/d3d9_fixed_function.h
@@ -66,53 +66,52 @@ namespace dxvk {
constexpr uint32_t TCIOffset = 16;
constexpr uint32_t TCIMask = 0b111 << TCIOffset;
- struct D3D9FFShaderKeyVS {
- D3D9FFShaderKeyVS() {
- // memcmp safety
- std::memset(this, 0, sizeof(*this));
- }
-
+ struct D3D9FFShaderKeyVSData {
union {
struct {
- uint32_t TexcoordIndices : 24;
+ uint32_t TexcoordIndices : 24;
- uint32_t HasPositionT : 1;
+ uint32_t HasPositionT : 1;
- uint32_t HasColor0 : 1; // Diffuse
- uint32_t HasColor1 : 1; // Specular
+ uint32_t HasColor0 : 1; // Diffuse
+ uint32_t HasColor1 : 1; // Specular
- uint32_t HasPointSize : 1;
+ uint32_t HasPointSize : 1;
- uint32_t UseLighting : 1;
+ uint32_t UseLighting : 1;
uint32_t NormalizeNormals : 1;
- uint32_t LocalViewer : 1;
- uint32_t RangeFog : 1;
+ uint32_t LocalViewer : 1;
+ uint32_t RangeFog : 1;
- uint32_t TexcoordFlags : 24;
+ uint32_t TexcoordFlags : 24;
- uint32_t DiffuseSource : 2;
- uint32_t AmbientSource : 2;
- uint32_t SpecularSource : 2;
- uint32_t EmissiveSource : 2;
+ uint32_t DiffuseSource : 2;
+ uint32_t AmbientSource : 2;
+ uint32_t SpecularSource : 2;
+ uint32_t EmissiveSource : 2;
- uint32_t TransformFlags : 24;
+ uint32_t TransformFlags : 24;
- uint32_t LightCount : 4;
+ uint32_t LightCount : 4;
- uint32_t TexcoordDeclMask : 24;
- uint32_t HasFog : 1;
- } data;
+ uint32_t TexcoordDeclMask : 24;
+ uint32_t HasFog : 1;
+ } Contents;
- struct {
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
- } primitive;
+ uint32_t Primitive[4];
};
};
+ struct D3D9FFShaderKeyVS {
+ D3D9FFShaderKeyVS() {
+ // memcmp safety
+ std::memset(&Data, 0, sizeof(Data));
+ }
+
+ D3D9FFShaderKeyVSData Data;
+ };
+
constexpr uint32_t TextureArgCount = 3;
struct D3D9FFShaderStage {
@@ -138,25 +137,21 @@ namespace dxvk {
// Affects all stages.
uint32_t GlobalSpecularEnable : 1;
uint32_t GlobalFlatShade : 1;
- } data;
+ } Contents;
- struct {
- uint32_t a;
- uint32_t b;
- } primitive;
+ uint32_t Primitive[2];
};
};
struct D3D9FFShaderKeyFS {
D3D9FFShaderKeyFS() {
// memcmp safety
- std::memset(this, 0, sizeof(*this));
+ std::memset(Stages, 0, sizeof(Stages));
+ // Normalize this. DISABLE != 0.
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
- auto& stage = Stages[i].data;
-
- stage.ColorOp = D3DTOP_DISABLE;
- stage.AlphaOp = D3DTOP_DISABLE;
+ Stages[i].Contents.ColorOp = D3DTOP_DISABLE;
+ Stages[i].Contents.AlphaOp = D3DTOP_DISABLE;
}
}
--
2.23.0.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment