mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
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:
parent
953e09428f
commit
aab81d5aa0
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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];
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user