summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2026-08-07 17:12:00 +1200
committerScott Mansell <phiren@gmail.com>2026-08-07 18:42:52 +1200
commite5eabd08f583fbdd3bb2551778e5ecb67dff0843 (patch)
treebe3f2202e01d477b2de1fa7df11945691028528a /Source/Core
parent4af65cbed06816bf4626831af369d3cb3dd18675 (diff)
Optimize vertex_shader_uid_data down to 28 bytes
This started as a fixing a misalignment issue, but I got carried away. Was originally 41 bytes (overflowing it's expected 40 bytes by 1 bit). Now it's 27 bytes plus 8 bits of padding (ready for future expansion). The savings come from: - Removing UV usage from components, it can be reconstructed from texcoord_elem_count (saved 8 bits) - Removed the 8 unused bits from texMtxInfo_n_projection (saved 8 bits) - Removing unused bit from from start of components (saved 1 bit) - Removed extra bit from inputform, texgentype and sourcerow - packed texMtxInfo_n_projection and texcoord_elem_count back into the per texgen info space freed up above. (saved 24 bits) - Overlayed postMtx index and Emboss mode shifts into a union based on texgentype (saved 56 bits) - Move to a single-bit union tag, freeing up an extra bit for regular texgens. - Move PotMtx normalize into the freed up space (saved 8 bits) Total savings: 105 bits of data EDIT: Even worse, MSVC wasn't respecting pack(1) for bitfields at all, so on windows this struct was actually quite a bit larger. Something like 80 bytes, if not more. Fixed this by dropping the size of any enums used in these bit structs to u8. Our Common::BitField allows for the underlying type to be explicitly specified to something larger. msvc's bitfield packing appears to be completely braindead, can't mix sizes at all.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/GXPipelineTypes.h2
-rw-r--r--Source/Core/VideoCommon/NativeVertexFormat.h58
-rw-r--r--Source/Core/VideoCommon/PipelineUtils.cpp3
-rw-r--r--Source/Core/VideoCommon/VertexShaderGen.cpp150
-rw-r--r--Source/Core/VideoCommon/VertexShaderGen.h69
-rw-r--r--Source/Core/VideoCommon/XFMemory.h16
6 files changed, 165 insertions, 133 deletions
diff --git a/Source/Core/VideoCommon/GXPipelineTypes.h b/Source/Core/VideoCommon/GXPipelineTypes.h
index 388551e767..22014c993f 100644
--- a/Source/Core/VideoCommon/GXPipelineTypes.h
+++ b/Source/Core/VideoCommon/GXPipelineTypes.h
@@ -19,7 +19,7 @@ namespace VideoCommon
// As pipelines encompass both shader UIDs and render states, changes to either of these should
// also increment the pipeline UID version. Incrementing the UID version will cause all UID
// caches to be invalidated.
-constexpr u32 GX_PIPELINE_UID_VERSION = 8; // Last changed in PR 12185
+constexpr u32 GX_PIPELINE_UID_VERSION = 9; // Last changed in PR 14789
struct GXPipelineUid
{
diff --git a/Source/Core/VideoCommon/NativeVertexFormat.h b/Source/Core/VideoCommon/NativeVertexFormat.h
index 0f6be25541..76ca7875c2 100644
--- a/Source/Core/VideoCommon/NativeVertexFormat.h
+++ b/Source/Core/VideoCommon/NativeVertexFormat.h
@@ -12,36 +12,38 @@
// m_components
enum : u32
{
- VB_HAS_POSMTXIDX = (1 << 1),
- VB_HAS_TEXMTXIDX0 = (1 << 2),
- VB_HAS_TEXMTXIDX1 = (1 << 3),
- VB_HAS_TEXMTXIDX2 = (1 << 4),
- VB_HAS_TEXMTXIDX3 = (1 << 5),
- VB_HAS_TEXMTXIDX4 = (1 << 6),
- VB_HAS_TEXMTXIDX5 = (1 << 7),
- VB_HAS_TEXMTXIDX6 = (1 << 8),
- VB_HAS_TEXMTXIDX7 = (1 << 9),
- VB_HAS_TEXMTXIDXALL = (0xff << 2),
+ VB_HAS_TEXMTXIDX0 = (1 << 0),
+ VB_HAS_TEXMTXIDX1 = (1 << 1),
+ VB_HAS_TEXMTXIDX2 = (1 << 2),
+ VB_HAS_TEXMTXIDX3 = (1 << 3),
+ VB_HAS_TEXMTXIDX4 = (1 << 4),
+ VB_HAS_TEXMTXIDX5 = (1 << 5),
+ VB_HAS_TEXMTXIDX6 = (1 << 6),
+ VB_HAS_TEXMTXIDX7 = (1 << 7),
+ VB_HAS_TEXMTXIDXALL = (0xff << 0),
+
+ VB_HAS_POSMTXIDX = (1 << 8),
// VB_HAS_POS=0, // Implied, it always has pos! don't bother testing
- VB_HAS_NORMAL = (1 << 10),
- VB_HAS_TANGENT = (1 << 11),
- VB_HAS_BINORMAL = (1 << 12),
-
- VB_COL_SHIFT = 13,
- VB_HAS_COL0 = (1 << 13),
- VB_HAS_COL1 = (1 << 14),
-
- VB_HAS_UV0 = (1 << 15),
- VB_HAS_UV1 = (1 << 16),
- VB_HAS_UV2 = (1 << 17),
- VB_HAS_UV3 = (1 << 18),
- VB_HAS_UV4 = (1 << 19),
- VB_HAS_UV5 = (1 << 20),
- VB_HAS_UV6 = (1 << 21),
- VB_HAS_UV7 = (1 << 22),
- VB_HAS_UVALL = (0xff << 15),
- VB_HAS_UVTEXMTXSHIFT = 13,
+ VB_HAS_NORMAL = (1 << 9),
+ VB_HAS_TANGENT = (1 << 10),
+ VB_HAS_BINORMAL = (1 << 11),
+
+ VB_COL_SHIFT = 12,
+ VB_HAS_COL0 = (1 << 12),
+ VB_HAS_COL1 = (1 << 13),
+ VB_HAS_SHARED = 0x3f << 8,
+
+ VB_HAS_UV0 = (1 << 16),
+ VB_HAS_UV1 = (1 << 17),
+ VB_HAS_UV2 = (1 << 18),
+ VB_HAS_UV3 = (1 << 19),
+ VB_HAS_UV4 = (1 << 20),
+ VB_HAS_UV5 = (1 << 21),
+ VB_HAS_UV6 = (1 << 22),
+ VB_HAS_UV7 = (1 << 23),
+ VB_HAS_UVALL = (0xff << 16),
+ VB_HAS_UVTEXMTXSHIFT = 16,
};
struct AttributeFormat
diff --git a/Source/Core/VideoCommon/PipelineUtils.cpp b/Source/Core/VideoCommon/PipelineUtils.cpp
index 40d9d08458..7562c99d2e 100644
--- a/Source/Core/VideoCommon/PipelineUtils.cpp
+++ b/Source/Core/VideoCommon/PipelineUtils.cpp
@@ -125,13 +125,12 @@ GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
vertex_shader_uid_data* vs = out.vs_uid.GetUidData();
const PortableVertexDeclaration& decl = out.vertex_format->GetVertexDeclaration();
vs->position_has_3_elems = decl.position.components >= 3;
- vs->texcoord_elem_count = 0;
for (int i = 0; i < 8; i++)
{
if (decl.texcoords[i].enable)
{
ASSERT(decl.texcoords[i].components <= 3);
- vs->texcoord_elem_count |= decl.texcoords[i].components << (i * 2);
+ vs->texGenInfo[i].texcoord_elem_count = decl.texcoords[i].components;
}
}
out.vertex_format = nullptr;
diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp
index 837c30c556..ac0950628a 100644
--- a/Source/Core/VideoCommon/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/VertexShaderGen.cpp
@@ -22,52 +22,68 @@ VertexShaderUid GetVertexShaderUid()
VertexShaderUid out;
vertex_shader_uid_data* const uid_data = out.GetUidData();
uid_data->numTexGens = xfmem.numTexGen.numTexGens;
- uid_data->components = VertexLoaderManager::g_current_components;
uid_data->numColorChans = xfmem.numChan.numColorChans;
+ uid_data->components =
+ VertexLoaderManager::g_current_components & (VB_HAS_SHARED | VB_HAS_TEXMTXIDXALL);
+
+ // Move UV components into texcoord_elem_count
+ for (u32 i = 0; i < 8; i++)
+ {
+ if (VertexLoaderManager::g_current_components & (VB_HAS_UV0 << i))
+ {
+ // Hardcode to 2 components (ApplyDriverBugs will replace this with an exact count if needed)
+ uid_data->texGenInfo[i].texcoord_elem_count = 2;
+ }
+ }
+
GetLightingShaderUid(uid_data->lighting);
// transform texcoords
for (u32 i = 0; i < uid_data->numTexGens; ++i)
{
- auto& texinfo = uid_data->texMtxInfo[i];
+ auto& texinfo = uid_data->texGenInfo[i];
+ // sourcerow, inputform and texgentype each have an extra bit that gets ignored later.
+ // Validate and eliminate them now to save space in the UID.
+ ASSERT(xfmem.texMtxInfo[i].sourcerow <= SourceRow::Tex7);
texinfo.sourcerow = xfmem.texMtxInfo[i].sourcerow;
- texinfo.texgentype = xfmem.texMtxInfo[i].texgentype;
- texinfo.inputform = xfmem.texMtxInfo[i].inputform;
+ texinfo.inputform = xfmem.texMtxInfo[i].inputform == TexInputForm::ABC1 ? TexInputForm::ABC1 :
+ TexInputForm::AB11;
+ auto texgentype = xfmem.texMtxInfo[i].texgentype;
// first transformation
- switch (texinfo.texgentype)
+ switch (texgentype)
{
- case TexGenType::EmbossMap: // calculate tex coords into bump map
- if ((uid_data->components & (VB_HAS_TANGENT | VB_HAS_BINORMAL)) != 0)
- {
- // transform the light dir into tangent space
- texinfo.embosslightshift = xfmem.texMtxInfo[i].embosslightshift;
- texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
- }
- else
+ default:
+ case TexGenType::Regular:
+ texinfo.is_regular_texgen = true;
+ texinfo.regular.projection = xfmem.texMtxInfo[i].projection;
+
+ // only put dualTexTrans_enabled in UID if we have at least one regular texgen.
+ uid_data->dualTexTrans_enabled = xfmem.dualTexTrans.enabled;
+
+ // CHECKME: does this only work for regular tex gen types?
+ if (uid_data->dualTexTrans_enabled)
{
- texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
+ texinfo.regular.postmtx_index = xfmem.postMtxInfo[i].index;
+ texinfo.regular.postmtx_normalize = xfmem.postMtxInfo[i].normalize;
}
break;
+ case TexGenType::EmbossMap: // calculate tex coords into bump map
+ texinfo.is_regular_texgen = false;
+ texinfo.other.texgentype = texgentype;
+
+ // transform the light dir into tangent space
+ texinfo.other.emboss_sourceshift = xfmem.texMtxInfo[i].embosssourceshift;
+ if ((uid_data->components & (VB_HAS_TANGENT | VB_HAS_BINORMAL)) != 0)
+ texinfo.other.emboss_lightshift = xfmem.texMtxInfo[i].embosslightshift;
+ break;
case TexGenType::Color0:
case TexGenType::Color1:
+ texinfo.is_regular_texgen = false;
+ texinfo.other.texgentype = texgentype;
break;
- case TexGenType::Regular:
- default:
- uid_data->texMtxInfo_n_projection |= static_cast<u32>(xfmem.texMtxInfo[i].projection.Value())
- << i;
- break;
- }
-
- uid_data->dualTexTrans_enabled = xfmem.dualTexTrans.enabled;
- // CHECKME: does this only work for regular tex gen types?
- if (uid_data->dualTexTrans_enabled && texinfo.texgentype == TexGenType::Regular)
- {
- auto& postInfo = uid_data->postMtxInfo[i];
- postInfo.index = xfmem.postMtxInfo[i].index;
- postInfo.normalize = xfmem.postMtxInfo[i].normalize;
}
}
@@ -163,10 +179,10 @@ static void WriteTexCoordTransforms(APIType api_type, const ShaderHostConfig& ho
{
for (u32 i = 0; i < uid_data->numTexGens; ++i)
{
- auto& texinfo = uid_data->texMtxInfo[i];
+ auto& texinfo = uid_data->texGenInfo[i];
out.Write("vec3 dolphin_transform_texcoord{}(vec4 coord)\n", i);
out.Write("{{\n");
- if (texinfo.texgentype != TexGenType::Regular)
+ if (!texinfo.is_regular_texgen)
{
out.Write("\treturn vec3(coord.xyz);\n");
}
@@ -176,7 +192,7 @@ static void WriteTexCoordTransforms(APIType api_type, const ShaderHostConfig& ho
if ((uid_data->components & (VB_HAS_TEXMTXIDX0 << i)) != 0)
{
out.Write("\tint tmp = int(rawtex{}.z);\n", i);
- if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
+ if (texinfo.regular.projection == TexSize::STQ)
{
out.Write("\tresult = vec3(dot(coord, " I_TRANSFORMMATRICES
"[tmp]), dot(coord, " I_TRANSFORMMATRICES
@@ -190,7 +206,7 @@ static void WriteTexCoordTransforms(APIType api_type, const ShaderHostConfig& ho
}
else
{
- if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
+ if (texinfo.regular.projection == TexSize::STQ)
{
out.Write("\tresult = vec3(dot(coord, " I_TEXMATRICES "[{}]), dot(coord, " I_TEXMATRICES
"[{}]), dot(coord, " I_TEXMATRICES "[{}]));\n",
@@ -206,14 +222,14 @@ static void WriteTexCoordTransforms(APIType api_type, const ShaderHostConfig& ho
// CHECKME: does this only work for regular tex gen types?
if (uid_data->dualTexTrans_enabled)
{
- auto& postInfo = uid_data->postMtxInfo[i];
+ auto postmtx_index = texinfo.regular.postmtx_index;
out.Write("\tvec4 P0 = " I_POSTTRANSFORMMATRICES "[{}];\n"
"\tvec4 P1 = " I_POSTTRANSFORMMATRICES "[{}];\n"
"\tvec4 P2 = " I_POSTTRANSFORMMATRICES "[{}];\n",
- postInfo.index & 0x3f, (postInfo.index + 1) & 0x3f, (postInfo.index + 2) & 0x3f);
+ postmtx_index & 0x3f, (postmtx_index + 1) & 0x3f, (postmtx_index + 2) & 0x3f);
- if (postInfo.normalize)
+ if (texinfo.regular.postmtx_normalize)
out.Write("\tresult = normalize(result);\n");
// multiply by postmatrix
@@ -313,7 +329,7 @@ static void WriteVertexDefines(APIType, const ShaderHostConfig&,
for (u32 i = 0; i < uid_data->numTexGens; i++)
{
- if ((uid_data->components & (VB_HAS_UV0 << i)) != 0)
+ if (uid_data->texGenInfo[i].texcoord_elem_count != 0)
{
out.Write("#define HAS_TEXTURE_COORD_{} 1\n", i);
}
@@ -415,7 +431,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
{
const u32 has_texmtx = (uid_data->components & (VB_HAS_TEXMTXIDX0 << i));
- if ((uid_data->components & (VB_HAS_UV0 << i)) != 0 || has_texmtx != 0)
+ if (uid_data->texGenInfo[i].texcoord_elem_count != 0 || has_texmtx != 0)
{
out.Write("ATTRIBUTE_LOCATION({:s}) in float{} rawtex{};\n", ShaderAttrib::TexCoord0 + i,
has_texmtx != 0 ? 3 : 2, i);
@@ -472,30 +488,25 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
for (int i = 0; i < 8; i++)
{
- if (uid_data->components & (VB_HAS_UV0 << i))
+ switch (uid_data->texGenInfo[i].texcoord_elem_count)
{
- u32 ncomponents = (uid_data->texcoord_elem_count >> (2 * i)) & 3;
- if (ncomponents < 2)
- {
- out.Write(" float tex{};\n", i);
- input_extract.Write("float3 rawtex{0} = float3(i.tex{0}, 0.0f, 0.0f);\n", i);
- }
- else if (ncomponents == 2)
- {
- out.Write(" float tex{0}_0;\n"
- " float tex{0}_1;\n",
- i);
- input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, 0.0f);\n", i);
- }
- else
- {
- out.Write(" float tex{0}_0;\n"
- " float tex{0}_1;\n"
- " float tex{0}_2;\n",
- i);
- input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, i.tex{0}_2);\n",
- i);
- }
+ case 1:
+ out.Write(" float tex{};\n", i);
+ input_extract.Write("float3 rawtex{0} = float3(i.tex{0}, 0.0f, 0.0f);\n", i);
+ break;
+ case 2:
+ out.Write(" float tex{0}_0;\n"
+ " float tex{0}_1;\n",
+ i);
+ input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, 0.0f);\n", i);
+ break;
+ case 3:
+ out.Write(" float tex{0}_0;\n"
+ " float tex{0}_1;\n"
+ " float tex{0}_2;\n",
+ i);
+ input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, i.tex{0}_2);\n", i);
+ break;
}
}
out.Write("}};\n\n"
@@ -633,7 +644,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
for (u32 i = 0; i < uid_data->numTexGens; ++i)
{
- auto& texinfo = uid_data->texMtxInfo[i];
+ auto& texinfo = uid_data->texGenInfo[i];
out.Write("\t{{\n");
out.Write("\t\tvec4 coord = vec4(0.0, 0.0, 1.0, 1.0);\n");
@@ -649,7 +660,9 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
break;
case SourceRow::Colors:
- ASSERT(texinfo.texgentype == TexGenType::Color0 || texinfo.texgentype == TexGenType::Color1);
+ ASSERT(!texinfo.is_regular_texgen);
+ ASSERT(texinfo.other.texgentype == TexGenType::Color0 ||
+ texinfo.other.texgentype == TexGenType::Color1);
break;
case SourceRow::BinormalT:
if ((uid_data->components & VB_HAS_TANGENT) != 0)
@@ -664,9 +677,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
break;
default:
- ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
u32 texnum = static_cast<u32>(texinfo.sourcerow) - static_cast<u32>(SourceRow::Tex0);
- if ((uid_data->components & (VB_HAS_UV0 << (texnum))) != 0)
+ if (uid_data->texGenInfo[texnum].texcoord_elem_count != 0)
{
out.Write("\t\tcoord = vec4(rawtex{}.x, rawtex{}.y, 1.0, 1.0);\n", texnum, texnum);
}
@@ -917,23 +929,25 @@ void WriteVertexBody(APIType api_type, const ShaderHostConfig& host_config,
for (u32 i = 0; i < uid_data->numTexGens; ++i)
{
- auto& texinfo = uid_data->texMtxInfo[i];
+ auto& texinfo = uid_data->texGenInfo[i];
+
+ auto texgentype = texinfo.is_regular_texgen ? TexGenType::Regular : texinfo.other.texgentype;
- switch (texinfo.texgentype)
+ switch (texgentype)
{
case TexGenType::EmbossMap: // calculate tex coords into bump map
out.Write("\t{{\n");
// transform the light dir into tangent space
out.Write("\t\tvec3 ldir = normalize(" LIGHT_POS ".xyz - vertex_output.position.xyz);\n",
- LIGHT_POS_PARAMS(texinfo.embosslightshift));
+ LIGHT_POS_PARAMS(texinfo.other.emboss_lightshift));
out.Write("\t\tvec3 tangent = vertex_input.tangent * dolphin_normal_matrix();\n");
out.Write("\t\tvec3 binormal = vertex_input.binormal * dolphin_normal_matrix();\n");
out.Write("\t\tvertex_output.texture_coord_{}.xyz = vertex_output.texture_coord_{}.xyz + "
"vec3(dot(ldir, tangent), "
"dot(ldir, binormal), 0.0);\n",
- i, texinfo.embosssourceshift);
+ i, texinfo.other.emboss_sourceshift);
out.Write("\t}}\n");
break;
case TexGenType::Color0:
diff --git a/Source/Core/VideoCommon/VertexShaderGen.h b/Source/Core/VideoCommon/VertexShaderGen.h
index 3e9b73940b..a0fd342621 100644
--- a/Source/Core/VideoCommon/VertexShaderGen.h
+++ b/Source/Core/VideoCommon/VertexShaderGen.h
@@ -10,9 +10,10 @@
#include "VideoCommon/ShaderGenCommon.h"
enum class APIType;
-enum class TexInputForm : u32;
-enum class TexGenType : u32;
-enum class SourceRow : u32;
+enum class TexInputForm : u8;
+enum class TexGenType : u8;
+enum class SourceRow : u8;
+enum class TexSize : u8;
enum class VSExpand : u32;
// TODO should be reordered
@@ -50,41 +51,57 @@ constexpr ShaderAttrib operator+(ShaderAttrib attrib, int offset)
return static_cast<ShaderAttrib>(static_cast<u8>(attrib) + offset);
}
-#pragma pack(1)
-
-struct vertex_shader_uid_data
+// Currently optimized to 28 bytes (with 8 bits spare)
+// The smaller (and less redundant) this is, the better.
+// Though, it probably does like to be somewhat aligned.
+struct alignas(4) vertex_shader_uid_data
{
u32 NumValues() const { return sizeof(vertex_shader_uid_data); }
- u32 components : 23;
- u32 numTexGens : 4;
- u32 numColorChans : 2;
+ u32 components : 14;
+ u32 position_has_3_elems : 1;
u32 dualTexTrans_enabled : 1;
+ u32 numTexGens : 4; // if more bits are needed, this could be eliminated by somehow marking the
+ // first unused texGen as empty.
+ u32 numColorChans : 2; // Output color channels.
VSExpand vs_expand : 2;
- u32 position_has_3_elems : 1;
- u16 texcoord_elem_count; // 2 bits per texcoord input
- u16 texMtxInfo_n_projection; // Stored separately to guarantee that the texMtxInfo struct is
- // 8 bits wide
+ u32 pad : 8;
+ // texInfo is optimized to fit all per-texgen config into just 16-bits.
+ // But it did require a union
struct
{
- TexInputForm inputform : 2;
- TexGenType texgentype : 3;
- SourceRow sourcerow : 5;
- u32 embosssourceshift : 3;
- u32 embosslightshift : 3;
- } texMtxInfo[8];
+ u8 texcoord_elem_count : 2;
+ TexInputForm inputform : 1;
+ SourceRow sourcerow : 4;
+ bool is_regular_texgen : 1; // union tag
+ union
+ {
+ struct
+ {
+ u8 postmtx_index : 6;
+ u8 postmtx_normalize : 1;
+ TexSize projection : 1;
+ } regular;
+ struct
+ {
+ TexGenType texgentype : 2;
+ // these are only used by EmbossMap texgen.
+ u8 emboss_sourceshift : 3;
+ u8 emboss_lightshift : 3;
+ } other;
+ };
+ } texGenInfo[8];
- struct
- {
- u32 index : 6;
- u32 normalize : 1;
- u32 pad : 1;
- } postMtxInfo[8];
+ static_assert(sizeof(texGenInfo[0]) == 2, "texGenInfo should be 2 bytes per texgen");
LightingUidData lighting;
};
-#pragma pack()
+
+// We do need to make sure lighting is correctly aligned
+static_assert(offsetof(vertex_shader_uid_data, lighting) % alignof(LightingUidData) == 0);
+static_assert(offsetof(vertex_shader_uid_data, texGenInfo) % alignof(u32) == 0);
+static_assert(sizeof(vertex_shader_uid_data) == 28, "vertex_shader_uid_data should be 28 bytes");
using VertexShaderUid = ShaderUid<vertex_shader_uid_data>;
diff --git a/Source/Core/VideoCommon/XFMemory.h b/Source/Core/VideoCommon/XFMemory.h
index 4077e50859..04d22dc9f3 100644
--- a/Source/Core/VideoCommon/XFMemory.h
+++ b/Source/Core/VideoCommon/XFMemory.h
@@ -18,7 +18,7 @@ constexpr size_t NUM_XF_COLOR_CHANNELS = 2;
// Lighting
// Projection
-enum class TexSize : u32
+enum class TexSize : u8
{
ST = 0,
STQ = 1
@@ -30,7 +30,7 @@ struct fmt::formatter<TexSize> : EnumFormatter<TexSize::STQ>
};
// Input form
-enum class TexInputForm : u32
+enum class TexInputForm : u8
{
AB11 = 0,
ABC1 = 1
@@ -63,7 +63,7 @@ struct fmt::formatter<NormalCount> : EnumFormatter<NormalCount::Invalid>
};
// Texture generation type
-enum class TexGenType : u32
+enum class TexGenType : u8
{
Regular = 0,
EmbossMap = 1, // Used when bump mapping
@@ -83,7 +83,7 @@ struct fmt::formatter<TexGenType> : EnumFormatter<TexGenType::Color1>
};
// Source row
-enum class SourceRow : u32
+enum class SourceRow : u8
{
Geom = 0, // Input is abc
Normal = 1, // Input is abc
@@ -318,11 +318,11 @@ struct fmt::formatter<INVTXSPEC>
union TexMtxInfo
{
BitField<0, 1, u32> unknown;
- BitField<1, 1, TexSize> projection;
- BitField<2, 1, TexInputForm> inputform;
+ BitField<1, 1, TexSize, u32> projection;
+ BitField<2, 1, TexInputForm, u32> inputform;
BitField<3, 1, u32> unknown2;
- BitField<4, 3, TexGenType> texgentype;
- BitField<7, 5, SourceRow> sourcerow;
+ BitField<4, 3, TexGenType, u32> texgentype;
+ BitField<7, 5, SourceRow, u32> sourcerow;
BitField<12, 3, u32> embosssourceshift; // what generated texcoord to use
BitField<15, 3, u32> embosslightshift; // light index that is used
u32 hex;