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

View File

@ -45,7 +45,7 @@ void GeometryShaderManager::SetConstants()
{ {
s_projection_changed = false; s_projection_changed = false;
if (xfmem.projection.type == GX_PERSPECTIVE) if (xfmem.projection.type == ProjectionType::Perspective)
{ {
float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) * float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) *
(g_ActiveConfig.iStereoDepthPercentage / 100.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 = alpha ? "a" : "rgb";
const char* swizzle_components = (alpha) ? "" : "3"; const char* swizzle_components = (alpha) ? "" : "3";
const u32 attnfunc = (uid_data.attnfunc >> (2 * litchan_index)) & 0x3; const auto attnfunc =
const u32 diffusefunc = (uid_data.diffusefunc >> (2 * litchan_index)) & 0x3; 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) switch (attnfunc)
{ {
case LIGHTATTN_NONE: case AttenuationFunc::None:
case LIGHTATTN_DIR: case AttenuationFunc::Dir:
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index)); object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
object.Write("attn = 1.0;\n"); object.Write("attn = 1.0;\n");
object.Write("if (length(ldir) == 0.0)\n\t ldir = _norm0;\n"); object.Write("if (length(ldir) == 0.0)\n\t ldir = _norm0;\n");
break; break;
case LIGHTATTN_SPEC: case AttenuationFunc::Spec:
object.Write("ldir = normalize(" LIGHT_POS ".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index)); 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 object.Write("attn = (dot(_norm0, ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR
".xyz)) : 0.0;\n", ".xyz)) : 0.0;\n",
LIGHT_DIR_PARAMS(index)); LIGHT_DIR_PARAMS(index));
object.Write("cosAttn = " LIGHT_COSATT ".xyz;\n", LIGHT_COSATT_PARAMS(index)); object.Write("cosAttn = " LIGHT_COSATT ".xyz;\n", LIGHT_COSATT_PARAMS(index));
object.Write("distAttn = {}(" LIGHT_DISTATT ".xyz);\n", 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, " object.Write("attn = max(0.0f, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
"float3(1.0, attn, attn*attn));\n"); "float3(1.0, attn, attn*attn));\n");
break; break;
case LIGHTATTN_SPOT: case AttenuationFunc::Spot:
object.Write("ldir = " LIGHT_POS ".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index)); object.Write("ldir = " LIGHT_POS ".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index));
object.Write("dist2 = dot(ldir, ldir);\n" object.Write("dist2 = dot(ldir, ldir);\n"
"dist = sqrt(dist2);\n" "dist = sqrt(dist2);\n"
@ -56,14 +59,14 @@ static void GenerateLightShader(ShaderCode& object, const LightingUidData& uid_d
switch (diffusefunc) switch (diffusefunc)
{ {
case LIGHTDIF_NONE: case DiffuseFunc::None:
object.Write("lacc.{} += int{}(round(attn * float{}(" LIGHT_COL ")));\n", swizzle, object.Write("lacc.{} += int{}(round(attn * float{}(" LIGHT_COL ")));\n", swizzle,
swizzle_components, swizzle_components, LIGHT_COL_PARAMS(index, swizzle)); swizzle_components, swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
break; break;
case LIGHTDIF_SIGN: case DiffuseFunc::Sign:
case LIGHTDIF_CLAMP: case DiffuseFunc::Clamp:
object.Write("lacc.{} += int{}(round(attn * {}dot(ldir, _norm0)) * float{}(" LIGHT_COL ")));\n", 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)); swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
break; break;
default: default:
@ -151,23 +154,23 @@ void GetLightingShaderUid(LightingUidData& uid_data)
{ {
for (u32 j = 0; j < NUM_XF_COLOR_CHANNELS; j++) for (u32 j = 0; j < NUM_XF_COLOR_CHANNELS; j++)
{ {
uid_data.matsource |= xfmem.color[j].matsource << j; uid_data.matsource |= static_cast<u32>(xfmem.color[j].matsource.Value()) << j;
uid_data.matsource |= xfmem.alpha[j].matsource << (j + 2); 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.color[j].enablelighting << j;
uid_data.enablelighting |= xfmem.alpha[j].enablelighting << (j + 2); uid_data.enablelighting |= xfmem.alpha[j].enablelighting << (j + 2);
if ((uid_data.enablelighting & (1 << j)) != 0) // Color lights if ((uid_data.enablelighting & (1 << j)) != 0) // Color lights
{ {
uid_data.ambsource |= xfmem.color[j].ambsource << j; uid_data.ambsource |= static_cast<u32>(xfmem.color[j].ambsource.Value()) << j;
uid_data.attnfunc |= xfmem.color[j].attnfunc << (2 * j); uid_data.attnfunc |= static_cast<u32>(xfmem.color[j].attnfunc.Value()) << (2 * j);
uid_data.diffusefunc |= xfmem.color[j].diffusefunc << (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); uid_data.light_mask |= xfmem.color[j].GetFullLightMask() << (8 * j);
} }
if ((uid_data.enablelighting & (1 << (j + 2))) != 0) // Alpha lights if ((uid_data.enablelighting & (1 << (j + 2))) != 0) // Alpha lights
{ {
uid_data.ambsource |= xfmem.alpha[j].ambsource << (j + 2); uid_data.ambsource |= static_cast<u32>(xfmem.alpha[j].ambsource.Value()) << (j + 2);
uid_data.attnfunc |= xfmem.alpha[j].attnfunc << (2 * (j + 2)); uid_data.attnfunc |= static_cast<u32>(xfmem.alpha[j].attnfunc.Value()) << (2 * (j + 2));
uid_data.diffusefunc |= xfmem.alpha[j].diffusefunc << (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)); 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) for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
{ {
// optional perspective divides // 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" " float dist, dist2, attn;\n"
"\n" "\n"
" switch (attnfunc) {{\n"); " switch (attnfunc) {{\n");
out.Write(" case {}u: // LIGNTATTN_NONE\n", LIGHTATTN_NONE); out.Write(" case {:s}:\n", AttenuationFunc::None);
out.Write(" case {}u: // LIGHTATTN_DIR\n", LIGHTATTN_DIR); out.Write(" case {:s}:\n", AttenuationFunc::Dir);
out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n" out.Write(" ldir = normalize(" I_LIGHTS "[index].pos.xyz - pos.xyz);\n"
" attn = 1.0;\n" " attn = 1.0;\n"
" if (length(ldir) == 0.0)\n" " if (length(ldir) == 0.0)\n"
" ldir = normal;\n" " ldir = normal;\n"
" break;\n\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" 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 " attn = (dot(normal, ldir) >= 0.0) ? max(0.0, dot(normal, " I_LIGHTS
"[index].dir.xyz)) : 0.0;\n" "[index].dir.xyz)) : 0.0;\n"
" cosAttn = " I_LIGHTS "[index].cosatt.xyz;\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" out.Write(" distAttn = " I_LIGHTS "[index].distatt.xyz;\n"
" else\n" " else\n"
" distAttn = normalize(" I_LIGHTS "[index].distatt.xyz);\n" " distAttn = normalize(" I_LIGHTS "[index].distatt.xyz);\n"
" attn = max(0.0, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, " " attn = max(0.0, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, "
"float3(1.0, attn, attn*attn));\n" "float3(1.0, attn, attn*attn));\n"
" break;\n\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" out.Write(" ldir = " I_LIGHTS "[index].pos.xyz - pos.xyz;\n"
" dist2 = dot(ldir, ldir);\n" " dist2 = dot(ldir, ldir);\n"
" dist = sqrt(dist2);\n" " dist = sqrt(dist2);\n"
@ -75,12 +75,12 @@ void WriteLightingFunction(ShaderCode& out)
" }}\n" " }}\n"
"\n" "\n"
" switch (diffusefunc) {{\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(" 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 out.Write(" return int4(round(attn * dot(ldir, normal) * float4(" I_LIGHTS
"[index].color)));\n\n"); "[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 out.Write(" return int4(round(attn * max(0.0, dot(ldir, normal)) * float4(" I_LIGHTS
"[index].color)));\n\n"); "[index].color)));\n\n");
out.Write(" default:\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" out.Write(" float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n"
" uint texMtxInfo = xfmem_texMtxInfo(texgen);\n"); " uint texMtxInfo = xfmem_texMtxInfo(texgen);\n");
out.Write(" switch ({}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().sourcerow)); 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(" coord.xyz = rawpos.xyz;\n");
out.Write(" break;\n\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( out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM0 */) != 0u) ? rawnorm0.xyz : coord.xyz;", " coord.xyz = ((components & {}u /* VB_HAS_NRM0 */) != 0u) ? rawnorm0.xyz : coord.xyz;",
VB_HAS_NRM0); VB_HAS_NRM0);
out.Write(" break;\n\n"); 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( out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM1 */) != 0u) ? rawnorm1.xyz : coord.xyz;", " coord.xyz = ((components & {}u /* VB_HAS_NRM1 */) != 0u) ? rawnorm1.xyz : coord.xyz;",
VB_HAS_NRM1); VB_HAS_NRM1);
out.Write(" break;\n\n"); 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( out.Write(
" coord.xyz = ((components & {}u /* VB_HAS_NRM2 */) != 0u) ? rawnorm2.xyz : coord.xyz;", " coord.xyz = ((components & {}u /* VB_HAS_NRM2 */) != 0u) ? rawnorm2.xyz : coord.xyz;",
VB_HAS_NRM2); VB_HAS_NRM2);
out.Write(" break;\n\n"); out.Write(" break;\n\n");
for (u32 i = 0; i < 8; i++) 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( out.Write(
" coord = ((components & {}u /* VB_HAS_UV{} */) != 0u) ? float4(rawtex{}.x, rawtex{}.y, " " coord = ((components & {}u /* VB_HAS_UV{} */) != 0u) ? float4(rawtex{}.x, rawtex{}.y, "
"1.0, 1.0) : coord;\n", "1.0, 1.0) : coord;\n",
@ -434,8 +434,8 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
"\n"); "\n");
out.Write(" // Input form of AB11 sets z element to 1.0\n"); out.Write(" // Input form of AB11 sets z element to 1.0\n");
out.Write(" if ({} == {}u) // inputform == XF_TEXINPUT_AB11\n", out.Write(" if ({} == {:s}) // inputform == AB11\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), XF_TEXINPUT_AB11); BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), TexInputForm::AB11);
out.Write(" coord.z = 1.0f;\n" out.Write(" coord.z = 1.0f;\n"
"\n"); "\n");
@ -444,7 +444,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" float3 output_tex;\n" out.Write(" float3 output_tex;\n"
" switch (texgentype)\n" " switch (texgentype)\n"
" {{\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(" {{\n");
out.Write(" uint light = {};\n", out.Write(" uint light = {};\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().embosslightshift)); BitfieldExtract("texMtxInfo", TexMtxInfo().embosslightshift));
@ -462,13 +462,14 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
" }}\n" " }}\n"
" }}\n" " }}\n"
" break;\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" out.Write(" output_tex.xyz = float3(o.colors_0.x, o.colors_0.y, 1.0);\n"
" break;\n\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" out.Write(" output_tex.xyz = float3(o.colors_1.x, o.colors_1.y, 1.0);\n"
" break;\n\n"); " break;\n\n");
out.Write(" default: // Also XF_TEXGEN_REGULAR\n" out.Write(" case {:s}:\n", TexGenType::Regular);
out.Write(" default:\n"
" {{\n"); " {{\n");
out.Write(" if ((components & ({}u /* VB_HAS_TEXMTXIDX0 */ << texgen)) != 0u) {{\n", out.Write(" if ((components & ({}u /* VB_HAS_TEXMTXIDX0 */ << texgen)) != 0u) {{\n",
VB_HAS_TEXMTXIDX0); 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(" case {}u: tmp = int(rawtex{}.z); break;\n", i, i);
out.Write(" }}\n" out.Write(" }}\n"
"\n"); "\n");
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection), out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
XF_TEXPROJ_STQ); TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TRANSFORMMATRICES "[tmp]),\n" out.Write(" output_tex.xyz = float3(dot(coord, " I_TRANSFORMMATRICES "[tmp]),\n"
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 1]),\n" " dot(coord, " I_TRANSFORMMATRICES "[tmp + 1]),\n"
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 2]));\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" " 1.0);\n"
" }}\n" " }}\n"
" }} else {{\n"); " }} else {{\n");
out.Write(" if ({} == {}u) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection), out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
XF_TEXPROJ_STQ); TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TEXMATRICES "[3u * texgen]),\n" 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 + 1u]),\n"
" dot(coord, " I_TEXMATRICES "[3u * texgen + 2u]));\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 // When q is 0, the GameCube appears to have a special case
// This can be seen in devkitPro's neheGX Lesson08 example for Wii // 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) // 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", out.Write(" if (texgentype == {:s} && output_tex.z == 0.0)\n", TexGenType::Regular);
XF_TEXGEN_REGULAR);
out.Write( out.Write(
" output_tex.xy = clamp(output_tex.xy / 2.0f, float2(-1.0f,-1.0f), float2(1.0f,1.0f));\n" " output_tex.xy = clamp(output_tex.xy / 2.0f, float2(-1.0f,-1.0f), float2(1.0f,1.0f));\n"
"\n"); "\n");

View File

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

View File

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

View File

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

View File

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

View File

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