Convert XFMemory to BitField and enum class

Additionally a new ClipDisable union has been added (though it is not currently used by Dolphin).
This commit is contained in:
Pokechu22 2021-02-10 16:01:42 -08:00
parent 953e09428f
commit aab81d5aa0
12 changed files with 299 additions and 202 deletions

View File

@ -80,7 +80,7 @@ void TransformPosition(const InputVertexData* src, OutputVertexData* dst)
const float* mat = &xfmem.posMatrices[src->posMtx * 4];
MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
if (xfmem.projection.type == GX_PERSPECTIVE)
if (xfmem.projection.type == ProjectionType::Perspective)
{
MultipleVec3Perspective(dst->mvPosition, xfmem.projection.rawProjection,
dst->projectedPosition);
@ -115,39 +115,42 @@ static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum,
Vec3 src;
switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
case SourceRow::Geom:
src = srcVertex->position;
break;
case XF_SRCNORMAL_INROW:
case SourceRow::Normal:
src = srcVertex->normal[0];
break;
case XF_SRCBINORMAL_T_INROW:
case SourceRow::BinormalT:
src = srcVertex->normal[1];
break;
case XF_SRCBINORMAL_B_INROW:
case SourceRow::BinormalB:
src = srcVertex->normal[2];
break;
default:
ASSERT(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
src.x = srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW][0];
src.y = srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW][1];
{
ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
u32 texnum = static_cast<u32>(texinfo.sourcerow.Value()) - static_cast<u32>(SourceRow::Tex0);
src.x = srcVertex->texCoords[texnum][0];
src.y = srcVertex->texCoords[texnum][1];
src.z = 1.0f;
break;
}
}
const float* mat = &xfmem.posMatrices[srcVertex->texMtx[coordNum] * 4];
Vec3* dst = &dstVertex->texCoords[coordNum];
if (texinfo.projection == XF_TEXPROJ_ST)
if (texinfo.projection == TexSize::ST)
{
if (texinfo.inputform == XF_TEXINPUT_AB11)
if (texinfo.inputform == TexInputForm::AB11)
MultiplyVec2Mat24(src, mat, *dst);
else
MultiplyVec3Mat24(src, mat, *dst);
}
else // texinfo.projection == XF_TEXPROJ_STQ
else // texinfo.projection == TexSize::STQ
{
if (texinfo.inputform == XF_TEXINPUT_AB11)
if (texinfo.inputform == TexInputForm::AB11)
MultiplyVec2Mat34(src, mat, *dst);
else
MultiplyVec3Mat34(src, mat, *dst);
@ -209,28 +212,28 @@ static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Ve
switch (chan.attnfunc)
{
case LIGHTATTN_NONE:
case LIGHTATTN_DIR:
case AttenuationFunc::None:
case AttenuationFunc::Dir:
{
ldir = ldir.Normalized();
if (ldir == Vec3(0.0f, 0.0f, 0.0f))
ldir = normal;
break;
}
case LIGHTATTN_SPEC:
case AttenuationFunc::Spec:
{
ldir = ldir.Normalized();
attn = (ldir * normal) >= 0.0 ? std::max(0.0f, light->dir * normal) : 0;
Vec3 attLen = Vec3(1.0, attn, attn * attn);
Vec3 cosAttn = light->cosatt;
Vec3 distAttn = light->distatt;
if (chan.diffusefunc != LIGHTDIF_NONE)
if (chan.diffusefunc != DiffuseFunc::None)
distAttn = distAttn.Normalized();
attn = SafeDivide(std::max(0.0f, attLen * cosAttn), attLen * distAttn);
break;
}
case LIGHTATTN_SPOT:
case AttenuationFunc::Spot:
{
float dist2 = ldir.Length2();
float dist = sqrtf(dist2);
@ -243,7 +246,7 @@ static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Ve
break;
}
default:
PanicAlertFmt("LightColor");
PanicAlertFmt("Invalid attnfunc: {}", chan.attnfunc);
}
return attn;
@ -260,18 +263,18 @@ static void LightColor(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
float difAttn = ldir * normal;
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
case DiffuseFunc::None:
AddScaledIntegerColor(light->color, attn, lightCol);
break;
case LIGHTDIF_SIGN:
case DiffuseFunc::Sign:
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
break;
case LIGHTDIF_CLAMP:
case DiffuseFunc::Clamp:
difAttn = std::max(0.0f, difAttn);
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
break;
default:
ASSERT(0);
PanicAlertFmt("Invalid diffusefunc: {}", chan.attnfunc);
}
}
@ -286,18 +289,18 @@ static void LightAlpha(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
float difAttn = ldir * normal;
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
case DiffuseFunc::None:
lightCol += light->color[0] * attn;
break;
case LIGHTDIF_SIGN:
case DiffuseFunc::Sign:
lightCol += light->color[0] * attn * difAttn;
break;
case LIGHTDIF_CLAMP:
case DiffuseFunc::Clamp:
difAttn = std::max(0.0f, difAttn);
lightCol += light->color[0] * attn * difAttn;
break;
default:
ASSERT(0);
PanicAlertFmt("Invalid diffusefunc: {}", chan.attnfunc);
}
}
@ -311,17 +314,16 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
// color
const LitChannel& colorchan = xfmem.color[chan];
if (colorchan.matsource)
matcolor = src->color[chan]; // vertex
if (colorchan.matsource == MatSource::Vertex)
matcolor = src->color[chan];
else
std::memcpy(matcolor.data(), &xfmem.matColor[chan], sizeof(u32));
if (colorchan.enablelighting)
{
Vec3 lightCol;
if (colorchan.ambsource)
if (colorchan.ambsource == AmbSource::Vertex)
{
// vertex
lightCol.x = src->color[chan][1];
lightCol.y = src->color[chan][2];
lightCol.z = src->color[chan][3];
@ -355,16 +357,16 @@ void TransformColor(const InputVertexData* src, OutputVertexData* dst)
// alpha
const LitChannel& alphachan = xfmem.alpha[chan];
if (alphachan.matsource)
matcolor[0] = src->color[chan][0]; // vertex
if (alphachan.matsource == MatSource::Vertex)
matcolor[0] = src->color[chan][0];
else
matcolor[0] = xfmem.matColor[chan] & 0xff;
if (xfmem.alpha[chan].enablelighting)
{
float lightCol;
if (alphachan.ambsource)
lightCol = src->color[chan][0]; // vertex
if (alphachan.ambsource == AmbSource::Vertex)
lightCol = src->color[chan][0];
else
lightCol = static_cast<float>(xfmem.ambColor[chan] & 0xff);
@ -397,10 +399,10 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
switch (texinfo.texgentype)
{
case XF_TEXGEN_REGULAR:
case TexGenType::Regular:
TransformTexCoordRegular(texinfo, coordNum, src, dst);
break;
case XF_TEXGEN_EMBOSS_MAP:
case TexGenType::EmbossMap:
{
const LightPointer* light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
@ -413,22 +415,22 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
}
break;
case XF_TEXGEN_COLOR_STRGBC0:
ASSERT(texinfo.sourcerow == XF_SRCCOLORS_INROW);
ASSERT(texinfo.inputform == XF_TEXINPUT_AB11);
case TexGenType::Color0:
ASSERT(texinfo.sourcerow == SourceRow::Colors);
ASSERT(texinfo.inputform == TexInputForm::AB11);
dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
case XF_TEXGEN_COLOR_STRGBC1:
ASSERT(texinfo.sourcerow == XF_SRCCOLORS_INROW);
ASSERT(texinfo.inputform == XF_TEXINPUT_AB11);
case TexGenType::Color1:
ASSERT(texinfo.sourcerow == SourceRow::Colors);
ASSERT(texinfo.inputform == TexInputForm::AB11);
dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
default:
ERROR_LOG_FMT(VIDEO, "Bad tex gen type {}", texinfo.texgentype.Value());
ERROR_LOG_FMT(VIDEO, "Bad tex gen type {}", texinfo.texgentype);
break;
}
}

View File

@ -45,7 +45,7 @@ void GeometryShaderManager::SetConstants()
{
s_projection_changed = false;
if (xfmem.projection.type == GX_PERSPECTIVE)
if (xfmem.projection.type == ProjectionType::Perspective)
{
float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) *
(g_ActiveConfig.iStereoDepthPercentage / 100.0f);

View File

@ -17,29 +17,32 @@ static void GenerateLightShader(ShaderCode& object, const LightingUidData& uid_d
const char* swizzle = alpha ? "a" : "rgb";
const char* swizzle_components = (alpha) ? "" : "3";
const u32 attnfunc = (uid_data.attnfunc >> (2 * litchan_index)) & 0x3;
const u32 diffusefunc = (uid_data.diffusefunc >> (2 * litchan_index)) & 0x3;
const auto attnfunc =
static_cast<AttenuationFunc>((uid_data.attnfunc >> (2 * litchan_index)) & 0x3);
const auto diffusefunc =
static_cast<DiffuseFunc>((uid_data.diffusefunc >> (2 * litchan_index)) & 0x3);
switch (attnfunc)
{
case LIGHTATTN_NONE:
case LIGHTATTN_DIR:
case AttenuationFunc::None:
case AttenuationFunc::Dir:
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
object.Write("attn = 1.0;\n");
object.Write("if (length(ldir) == 0.0)\n\t ldir = _norm0;\n");
break;
case LIGHTATTN_SPEC:
case AttenuationFunc::Spec:
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
object.Write("attn = (dot(_norm0, ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR
".xyz)) : 0.0;\n",
LIGHT_DIR_PARAMS(index));
object.Write("cosAttn = " LIGHT_COSATT ".xyz;\n", LIGHT_COSATT_PARAMS(index));
object.Write("distAttn = {}(" LIGHT_DISTATT ".xyz);\n",
(diffusefunc == LIGHTDIF_NONE) ? "" : "normalize", LIGHT_DISTATT_PARAMS(index));
(diffusefunc == DiffuseFunc::None) ? "" : "normalize",
LIGHT_DISTATT_PARAMS(index));
object.Write("attn = max(0.0f, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
"float3(1.0, attn, attn*attn));\n");
break;
case LIGHTATTN_SPOT:
case AttenuationFunc::Spot:
object.Write("ldir = " LIGHT_POS ".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index));
object.Write("dist2 = dot(ldir, ldir);\n"
"dist = sqrt(dist2);\n"
@ -56,14 +59,14 @@ static void GenerateLightShader(ShaderCode& object, const LightingUidData& uid_d
switch (diffusefunc)
{
case LIGHTDIF_NONE:
case DiffuseFunc::None:
object.Write("lacc.{} += int{}(round(attn * float{}(" LIGHT_COL ")));\n", swizzle,
swizzle_components, swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
break;
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
case DiffuseFunc::Sign:
case DiffuseFunc::Clamp:
object.Write("lacc.{} += int{}(round(attn * {}dot(ldir, _norm0)) * float{}(" LIGHT_COL ")));\n",
swizzle, swizzle_components, diffusefunc != LIGHTDIF_SIGN ? "max(0.0," : "(",
swizzle, swizzle_components, diffusefunc != DiffuseFunc::Sign ? "max(0.0," : "(",
swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
break;
default:
@ -151,23 +154,23 @@ void GetLightingShaderUid(LightingUidData& uid_data)
{
for (u32 j = 0; j < NUM_XF_COLOR_CHANNELS; j++)
{
uid_data.matsource |= xfmem.color[j].matsource << j;
uid_data.matsource |= xfmem.alpha[j].matsource << (j + 2);
uid_data.matsource |= static_cast<u32>(xfmem.color[j].matsource.Value()) << j;
uid_data.matsource |= static_cast<u32>(xfmem.alpha[j].matsource.Value()) << (j + 2);
uid_data.enablelighting |= xfmem.color[j].enablelighting << j;
uid_data.enablelighting |= xfmem.alpha[j].enablelighting << (j + 2);
if ((uid_data.enablelighting & (1 << j)) != 0) // Color lights
{
uid_data.ambsource |= xfmem.color[j].ambsource << j;
uid_data.attnfunc |= xfmem.color[j].attnfunc << (2 * j);
uid_data.diffusefunc |= xfmem.color[j].diffusefunc << (2 * j);
uid_data.ambsource |= static_cast<u32>(xfmem.color[j].ambsource.Value()) << j;
uid_data.attnfunc |= static_cast<u32>(xfmem.color[j].attnfunc.Value()) << (2 * j);
uid_data.diffusefunc |= static_cast<u32>(xfmem.color[j].diffusefunc.Value()) << (2 * j);
uid_data.light_mask |= xfmem.color[j].GetFullLightMask() << (8 * j);
}
if ((uid_data.enablelighting & (1 << (j + 2))) != 0) // Alpha lights
{
uid_data.ambsource |= xfmem.alpha[j].ambsource << (j + 2);
uid_data.attnfunc |= xfmem.alpha[j].attnfunc << (2 * (j + 2));
uid_data.diffusefunc |= xfmem.alpha[j].diffusefunc << (2 * (j + 2));
uid_data.ambsource |= static_cast<u32>(xfmem.alpha[j].ambsource.Value()) << (j + 2);
uid_data.attnfunc |= static_cast<u32>(xfmem.alpha[j].attnfunc.Value()) << (2 * (j + 2));
uid_data.diffusefunc |= static_cast<u32>(xfmem.alpha[j].diffusefunc.Value()) << (2 * (j + 2));
uid_data.light_mask |= xfmem.alpha[j].GetFullLightMask() << (8 * (j + 2));
}
}

View File

@ -212,7 +212,8 @@ PixelShaderUid GetPixelShaderUid()
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
{
// optional perspective divides
uid_data->texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
uid_data->texMtxInfo_n_projection |= static_cast<u32>(xfmem.texMtxInfo[i].projection.Value())
<< i;
}
}

View File

@ -39,26 +39,26 @@ void WriteLightingFunction(ShaderCode& out)
" float dist, dist2, attn;\n"
"\n"
" switch (attnfunc) {{\n");
out.Write(" case {}u: // LIGNTATTN_NONE\n", LIGHTATTN_NONE);
out.Write(" case {}u: // LIGHTATTN_DIR\n", LIGHTATTN_DIR);
out.Write(" case {:s}:\n", AttenuationFunc::None);
out.Write(" case {:s}:\n", AttenuationFunc::Dir);
out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n"
" attn = 1.0;\n"
" if (length(ldir) == 0.0)\n"
" ldir = normal;\n"
" break;\n\n");
out.Write(" case {}u: // LIGHTATTN_SPEC\n", LIGHTATTN_SPEC);
out.Write(" case {:s}:\n", AttenuationFunc::Spec);
out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n"
" attn = (dot(normal, ldir) >= 0.0) ? max(0.0, dot(normal, " I_LIGHTS
"[index].dir.xyz)) : 0.0;\n"
" cosAttn = " I_LIGHTS "[index].cosatt.xyz;\n");
out.Write(" if (diffusefunc == {}u) // LIGHTDIF_NONE\n", LIGHTDIF_NONE);
out.Write(" if (diffusefunc == {:s})\n", DiffuseFunc::None);
out.Write(" distAttn = " I_LIGHTS "[index].distatt.xyz;\n"
" else\n"
" distAttn = normalize(" I_LIGHTS "[index].distatt.xyz);\n"
" attn = max(0.0, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
"float3(1.0, attn, attn*attn));\n"
" break;\n\n");
out.Write(" case {}u: // LIGHTATTN_SPOT\n", LIGHTATTN_SPOT);
out.Write(" case {:s}:\n", AttenuationFunc::Spot);
out.Write(" ldir = " I_LIGHTS "[index].pos.xyz - pos.xyz;\n"
" dist2 = dot(ldir, ldir);\n"
" dist = sqrt(dist2);\n"
@ -75,12 +75,12 @@ void WriteLightingFunction(ShaderCode& out)
" }}\n"
"\n"
" switch (diffusefunc) {{\n");
out.Write(" case {}u: // LIGHTDIF_NONE\n", LIGHTDIF_NONE);
out.Write(" case {:s}:\n", DiffuseFunc::None);
out.Write(" return int4(round(attn * float4(" I_LIGHTS "[index].color)));\n\n");
out.Write(" case {}u: // LIGHTDIF_SIGN\n", LIGHTDIF_SIGN);
out.Write(" case {:s}:\n", DiffuseFunc::Sign);
out.Write(" return int4(round(attn * dot(ldir, normal) * float4(" I_LIGHTS
"[index].color)));\n\n");
out.Write(" case {}u: // LIGHTDIF_CLAMP\n", LIGHTDIF_CLAMP);
out.Write(" case {:s}:\n", DiffuseFunc::Clamp);
out.Write(" return int4(round(attn * max(0.0, dot(ldir, normal)) * float4(" I_LIGHTS
"[index].color)));\n\n");
out.Write(" default:\n"

View File

@ -403,27 +403,27 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n"
" uint texMtxInfo = xfmem_texMtxInfo(texgen);\n");
out.Write(" switch ({}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().sourcerow));
out.Write(" case {}u: // XF_SRCGEOM_INROW\n", XF_SRCGEOM_INROW);
out.Write(" case {:s}:\n", SourceRow::Geom);
out.Write(" coord.xyz = rawpos.xyz;\n");
out.Write(" break;\n\n");
out.Write(" case {}u: // XF_SRCNORMAL_INROW\n", XF_SRCNORMAL_INROW);
out.Write(" case {:s}:\n", SourceRow::Normal);
out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM0 */) != 0u) ? rawnorm0.xyz : coord.xyz;",
VB_HAS_NRM0);
out.Write(" break;\n\n");
out.Write(" case {}u: // XF_SRCBINORMAL_T_INROW\n", XF_SRCBINORMAL_T_INROW);
out.Write(" case {:s}:\n", SourceRow::BinormalT);
out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM1 */) != 0u) ? rawnorm1.xyz : coord.xyz;",
VB_HAS_NRM1);
out.Write(" break;\n\n");
out.Write(" case {}u: // XF_SRCBINORMAL_B_INROW\n", XF_SRCBINORMAL_B_INROW);
out.Write(" case {:s}:\n", SourceRow::BinormalB);
out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM2 */) != 0u) ? rawnorm2.xyz : coord.xyz;",
VB_HAS_NRM2);
out.Write(" break;\n\n");
for (u32 i = 0; i < 8; i++)
{
out.Write(" case {}u: // XF_SRCTEX{}_INROW\n", XF_SRCTEX0_INROW + i, i);
out.Write(" case {:s}:\n", static_cast<SourceRow>(static_cast<u32>(SourceRow::Tex0) + i));
out.Write(
" coord = ((components & {}u /* VB_HAS_UV{} */) != 0u) ? float4(rawtex{}.x, rawtex{}.y, "
"1.0, 1.0) : coord;\n",
@ -434,8 +434,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
"\n");
out.Write(" // Input form of AB11 sets z element to 1.0\n");
out.Write(" if ({} == {}u) // inputform == XF_TEXINPUT_AB11\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), XF_TEXINPUT_AB11);
out.Write(" if ({} == {:s}) // inputform == AB11\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), TexInputForm::AB11);
out.Write(" coord.z = 1.0f;\n"
"\n");
@ -444,7 +444,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" float3 output_tex;\n"
" switch (texgentype)\n"
" {{\n");
out.Write(" case {}u: // XF_TEXGEN_EMBOSS_MAP\n", XF_TEXGEN_EMBOSS_MAP);
out.Write(" case {:s}:\n", TexGenType::EmbossMap);
out.Write(" {{\n");
out.Write(" uint light = {};\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().embosslightshift));
@ -462,13 +462,14 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
" }}\n"
" }}\n"
" break;\n\n");
out.Write(" case {}u: // XF_TEXGEN_COLOR_STRGBC0\n", XF_TEXGEN_COLOR_STRGBC0);
out.Write(" case {:s}:\n", TexGenType::Color0);
out.Write(" output_tex.xyz = float3(o.colors_0.x, o.colors_0.y, 1.0);\n"
" break;\n\n");
out.Write(" case {}u: // XF_TEXGEN_COLOR_STRGBC1\n", XF_TEXGEN_COLOR_STRGBC1);
out.Write(" case {:s}:\n", TexGenType::Color1);
out.Write(" output_tex.xyz = float3(o.colors_1.x, o.colors_1.y, 1.0);\n"
" break;\n\n");
out.Write(" default: // Also XF_TEXGEN_REGULAR\n"
out.Write(" case {:s}:\n", TexGenType::Regular);
out.Write(" default:\n"
" {{\n");
out.Write(" if ((components & ({}u /* VB_HAS_TEXMTXIDX0 */ << texgen)) != 0u) {{\n",
VB_HAS_TEXMTXIDX0);
@ -480,8 +481,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" case {}u: tmp = int(rawtex{}.z); break;\n", i, i);
out.Write(" }}\n"
"\n");
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
XF_TEXPROJ_STQ);
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TRANSFORMMATRICES "[tmp]),\n"
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 1]),\n"
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 2]));\n"
@ -491,8 +492,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
" 1.0);\n"
" }}\n"
" }} else {{\n");
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
XF_TEXPROJ_STQ);
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TEXMATRICES "[3u * texgen]),\n"
" dot(coord, " I_TEXMATRICES "[3u * texgen + 1u]),\n"
" dot(coord, " I_TEXMATRICES "[3u * texgen + 2u]));\n"
@ -526,8 +527,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
// When q is 0, the GameCube appears to have a special case
// This can be seen in devkitPro's neheGX Lesson08 example for Wii
// Makes differences in Rogue Squadron 3 (Hoth sky) and The Last Story (shadow culling)
out.Write(" if (texgentype == {}u && output_tex.z == 0.0) // XF_TEXGEN_REGULAR\n",
XF_TEXGEN_REGULAR);
out.Write(" if (texgentype == {:s} && output_tex.z == 0.0)\n", TexGenType::Regular);
out.Write(
" output_tex.xy = clamp(output_tex.xy / 2.0f, float2(-1.0f,-1.0f), float2(1.0f,1.0f));\n"
"\n");

View File

@ -408,10 +408,10 @@ void VertexManagerBase::Flush()
for (u32 i = 0; i < xfmem.numTexGen.numTexGens; ++i)
{
TexMtxInfo tinfo = xfmem.texMtxInfo[i];
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
if (tinfo.texgentype != TexGenType::EmbossMap)
tinfo.hex &= 0x7ff;
if (tinfo.texgentype != XF_TEXGEN_REGULAR)
tinfo.projection = 0;
if (tinfo.texgentype != TexGenType::Regular)
tinfo.projection = TexSize::ST;
PRIM_LOG("txgen{}: proj={}, input={}, gentype={}, srcrow={}, embsrc={}, emblght={}, "
"postmtx={}, postnorm={}",
@ -430,7 +430,7 @@ void VertexManagerBase::Flush()
// Track some stats used elsewhere by the anamorphic widescreen heuristic.
if (!SConfig::GetInstance().bWii)
{
const bool is_perspective = xfmem.projection.type == GX_PERSPECTIVE;
const bool is_perspective = xfmem.projection.type == ProjectionType::Perspective;
auto& counts =
is_perspective ? m_flush_statistics.perspective : m_flush_statistics.orthographic;

View File

@ -39,7 +39,7 @@ VertexShaderUid GetVertexShaderUid()
// first transformation
switch (texinfo.texgentype)
{
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
case TexGenType::EmbossMap: // calculate tex coords into bump map
if ((uid_data->components & (VB_HAS_NRM1 | VB_HAS_NRM2)) != 0)
{
// transform the light dir into tangent space
@ -51,18 +51,19 @@ VertexShaderUid GetVertexShaderUid()
texinfo.embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
}
break;
case XF_TEXGEN_COLOR_STRGBC0:
case XF_TEXGEN_COLOR_STRGBC1:
case TexGenType::Color0:
case TexGenType::Color1:
break;
case XF_TEXGEN_REGULAR:
case TexGenType::Regular:
default:
uid_data->texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
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 == XF_TEXGEN_REGULAR)
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == TexGenType::Regular)
{
auto& postInfo = uid_data->postMtxInfo[i];
postInfo.index = xfmem.postMtxInfo[i].index;
@ -297,49 +298,48 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
out.Write("coord = float4(0.0, 0.0, 1.0, 1.0);\n");
switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
case SourceRow::Geom:
out.Write("coord.xyz = rawpos.xyz;\n");
break;
case XF_SRCNORMAL_INROW:
case SourceRow::Normal:
if ((uid_data->components & VB_HAS_NRM0) != 0)
{
out.Write("coord.xyz = rawnorm0.xyz;\n");
}
break;
case XF_SRCCOLORS_INROW:
ASSERT(texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 ||
texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1);
case SourceRow::Colors:
ASSERT(texinfo.texgentype == TexGenType::Color0 || texinfo.texgentype == TexGenType::Color1);
break;
case XF_SRCBINORMAL_T_INROW:
case SourceRow::BinormalT:
if ((uid_data->components & VB_HAS_NRM1) != 0)
{
out.Write("coord.xyz = rawnorm1.xyz;\n");
}
break;
case XF_SRCBINORMAL_B_INROW:
case SourceRow::BinormalB:
if ((uid_data->components & VB_HAS_NRM2) != 0)
{
out.Write("coord.xyz = rawnorm2.xyz;\n");
}
break;
default:
ASSERT(texinfo.sourcerow <= XF_SRCTEX7_INROW);
if ((uid_data->components & (VB_HAS_UV0 << (texinfo.sourcerow - XF_SRCTEX0_INROW))) != 0)
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)
{
out.Write("coord = float4(rawtex{}.x, rawtex{}.y, 1.0, 1.0);\n",
texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW);
out.Write("coord = float4(rawtex{}.x, rawtex{}.y, 1.0, 1.0);\n", texnum, texnum);
}
break;
}
// Input form of AB11 sets z element to 1.0
if (texinfo.inputform == XF_TEXINPUT_AB11)
if (texinfo.inputform == TexInputForm::AB11)
out.Write("coord.z = 1.0;\n");
// first transformation
switch (texinfo.texgentype)
{
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
case TexGenType::EmbossMap: // calculate tex coords into bump map
if ((uid_data->components & (VB_HAS_NRM1 | VB_HAS_NRM2)) != 0)
{
@ -359,18 +359,18 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
break;
case XF_TEXGEN_COLOR_STRGBC0:
case TexGenType::Color0:
out.Write("o.tex{}.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i);
break;
case XF_TEXGEN_COLOR_STRGBC1:
case TexGenType::Color1:
out.Write("o.tex{}.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i);
break;
case XF_TEXGEN_REGULAR:
case TexGenType::Regular:
default:
if ((uid_data->components & (VB_HAS_TEXMTXIDX0 << i)) != 0)
{
out.Write("int tmp = int(rawtex{}.z);\n", i);
if (((uid_data->texMtxInfo_n_projection >> i) & 1) == XF_TEXPROJ_STQ)
if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
{
out.Write("o.tex{}.xyz = float3(dot(coord, " I_TRANSFORMMATRICES
"[tmp]), dot(coord, " I_TRANSFORMMATRICES
@ -386,7 +386,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
else
{
if (((uid_data->texMtxInfo_n_projection >> i) & 1) == XF_TEXPROJ_STQ)
if (static_cast<TexSize>((uid_data->texMtxInfo_n_projection >> i) & 1) == TexSize::STQ)
{
out.Write("o.tex{}.xyz = float3(dot(coord, " I_TEXMATRICES
"[{}]), dot(coord, " I_TEXMATRICES "[{}]), dot(coord, " I_TEXMATRICES
@ -404,7 +404,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
}
// CHECKME: does this only work for regular tex gen types?
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
if (uid_data->dualTexTrans_enabled && texinfo.texgentype == TexGenType::Regular)
{
auto& postInfo = uid_data->postMtxInfo[i];
@ -427,7 +427,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
// This can be seen in devkitPro's neheGX Lesson08 example for Wii
// Makes differences in Rogue Squadron 3 (Hoth sky) and The Last Story (shadow culling)
// TODO: check if this only affects XF_TEXGEN_REGULAR
if (texinfo.texgentype == XF_TEXGEN_REGULAR)
if (texinfo.texgentype == TexGenType::Regular)
{
out.Write(
"if(o.tex{0}.z == 0.0f)\n"

View File

@ -9,6 +9,9 @@
#include "VideoCommon/ShaderGenCommon.h"
enum class APIType;
enum class TexInputForm : u32;
enum class TexGenType : u32;
enum class SourceRow : u32;
// TODO should be reordered
enum : int
@ -47,9 +50,9 @@ struct vertex_shader_uid_data
struct
{
u32 inputform : 2;
u32 texgentype : 3;
u32 sourcerow : 5;
TexInputForm inputform : 2;
TexGenType texgentype : 3;
SourceRow sourcerow : 5;
u32 embosssourceshift : 3;
u32 embosslightshift : 3;
} texMtxInfo[8];

View File

@ -353,7 +353,7 @@ void VertexShaderManager::SetConstants()
switch (xfmem.projection.type)
{
case GX_PERSPECTIVE:
case ProjectionType::Perspective:
{
const Common::Vec2 fov =
g_freelook_camera.IsActive() ? g_freelook_camera.GetFieldOfView() : Common::Vec2{1, 1};
@ -382,7 +382,7 @@ void VertexShaderManager::SetConstants()
}
break;
case GX_ORTHOGRAPHIC:
case ProjectionType::Orthographic:
{
g_fProjectionMatrix[0] = rawProjection[0];
g_fProjectionMatrix[1] = 0.0f;
@ -419,7 +419,7 @@ void VertexShaderManager::SetConstants()
auto corrected_matrix = s_viewportCorrection * Common::Matrix44::FromArray(g_fProjectionMatrix);
if (g_freelook_camera.IsActive() && xfmem.projection.type == GX_PERSPECTIVE)
if (g_freelook_camera.IsActive() && xfmem.projection.type == ProjectionType::Perspective)
corrected_matrix *= g_freelook_camera.GetView();
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));

View File

@ -4,10 +4,14 @@
#pragma once
// X.h defines None to be 0, which causes problems with some of the enums
#undef None
#include <array>
#include "Common/BitField.h"
#include "Common/CommonTypes.h"
#include "Common/EnumFormatter.h"
#include "VideoCommon/CPMemory.h"
class DataReader;
@ -17,75 +21,164 @@ constexpr size_t NUM_XF_COLOR_CHANNELS = 2;
// Lighting
// Projection
enum : u32
enum class TexSize : u32
{
XF_TEXPROJ_ST = 0,
XF_TEXPROJ_STQ = 1
ST = 0,
STQ = 1
};
template <>
struct fmt::formatter<TexSize> : EnumFormatter<TexSize::STQ>
{
formatter() : EnumFormatter({"ST (2x4 matrix)", "STQ (3x4 matrix)"}) {}
};
// Input form
enum : u32
enum class TexInputForm : u32
{
XF_TEXINPUT_AB11 = 0,
XF_TEXINPUT_ABC1 = 1
AB11 = 0,
ABC1 = 1
};
template <>
struct fmt::formatter<TexInputForm> : EnumFormatter<TexInputForm::ABC1>
{
formatter() : EnumFormatter({"AB11", "ABC1"}) {}
};
enum class NormalCount : u32
{
None = 0,
Normals = 1,
NormalsBinormals = 2
};
template <>
struct fmt::formatter<NormalCount> : EnumFormatter<NormalCount::NormalsBinormals>
{
formatter() : EnumFormatter({"None", "Normals only", "Normals and binormals"}) {}
};
// Texture generation type
enum : u32
enum class TexGenType : u32
{
XF_TEXGEN_REGULAR = 0,
XF_TEXGEN_EMBOSS_MAP = 1, // Used when bump mapping
XF_TEXGEN_COLOR_STRGBC0 = 2,
XF_TEXGEN_COLOR_STRGBC1 = 3
Regular = 0,
EmbossMap = 1, // Used when bump mapping
Color0 = 2,
Color1 = 3
};
template <>
struct fmt::formatter<TexGenType> : EnumFormatter<TexGenType::Color1>
{
static constexpr array_type names = {
"Regular",
"Emboss map (used when bump mapping)",
"Color channel 0",
"Color channel 1",
};
formatter() : EnumFormatter(names) {}
};
// Source row
enum : u32
enum class SourceRow : u32
{
XF_SRCGEOM_INROW = 0, // Input is abc
XF_SRCNORMAL_INROW = 1, // Input is abc
XF_SRCCOLORS_INROW = 2,
XF_SRCBINORMAL_T_INROW = 3, // Input is abc
XF_SRCBINORMAL_B_INROW = 4, // Input is abc
XF_SRCTEX0_INROW = 5,
XF_SRCTEX1_INROW = 6,
XF_SRCTEX2_INROW = 7,
XF_SRCTEX3_INROW = 8,
XF_SRCTEX4_INROW = 9,
XF_SRCTEX5_INROW = 10,
XF_SRCTEX6_INROW = 11,
XF_SRCTEX7_INROW = 12
Geom = 0, // Input is abc
Normal = 1, // Input is abc
Colors = 2,
BinormalT = 3, // Input is abc
BinormalB = 4, // Input is abc
Tex0 = 5,
Tex1 = 6,
Tex2 = 7,
Tex3 = 8,
Tex4 = 9,
Tex5 = 10,
Tex6 = 11,
Tex7 = 12
};
template <>
struct fmt::formatter<SourceRow> : EnumFormatter<SourceRow::Tex7>
{
static constexpr array_type names = {
"Geometry (input is ABC1)",
"Normal (input is ABC1)",
"Colors",
"Binormal T (input is ABC1)",
"Binormal B (input is ABC1)",
"Tex 0",
"Tex 1",
"Tex 2",
"Tex 3",
"Tex 4",
"Tex 5",
"Tex 6",
"Tex 7",
};
formatter() : EnumFormatter(names) {}
};
// Control source
enum : u32
enum class MatSource : u32
{
GX_SRC_REG = 0,
GX_SRC_VTX = 1
MatColorRegister = 0,
Vertex = 1,
};
template <>
struct fmt::formatter<MatSource> : EnumFormatter<MatSource::Vertex>
{
formatter() : EnumFormatter({"Material color register", "Vertex color"}) {}
};
enum class AmbSource : u32
{
AmbColorRegister = 0,
Vertex = 1,
};
template <>
struct fmt::formatter<AmbSource> : EnumFormatter<AmbSource::Vertex>
{
formatter() : EnumFormatter({"Ambient color register", "Vertex color"}) {}
};
// Light diffuse attenuation function
enum : u32
enum class DiffuseFunc : u32
{
LIGHTDIF_NONE = 0,
LIGHTDIF_SIGN = 1,
LIGHTDIF_CLAMP = 2
None = 0,
Sign = 1,
Clamp = 2
};
template <>
struct fmt::formatter<DiffuseFunc> : EnumFormatter<DiffuseFunc::Clamp>
{
formatter() : EnumFormatter({"None", "Sign", "Clamp"}) {}
};
// Light attenuation function
enum : u32
enum class AttenuationFunc : u32
{
LIGHTATTN_NONE = 0, // No attenuation
LIGHTATTN_SPEC = 1, // Point light attenuation
LIGHTATTN_DIR = 2, // Directional light attenuation
LIGHTATTN_SPOT = 3 // Spot light attenuation
None = 0, // No attenuation
Spec = 1, // Point light attenuation
Dir = 2, // Directional light attenuation
Spot = 3 // Spot light attenuation
};
template <>
struct fmt::formatter<AttenuationFunc> : EnumFormatter<AttenuationFunc::Spot>
{
static constexpr array_type names = {
"No attenuation",
"Point light attenuation",
"Directional light attenuation",
"Spot light attenuation",
};
formatter() : EnumFormatter(names) {}
};
// Projection type
enum : u32
enum class ProjectionType : u32
{
GX_PERSPECTIVE = 0,
GX_ORTHOGRAPHIC = 1
Perspective = 0,
Orthographic = 1
};
template <>
struct fmt::formatter<ProjectionType> : EnumFormatter<ProjectionType::Orthographic>
{
formatter() : EnumFormatter({"Perspective", "Orthographic"}) {}
};
// Registers and register ranges
@ -137,12 +230,12 @@ enum
union LitChannel
{
BitField<0, 1, u32> matsource;
BitField<1, 1, u32> enablelighting;
BitField<0, 1, MatSource> matsource;
BitField<1, 1, bool, u32> enablelighting;
BitField<2, 4, u32> lightMask0_3;
BitField<6, 1, u32> ambsource;
BitField<7, 2, u32> diffusefunc; // LIGHTDIF_X
BitField<9, 2, u32> attnfunc; // LIGHTATTN_X
BitField<6, 1, AmbSource> ambsource;
BitField<7, 2, DiffuseFunc> diffusefunc;
BitField<9, 2, AttenuationFunc> attnfunc;
BitField<11, 4, u32> lightMask4_7;
u32 hex;
@ -152,26 +245,30 @@ union LitChannel
}
};
union ClipDisable
{
BitField<0, 1, bool, u32> disable_clipping_detection;
BitField<1, 1, bool, u32> disable_trivial_rejection;
BitField<2, 1, bool, u32> disable_cpoly_clipping_acceleration;
u32 hex;
};
union INVTXSPEC
{
struct
{
u32 numcolors : 2;
u32 numnormals : 2; // 0 - nothing, 1 - just normal, 2 - normals and binormals
u32 numtextures : 4;
u32 unused : 24;
};
BitField<0, 2, u32> numcolors;
BitField<2, 2, NormalCount> numnormals;
BitField<4, 4, u32> numtextures;
u32 hex;
};
union TexMtxInfo
{
BitField<0, 1, u32> unknown; //
BitField<1, 1, u32> projection; // XF_TEXPROJ_X
BitField<2, 1, u32> inputform; // XF_TEXINPUT_X
BitField<3, 1, u32> unknown2; //
BitField<4, 3, u32> texgentype; // XF_TEXGEN_X
BitField<7, 5, u32> sourcerow; // XF_SRCGEOM_X
BitField<0, 1, u32> unknown;
BitField<1, 1, TexSize> projection;
BitField<2, 1, TexInputForm> inputform;
BitField<3, 1, u32> unknown2;
BitField<4, 3, TexGenType> texgentype;
BitField<7, 5, SourceRow> sourcerow;
BitField<12, 3, u32> embosssourceshift; // what generated texcoord to use
BitField<15, 3, u32> embosslightshift; // light index that is used
u32 hex;
@ -179,36 +276,27 @@ union TexMtxInfo
union PostMtxInfo
{
BitField<0, 6, u32> index; // base row of dual transform matrix
BitField<6, 2, u32> unused; //
BitField<8, 1, u32> normalize; // normalize before send operation
BitField<0, 6, u32> index; // base row of dual transform matrix
BitField<6, 2, u32> unused; //
BitField<8, 1, bool, u32> normalize; // normalize before send operation
u32 hex;
};
union NumColorChannel
{
struct
{
u32 numColorChans : 2;
};
BitField<0, 2, u32> numColorChans;
u32 hex;
};
union NumTexGen
{
struct
{
u32 numTexGens : 4;
};
BitField<0, 4, u32> numTexGens;
u32 hex;
};
union DualTexInfo
{
struct
{
u32 enabled : 1;
};
BitField<0, 1, bool, u32> enabled;
u32 hex;
};
@ -250,7 +338,7 @@ struct Projection
using Raw = std::array<float, 6>;
Raw rawProjection;
u32 type; // only GX_PERSPECTIVE or GX_ORTHOGRAPHIC are allowed
ProjectionType type;
};
struct XFMemory
@ -267,7 +355,7 @@ struct XFMemory
u32 state0; // 0x1002
u32 state1; // 0x1003
u32 xfClock; // 0x1004
u32 clipDisable; // 0x1005
ClipDisable clipDisable; // 0x1005
u32 perf0; // 0x1006
u32 perf1; // 0x1007
INVTXSPEC hostinfo; // 0x1008 number of textures,colors,normals from vertex input

View File

@ -93,7 +93,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src)
break;
case XFMEM_DUALTEX:
if (xfmem.dualTexTrans.enabled != (newValue & 1))
if (xfmem.dualTexTrans.enabled != bool(newValue & 1))
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(-1);
break;