mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-09-08 05:32:55 +02:00
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.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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_HAS_NORMAL = (1 << 9),
|
||||
VB_HAS_TANGENT = (1 << 10),
|
||||
VB_HAS_BINORMAL = (1 << 11),
|
||||
|
||||
VB_COL_SHIFT = 13,
|
||||
VB_HAS_COL0 = (1 << 13),
|
||||
VB_HAS_COL1 = (1 << 14),
|
||||
VB_COL_SHIFT = 12,
|
||||
VB_HAS_COL0 = (1 << 12),
|
||||
VB_HAS_COL1 = (1 << 13),
|
||||
VB_HAS_SHARED = 0x3f << 8,
|
||||
|
||||
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_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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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.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)
|
||||
{
|
||||
// transform the light dir into tangent space
|
||||
texinfo.embosslightshift = xfmem.texMtxInfo[i].embosslightshift;
|
||||
texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
|
||||
}
|
||||
else
|
||||
{
|
||||
texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
|
||||
}
|
||||
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];
|
||||
|
||||
switch (texinfo.texgentype)
|
||||
auto texgentype = texinfo.is_regular_texgen ? TexGenType::Regular : texinfo.other.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:
|
||||
|
||||
@@ -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 dualTexTrans_enabled : 1;
|
||||
VSExpand vs_expand : 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;
|
||||
|
||||
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>;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user