Merge pull request #269 from magumagu/swbackend-xfregisters

SW backend: use VideoCommon XFRegisters struct.
This commit is contained in:
Tony Wasserka 2014-05-17 10:40:57 +02:00
commit 0fac17da33
25 changed files with 201 additions and 268 deletions

View File

@ -176,10 +176,10 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
code.Write("\n%s", LINE_GS_COMMON);
std::stringstream numTexCoordsStream;
numTexCoordsStream << xfregs.numTexGen.numTexGens;
numTexCoordsStream << xfmem.numTexGen.numTexGens;
INFO_LOG(VIDEO, "Compiling line geometry shader for components 0x%.08X (num texcoords %d)",
components, xfregs.numTexGen.numTexGens);
components, xfmem.numTexGen.numTexGens);
const std::string& numTexCoordsStr = numTexCoordsStream.str();
D3D_SHADER_MACRO macros[] = {

View File

@ -170,10 +170,10 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
code.Write("\n%s", POINT_GS_COMMON);
std::stringstream numTexCoordsStream;
numTexCoordsStream << xfregs.numTexGen.numTexGens;
numTexCoordsStream << xfmem.numTexGen.numTexGens;
INFO_LOG(VIDEO, "Compiling point geometry shader for components 0x%.08X (num texcoords %d)",
components, xfregs.numTexGen.numTexGens);
components, xfmem.numTexGen.numTexGens);
const std::string& numTexCoordsStr = numTexCoordsStream.str();
D3D_SHADER_MACRO macros[] = {

View File

@ -487,16 +487,16 @@ void Renderer::SetViewport()
// [5] = 16777215 * farz
// D3D crashes for zero viewports
if (xfregs.viewport.wd == 0 || xfregs.viewport.ht == 0)
if (xfmem.viewport.wd == 0 || xfmem.viewport.ht == 0)
return;
int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 2;
float X = Renderer::EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff);
float Y = Renderer::EFBToScaledYf(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff);
float Wd = Renderer::EFBToScaledXf(2.0f * xfregs.viewport.wd);
float Ht = Renderer::EFBToScaledYf(-2.0f * xfregs.viewport.ht);
float X = Renderer::EFBToScaledXf(xfmem.viewport.xOrig - xfmem.viewport.wd - scissorXOff);
float Y = Renderer::EFBToScaledYf(xfmem.viewport.yOrig + xfmem.viewport.ht - scissorYOff);
float Wd = Renderer::EFBToScaledXf(2.0f * xfmem.viewport.wd);
float Ht = Renderer::EFBToScaledYf(-2.0f * xfmem.viewport.ht);
if (Wd < 0.0f)
{
X += Wd;
@ -516,8 +516,8 @@ void Renderer::SetViewport()
// Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht,
0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
1.f); // xfregs.viewport.farZ / 16777216.0f;
0.f, // (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f;
1.f); // xfmem.viewport.farZ / 16777216.0f;
D3D::context->RSSetViewports(1, &vp);
}

View File

@ -151,8 +151,8 @@ void VertexManager::Draw(UINT stride)
{
float lineWidth = float(bpmem.lineptwidth.linesize) / 6.f;
float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff];
float vpWidth = 2.0f * xfregs.viewport.wd;
float vpHeight = -2.0f * xfregs.viewport.ht;
float vpWidth = 2.0f * xfmem.viewport.wd;
float vpHeight = -2.0f * xfmem.viewport.ht;
bool texOffsetEnable[8];
@ -175,8 +175,8 @@ void VertexManager::Draw(UINT stride)
{
float pointSize = float(bpmem.lineptwidth.pointsize) / 6.f;
float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff];
float vpWidth = 2.0f * xfregs.viewport.wd;
float vpHeight = -2.0f * xfregs.viewport.ht;
float vpWidth = 2.0f * xfmem.viewport.wd;
float vpHeight = -2.0f * xfmem.viewport.ht;
bool texOffsetEnable[8];

View File

@ -1160,12 +1160,12 @@ void Renderer::SetViewport()
int scissorYOff = bpmem.scissorOffset.y * 2;
// TODO: ceil, floor or just cast to int?
float X = EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - (float)scissorXOff);
float Y = EFBToScaledYf((float)EFB_HEIGHT - xfregs.viewport.yOrig + xfregs.viewport.ht + (float)scissorYOff);
float Width = EFBToScaledXf(2.0f * xfregs.viewport.wd);
float Height = EFBToScaledYf(-2.0f * xfregs.viewport.ht);
float GLNear = (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
float GLFar = xfregs.viewport.farZ / 16777216.0f;
float X = EFBToScaledXf(xfmem.viewport.xOrig - xfmem.viewport.wd - (float)scissorXOff);
float Y = EFBToScaledYf((float)EFB_HEIGHT - xfmem.viewport.yOrig + xfmem.viewport.ht + (float)scissorYOff);
float Width = EFBToScaledXf(2.0f * xfmem.viewport.wd);
float Height = EFBToScaledYf(-2.0f * xfmem.viewport.ht);
float GLNear = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f;
float GLFar = xfmem.viewport.farZ / 16777216.0f;
if (Width < 0)
{
X += Width;
@ -1807,7 +1807,7 @@ void Renderer::SetDitherMode()
void Renderer::SetLineWidth()
{
float fratio = xfregs.viewport.wd != 0 ?
float fratio = xfmem.viewport.wd != 0 ?
((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f;
if (bpmem.lineptwidth.linesize > 0)
// scale by ratio of widths

View File

@ -67,8 +67,8 @@ namespace Clipper
void SetViewOffset()
{
m_ViewOffset[0] = swxfregs.viewport.xOrig - 342;
m_ViewOffset[1] = swxfregs.viewport.yOrig - 342;
m_ViewOffset[0] = xfmem.viewport.xOrig - 342;
m_ViewOffset[1] = xfmem.viewport.yOrig - 342;
}
@ -430,9 +430,9 @@ namespace Clipper
Vec3 &screen = vertex->screenPosition;
float wInverse = 1.0f/projected.w;
screen.x = projected.x * wInverse * swxfregs.viewport.wd + m_ViewOffset[0];
screen.y = projected.y * wInverse * swxfregs.viewport.ht + m_ViewOffset[1];
screen.z = projected.z * wInverse * swxfregs.viewport.zRange + swxfregs.viewport.farZ;
screen.x = projected.x * wInverse * xfmem.viewport.wd + m_ViewOffset[0];
screen.y = projected.y * wInverse * xfmem.viewport.ht + m_ViewOffset[1];
screen.z = projected.z * wInverse * xfmem.viewport.zRange + xfmem.viewport.farZ;
}
}

View File

@ -270,7 +270,7 @@ void BuildBlock(s32 blockX, s32 blockY)
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; i++)
{
float projection = invW;
if (swxfregs.texMtxInfo[i].projection)
if (xfmem.texMtxInfo[i].projection)
{
float q = TexSlopes[i][2].GetValue(dx, dy) * invW;
if (q != 0.0f)

View File

@ -95,15 +95,15 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
// Reset vertex
// matrix index from xf regs or cp memory?
if (swxfregs.MatrixIndexA.PosNormalMtxIdx != MatrixIndexA.PosNormalMtxIdx ||
swxfregs.MatrixIndexA.Tex0MtxIdx != MatrixIndexA.Tex0MtxIdx ||
swxfregs.MatrixIndexA.Tex1MtxIdx != MatrixIndexA.Tex1MtxIdx ||
swxfregs.MatrixIndexA.Tex2MtxIdx != MatrixIndexA.Tex2MtxIdx ||
swxfregs.MatrixIndexA.Tex3MtxIdx != MatrixIndexA.Tex3MtxIdx ||
swxfregs.MatrixIndexB.Tex4MtxIdx != MatrixIndexB.Tex4MtxIdx ||
swxfregs.MatrixIndexB.Tex5MtxIdx != MatrixIndexB.Tex5MtxIdx ||
swxfregs.MatrixIndexB.Tex6MtxIdx != MatrixIndexB.Tex6MtxIdx ||
swxfregs.MatrixIndexB.Tex7MtxIdx != MatrixIndexB.Tex7MtxIdx)
if (xfmem.MatrixIndexA.PosNormalMtxIdx != MatrixIndexA.PosNormalMtxIdx ||
xfmem.MatrixIndexA.Tex0MtxIdx != MatrixIndexA.Tex0MtxIdx ||
xfmem.MatrixIndexA.Tex1MtxIdx != MatrixIndexA.Tex1MtxIdx ||
xfmem.MatrixIndexA.Tex2MtxIdx != MatrixIndexA.Tex2MtxIdx ||
xfmem.MatrixIndexA.Tex3MtxIdx != MatrixIndexA.Tex3MtxIdx ||
xfmem.MatrixIndexB.Tex4MtxIdx != MatrixIndexB.Tex4MtxIdx ||
xfmem.MatrixIndexB.Tex5MtxIdx != MatrixIndexB.Tex5MtxIdx ||
xfmem.MatrixIndexB.Tex6MtxIdx != MatrixIndexB.Tex6MtxIdx ||
xfmem.MatrixIndexB.Tex7MtxIdx != MatrixIndexB.Tex7MtxIdx)
{
WARN_LOG(VIDEO, "Matrix indices don't match");
@ -114,15 +114,15 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
}
#if(1)
m_Vertex.posMtx = swxfregs.MatrixIndexA.PosNormalMtxIdx;
m_Vertex.texMtx[0] = swxfregs.MatrixIndexA.Tex0MtxIdx;
m_Vertex.texMtx[1] = swxfregs.MatrixIndexA.Tex1MtxIdx;
m_Vertex.texMtx[2] = swxfregs.MatrixIndexA.Tex2MtxIdx;
m_Vertex.texMtx[3] = swxfregs.MatrixIndexA.Tex3MtxIdx;
m_Vertex.texMtx[4] = swxfregs.MatrixIndexB.Tex4MtxIdx;
m_Vertex.texMtx[5] = swxfregs.MatrixIndexB.Tex5MtxIdx;
m_Vertex.texMtx[6] = swxfregs.MatrixIndexB.Tex6MtxIdx;
m_Vertex.texMtx[7] = swxfregs.MatrixIndexB.Tex7MtxIdx;
m_Vertex.posMtx = xfmem.MatrixIndexA.PosNormalMtxIdx;
m_Vertex.texMtx[0] = xfmem.MatrixIndexA.Tex0MtxIdx;
m_Vertex.texMtx[1] = xfmem.MatrixIndexA.Tex1MtxIdx;
m_Vertex.texMtx[2] = xfmem.MatrixIndexA.Tex2MtxIdx;
m_Vertex.texMtx[3] = xfmem.MatrixIndexA.Tex3MtxIdx;
m_Vertex.texMtx[4] = xfmem.MatrixIndexB.Tex4MtxIdx;
m_Vertex.texMtx[5] = xfmem.MatrixIndexB.Tex5MtxIdx;
m_Vertex.texMtx[6] = xfmem.MatrixIndexB.Tex6MtxIdx;
m_Vertex.texMtx[7] = xfmem.MatrixIndexB.Tex7MtxIdx;
#else
m_Vertex.posMtx = MatrixIndexA.PosNormalMtxIdx;
m_Vertex.texMtx[0] = MatrixIndexA.Tex0MtxIdx;
@ -242,7 +242,7 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_TexGenSpecialCase =
((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0
(g_VtxDesc.Tex0Coord != NOT_PRESENT) &&
(swxfregs.texMtxInfo[0].projection == XF_TEXPROJ_ST);
(xfmem.texMtxInfo[0].projection == XF_TEXPROJ_ST);
m_SetupUnit->Init(primitiveType);
}

View File

@ -115,7 +115,7 @@ void VideoSoftware::DoState(PointerWrap& p)
EfbInterface::DoState(p);
OpcodeDecoder::DoState(p);
Clipper::DoState(p);
p.Do(swxfregs);
p.Do(xfmem);
p.Do(bpmem);
p.DoPOD(swstats);

View File

@ -699,7 +699,7 @@ void Tev::Draw()
// - scaling of the "k" coefficient isn't clear either.
// First, calculate the offset from the viewport center (normalized to 0..1)
float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)swxfregs.viewport.wd;
float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)xfmem.viewport.wd;
// Based on that, choose the index such that points which are far away from the z-axis use the 10th "k" value and such that central points use the first value.
float floatindex = 9.f - std::abs(offset) * 9.f;

View File

@ -70,22 +70,22 @@ void MultipleVec3Ortho(const Vec3 &vec, const float *proj, Vec4 &result)
void TransformPosition(const InputVertexData *src, OutputVertexData *dst)
{
const float* mat = (const float*)&swxfregs.posMatrices[src->posMtx * 4];
const float* mat = (const float*)&xfmem.posMatrices[src->posMtx * 4];
MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
if (swxfregs.projection.type == GX_PERSPECTIVE)
if (xfmem.projection.type == GX_PERSPECTIVE)
{
MultipleVec3Perspective(dst->mvPosition, swxfregs.projection.rawProjection, dst->projectedPosition);
MultipleVec3Perspective(dst->mvPosition, xfmem.projection.rawProjection, dst->projectedPosition);
}
else
{
MultipleVec3Ortho(dst->mvPosition, swxfregs.projection.rawProjection, dst->projectedPosition);
MultipleVec3Ortho(dst->mvPosition, xfmem.projection.rawProjection, dst->projectedPosition);
}
}
void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst)
{
const float* mat = (const float*)&swxfregs.normalMatrices[(src->posMtx & 31) * 3];
const float* mat = (const float*)&xfmem.normalMatrices[(src->posMtx & 31) * 3];
if (nbt)
{
@ -124,7 +124,7 @@ void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool spec
break;
}
const float *mat = (const float*)&swxfregs.posMatrices[srcVertex->texMtx[coordNum] * 4];
const float *mat = (const float*)&xfmem.posMatrices[srcVertex->texMtx[coordNum] * 4];
Vec3 *dst = &dstVertex->texCoords[coordNum];
if (texinfo.projection == XF_TEXPROJ_ST)
@ -144,13 +144,13 @@ void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool spec
MultiplyVec3Mat34(*src, mat, *dst);
}
if (swxfregs.dualTexTrans)
if (xfmem.dualTexTrans.enabled)
{
Vec3 tempCoord;
// normalize
const PostMtxInfo &postInfo = swxfregs.postMtxInfo[coordNum];
const float *postMat = (const float*)&swxfregs.postMatrices[postInfo.index * 4];
const PostMtxInfo &postInfo = xfmem.postMtxInfo[coordNum];
const float *postMat = (const float*)&xfmem.postMatrices[postInfo.index * 4];
if (specialCase)
{
@ -212,7 +212,7 @@ inline float SafeDivide(float n, float d)
void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol)
{
const LightPointer *light = (const LightPointer*)&swxfregs.lights[0x10*lightNum];
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum];
if (!(chan.attnfunc & 1))
{
@ -297,7 +297,7 @@ void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChann
void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
{
const LightPointer *light = (const LightPointer*)&swxfregs.lights[0x10*lightNum];
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum];
if (!(chan.attnfunc & 1))
{
@ -376,18 +376,18 @@ void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChann
void TransformColor(const InputVertexData *src, OutputVertexData *dst)
{
for (u32 chan = 0; chan < swxfregs.nNumChans; chan++)
for (u32 chan = 0; chan < xfmem.numChan.numColorChans; chan++)
{
// abgr
u8 matcolor[4];
u8 chancolor[4];
// color
LitChannel &colorchan = swxfregs.color[chan];
LitChannel &colorchan = xfmem.color[chan];
if (colorchan.matsource)
*(u32*)matcolor = *(u32*)src->color[chan]; // vertex
else
*(u32*)matcolor = swxfregs.matColor[chan];
*(u32*)matcolor = xfmem.matColor[chan];
if (colorchan.enablelighting)
{
@ -401,7 +401,7 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst)
}
else
{
u8 *ambColor = (u8*)&swxfregs.ambColor[chan];
u8 *ambColor = (u8*)&xfmem.ambColor[chan];
lightCol.x = ambColor[1];
lightCol.y = ambColor[2];
lightCol.z = ambColor[3];
@ -425,19 +425,19 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst)
}
// alpha
LitChannel &alphachan = swxfregs.alpha[chan];
LitChannel &alphachan = xfmem.alpha[chan];
if (alphachan.matsource)
matcolor[0] = src->color[chan][0]; // vertex
else
matcolor[0] = swxfregs.matColor[chan] & 0xff;
matcolor[0] = xfmem.matColor[chan] & 0xff;
if (swxfregs.alpha[chan].enablelighting)
if (xfmem.alpha[chan].enablelighting)
{
float lightCol;
if (alphachan.ambsource)
lightCol = src->color[chan][0]; // vertex
else
lightCol = (float)(swxfregs.ambColor[chan] & 0xff);
lightCol = (float)(xfmem.ambColor[chan] & 0xff);
u8 mask = alphachan.GetFullLightMask();
for (int i = 0; i < 8; ++i)
@ -460,9 +460,9 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst)
void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase)
{
for (u32 coordNum = 0; coordNum < swxfregs.numTexGens; coordNum++)
for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
{
const TexMtxInfo &texinfo = swxfregs.texMtxInfo[coordNum];
const TexMtxInfo &texinfo = xfmem.texMtxInfo[coordNum];
switch (texinfo.texgentype)
{
@ -471,7 +471,7 @@ void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool s
break;
case XF_TEXGEN_EMBOSS_MAP:
{
const LightPointer *light = (const LightPointer*)&swxfregs.lights[0x10*texinfo.embosslightshift];
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*texinfo.embosslightshift];
Vec3 ldir = (light->pos - dst->mvPosition).normalized();
float d1 = ldir * dst->normal[1];
@ -501,7 +501,7 @@ void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool s
}
}
for (u32 coordNum = 0; coordNum < swxfregs.numTexGens; coordNum++)
for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
{
dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);

View File

@ -8,11 +8,9 @@
#include "VideoBackends/Software/XFMemLoader.h"
#include "VideoCommon/VideoCommon.h"
SWXFRegisters swxfregs;
void InitXFMemory()
{
memset(&swxfregs, 0, sizeof(swxfregs));
memset(&xfmem, 0, sizeof(xfmem));
}
void XFWritten(u32 transferSize, u32 baseAddress)
@ -25,7 +23,7 @@ void XFWritten(u32 transferSize, u32 baseAddress)
// fix lights so invalid values don't trash the lighting computations
if (baseAddress <= 0x067f && topAddress >= 0x0604)
{
u32* x = swxfregs.lights;
u32* x = xfmem.lights;
// go through all lights
for (int light = 0; light < 8; light++)
@ -49,22 +47,21 @@ void XFWritten(u32 transferSize, u32 baseAddress)
void SWLoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
{
u32 size = transferSize;
// do not allow writes past registers
if (baseAddress + transferSize > 0x1058)
{
INFO_LOG(VIDEO, "xf load exceeds address space: %x %d bytes\n", baseAddress, transferSize);
INFO_LOG(VIDEO, "XF load exceeds address space: %x %d bytes", baseAddress, transferSize);
if (baseAddress >= 0x1058)
size = 0;
transferSize = 0;
else
size = 0x1058 - baseAddress;
transferSize = 0x1058 - baseAddress;
}
if (size > 0)
// write to XF regs
if (transferSize > 0)
{
memcpy_gc( &((u32*)&swxfregs)[baseAddress], pData, size * 4);
memcpy_gc((u32*)(&xfmem) + baseAddress, pData, transferSize * 4);
XFWritten(transferSize, baseAddress);
}
}

View File

@ -8,81 +8,6 @@
#include "VideoCommon/XFMemory.h"
union TXFMatrixIndexA
{
struct
{
u32 PosNormalMtxIdx : 6;
u32 Tex0MtxIdx : 6;
u32 Tex1MtxIdx : 6;
u32 Tex2MtxIdx : 6;
u32 Tex3MtxIdx : 6;
};
struct
{
u32 Hex : 30;
u32 unused : 2;
};
};
union TXFMatrixIndexB
{
struct
{
u32 Tex4MtxIdx : 6;
u32 Tex5MtxIdx : 6;
u32 Tex6MtxIdx : 6;
u32 Tex7MtxIdx : 6;
};
struct
{
u32 Hex : 24;
u32 unused : 8;
};
};
struct SWXFRegisters
{
u32 posMatrices[256]; // 0x0000 - 0x00ff
u32 unk0[768]; // 0x0100 - 0x03ff
u32 normalMatrices[96]; // 0x0400 - 0x045f
u32 unk1[160]; // 0x0460 - 0x04ff
u32 postMatrices[256]; // 0x0500 - 0x05ff
u32 lights[128]; // 0x0600 - 0x067f
u32 unk2[2432]; // 0x0680 - 0x0fff
u32 error; // 0x1000
u32 diag; // 0x1001
u32 state0; // 0x1002
u32 state1; // 0x1003
u32 xfClock; // 0x1004
u32 clipDisable; // 0x1005
u32 perf0; // 0x1006
u32 perf1; // 0x1007
INVTXSPEC hostinfo; // 0x1008 number of textures,colors,normals from vertex input
u32 nNumChans; // 0x1009
u32 ambColor[2]; // 0x100a, 0x100b
u32 matColor[2]; // 0x100c, 0x100d
LitChannel color[2]; // 0x100e, 0x100f
LitChannel alpha[2]; // 0x1010, 0x1011
u32 dualTexTrans; // 0x1012
u32 unk3; // 0x1013
u32 unk4; // 0x1014
u32 unk5; // 0x1015
u32 unk6; // 0x1016
u32 unk7; // 0x1017
TXFMatrixIndexA MatrixIndexA; // 0x1018
TXFMatrixIndexB MatrixIndexB; // 0x1019
Viewport viewport; // 0x101a - 0x101f
Projection projection; // 0x1020 - 0x1026
u32 unk8[24]; // 0x1027 - 0x103e
u32 numTexGens; // 0x103f
TexMtxInfo texMtxInfo[8]; // 0x1040 - 0x1047
u32 unk9[8]; // 0x1048 - 0x104f
PostMtxInfo postMtxInfo[8]; // 0x1050 - 0x1057
};
extern SWXFRegisters swxfregs;
void InitXFMemory();
void XFWritten(u32 transferSize, u32 baseAddress);

View File

@ -41,7 +41,7 @@ struct LightingUidData
template<class T>
static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsColName, const char* lightsName, int coloralpha)
{
const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index];
const LitChannel& chan = (litchan_index > 1) ? xfmem.alpha[litchan_index-2] : xfmem.color[litchan_index];
const char* swizzle = (coloralpha == 1) ? "xyz" : (coloralpha == 2) ? "w" : "xyzw";
const char* swizzle_components = (coloralpha == 1) ? "3" : (coloralpha == 2) ? "" : "4";
@ -117,14 +117,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
template<class T>
static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsColName, const char* lightsName, const char* inColorName, const char* dest)
{
for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++)
for (unsigned int j = 0; j < xfmem.numChan.numColorChans; j++)
{
const LitChannel& color = xfregs.color[j];
const LitChannel& alpha = xfregs.alpha[j];
const LitChannel& color = xfmem.color[j];
const LitChannel& alpha = xfmem.alpha[j];
object.Write("{\n");
uid_data.matsource |= xfregs.color[j].matsource << j;
uid_data.matsource |= xfmem.color[j].matsource << j;
if (color.matsource) // from vertex
{
if (components & (VB_HAS_COL0 << j))
@ -139,10 +139,10 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
object.Write("int4 mat = %s[%d];\n", materialsName, j+2);
}
uid_data.enablelighting |= xfregs.color[j].enablelighting << j;
uid_data.enablelighting |= xfmem.color[j].enablelighting << j;
if (color.enablelighting)
{
uid_data.ambsource |= xfregs.color[j].ambsource << j;
uid_data.ambsource |= xfmem.color[j].ambsource << j;
if (color.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )
@ -166,7 +166,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
}
// check if alpha is different
uid_data.matsource |= xfregs.alpha[j].matsource << (j+2);
uid_data.matsource |= xfmem.alpha[j].matsource << (j+2);
if (alpha.matsource != color.matsource)
{
if (alpha.matsource) // from vertex
@ -183,10 +183,10 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
}
}
uid_data.enablelighting |= xfregs.alpha[j].enablelighting << (j+2);
uid_data.enablelighting |= xfmem.alpha[j].enablelighting << (j+2);
if (alpha.enablelighting)
{
uid_data.ambsource |= xfregs.alpha[j].ambsource << (j+2);
uid_data.ambsource |= xfmem.alpha[j].ambsource << (j+2);
if (alpha.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )

View File

@ -294,7 +294,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
// compute window position if needed because binding semantic WPOS is not widely supported
// Let's set up attributes
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
{
out.Write("centroid in float3 uv%d;\n", i);
}
@ -370,8 +370,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
{
out.Write("\tint2 fixpoint_uv%d = iround(", i);
// optional perspective divides
uid_data.texMtxInfo_n_projection |= xfregs.texMtxInfo[i].projection << i;
if (xfregs.texMtxInfo[i].projection == XF_TEXPROJ_STQ)
uid_data.texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
if (xfmem.texMtxInfo[i].projection == XF_TEXPROJ_STQ)
{
out.Write("(uv%d.z == 0.0 ? uv%d.xy : uv%d.xy / uv%d.z)", i, i, i, i);
}

View File

@ -77,7 +77,7 @@ void PixelShaderManager::SetConstants()
//bpmem.fogRange.Base.Center : center of the viewport in x axis. observation: bpmem.fogRange.Base.Center = realcenter + 342;
int center = ((u32)bpmem.fogRange.Base.Center) - 342;
// normalize center to make calculations easy
float ScreenSpaceCenter = center / (2.0f * xfregs.viewport.wd);
float ScreenSpaceCenter = center / (2.0f * xfmem.viewport.wd);
ScreenSpaceCenter = (ScreenSpaceCenter * 2.0f) - 1.0f;
//bpmem.fogRange.K seems to be a table of precalculated coefficients for the adjust factor
//observations: bpmem.fogRange.K[0].LO appears to be the lowest value and bpmem.fogRange.K[4].HI the largest
@ -86,7 +86,7 @@ void PixelShaderManager::SetConstants()
// so to simplify I use the hi coefficient as K in the shader taking 256 as the scale
// TODO: Shouldn't this be EFBToScaledXf?
constants.fogf[0][0] = ScreenSpaceCenter;
constants.fogf[0][1] = (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd));
constants.fogf[0][1] = (float)Renderer::EFBToScaledX((int)(2.0f * xfmem.viewport.wd));
constants.fogf[0][2] = bpmem.fogRange.K[4].HI / 256.0f;
}
else
@ -108,7 +108,7 @@ void PixelShaderManager::SetConstants()
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
int istart = nLightsChanged[0] / 0x10;
int iend = (nLightsChanged[1] + 15) / 0x10;
const float* xfmemptr = (const float*)&xfmem[0x10 * istart + XFMEM_LIGHTS];
const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart];
for (int i = istart; i < iend; ++i)
{
@ -141,8 +141,8 @@ void PixelShaderManager::SetConstants()
if (s_bViewPortChanged)
{
constants.zbias[1][0] = xfregs.viewport.farZ;
constants.zbias[1][1] = xfregs.viewport.zRange;
constants.zbias[1][0] = xfmem.viewport.farZ;
constants.zbias[1][1] = xfmem.viewport.zRange;
dirty = true;
s_bViewPortChanged = false;
}

View File

@ -502,15 +502,18 @@ void Renderer::CheckFifoRecording()
void Renderer::RecordVideoMemory()
{
u32 *bpMem = (u32*)&bpmem;
u32 cpMem[256];
u32 *xfMem = (u32*)xfmem;
u32 *xfRegs = (u32*)&xfregs;
u32 *bpmem_ptr = (u32*)&bpmem;
u32 cpmem[256];
// The FIFO recording format splits XF memory into xfmem and xfregs; follow
// that split here.
u32 *xfmem_ptr = (u32*)&xfmem;
u32 *xfregs_ptr = (u32*)&xfmem + FifoDataFile::XF_MEM_SIZE;
u32 xfregs_size = sizeof(XFMemory) / 4 - FifoDataFile::XF_MEM_SIZE;
memset(cpMem, 0, 256 * 4);
FillCPMemoryArray(cpMem);
memset(cpmem, 0, 256 * 4);
FillCPMemoryArray(cpmem);
FifoRecorder::GetInstance().SetVideoMemory(bpMem, cpMem, xfMem, xfRegs, sizeof(XFRegisters) / 4);
FifoRecorder::GetInstance().SetVideoMemory(bpmem_ptr, cpmem, xfmem_ptr, xfregs_ptr, xfregs_size);
}
void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc, float Gamma)

View File

@ -217,8 +217,8 @@ void LOADERDECL UpdateBoundingBox()
// We need to get the raw projection values for the bounding box calculation
// to work properly. That means, no projection hacks!
const float * const orig_point = s_bbox_vertex_buffer;
const float * const world_matrix = (float*)xfmem + s_curposmtx * 4;
const float * const proj_matrix = xfregs.projection.rawProjection;
const float * const world_matrix = (float*)xfmem.posMatrices + s_curposmtx * 4;
const float * const proj_matrix = xfmem.projection.rawProjection;
// Transform by world matrix
// Only calculate what we need, discard the rest
@ -226,7 +226,7 @@ void LOADERDECL UpdateBoundingBox()
transformed[1] = orig_point[0] * world_matrix[4] + orig_point[1] * world_matrix[5] + orig_point[2] * world_matrix[6] + world_matrix[7];
// Transform by projection matrix
switch (xfregs.projection.type)
switch (xfmem.projection.type)
{
// Perspective projection, we must divide by w
case GX_PERSPECTIVE:
@ -246,13 +246,13 @@ void LOADERDECL UpdateBoundingBox()
break;
default:
ERROR_LOG(VIDEO, "Unknown projection type: %d", xfregs.projection.type);
ERROR_LOG(VIDEO, "Unknown projection type: %d", xfmem.projection.type);
screenPoint[0] = screenPoint[1] = screenPoint[2] = 1;
}
// Convert to screen space and add the point to the list - round like the real hardware
s_bbox_points[s_bbox_currPoint].x = (((s32) (0.5f + (16.0f * (screenPoint[0] * xfregs.viewport.wd + (xfregs.viewport.xOrig - 342.0f))))) + 3) >> 4;
s_bbox_points[s_bbox_currPoint].y = (((s32) (0.5f + (16.0f * (screenPoint[1] * xfregs.viewport.ht + (xfregs.viewport.yOrig - 342.0f))))) + 3) >> 4;
s_bbox_points[s_bbox_currPoint].x = (((s32) (0.5f + (16.0f * (screenPoint[0] * xfmem.viewport.wd + (xfmem.viewport.xOrig - 342.0f))))) + 3) >> 4;
s_bbox_points[s_bbox_currPoint].y = (((s32) (0.5f + (16.0f * (screenPoint[1] * xfmem.viewport.ht + (xfmem.viewport.yOrig - 342.0f))))) + 3) >> 4;
s_bbox_points[s_bbox_currPoint].z = screenPoint[2];
// Update point list for primitive

View File

@ -150,27 +150,27 @@ void VertexManager::Flush()
VideoFifo_CheckEFBAccess();
#if defined(_DEBUG) || defined(DEBUGFAST)
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens,
xfregs.numChan.numColorChans, xfregs.dualTexTrans.enabled, bpmem.ztex2.op,
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfmem.numTexGen.numTexGens,
xfmem.numChan.numColorChans, xfmem.dualTexTrans.enabled, bpmem.ztex2.op,
bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.zmode.updateenable);
for (unsigned int i = 0; i < xfregs.numChan.numColorChans; ++i)
for (unsigned int i = 0; i < xfmem.numChan.numColorChans; ++i)
{
LitChannel* ch = &xfregs.color[i];
LitChannel* ch = &xfmem.color[i];
PRIM_LOG("colchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc);
ch = &xfregs.alpha[i];
ch = &xfmem.alpha[i];
PRIM_LOG("alpchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc);
}
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
{
TexMtxInfo tinfo = xfregs.texMtxInfo[i];
TexMtxInfo tinfo = xfmem.texMtxInfo[i];
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP) tinfo.hex &= 0x7ff;
if (tinfo.texgentype != XF_TEXGEN_REGULAR) tinfo.projection = 0;
PRIM_LOG("txgen%d: proj=%d, input=%d, gentype=%d, srcrow=%d, embsrc=%d, emblght=%d, postmtx=%d, postnorm=%d",
i, tinfo.projection, tinfo.inputform, tinfo.texgentype, tinfo.sourcerow, tinfo.embosssourceshift, tinfo.embosslightshift,
xfregs.postMtxInfo[i].index, xfregs.postMtxInfo[i].normalize);
xfmem.postMtxInfo[i].index, xfmem.postMtxInfo[i].normalize);
}
PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphatest=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages,

View File

@ -44,13 +44,13 @@ static inline void GenerateVSOutputStruct(T& object, API_TYPE api_type)
DefineVSOutputStructMember(object, api_type, "float4", "colors_", 0, "COLOR", 0);
DefineVSOutputStructMember(object, api_type, "float4", "colors_", 1, "COLOR", 1);
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
DefineVSOutputStructMember(object, api_type, "float3", "tex", i, "TEXCOORD", i);
DefineVSOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfregs.numTexGen.numTexGens);
DefineVSOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens);
if (g_ActiveConfig.bEnablePixelLighting)
DefineVSOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfregs.numTexGen.numTexGens + 1);
DefineVSOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1);
object.Write("};\n");
}
@ -78,8 +78,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
if (is_writing_shadercode)
text[sizeof(text) - 1] = 0x7C; // canary
_assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans);
_assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans);
// uniforms
if (api_type == API_OPENGL)
@ -101,7 +101,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
GenerateVSOutputStruct(out, api_type);
uid_data.numTexGens = xfregs.numTexGen.numTexGens;
uid_data.numTexGens = xfmem.numTexGen.numTexGens;
uid_data.components = components;
uid_data.pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
@ -132,7 +132,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
// Let's set up attributes
for (size_t i = 0; i < 8; ++i)
{
if (i < xfregs.numTexGen.numTexGens)
if (i < xfmem.numTexGen.numTexGens)
{
out.Write("centroid out float3 uv%d;\n", i);
}
@ -220,8 +220,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
"float3 ldir, h;\n"
"float dist, dist2, attn;\n");
uid_data.numColorChans = xfregs.numChan.numColorChans;
if (xfregs.numChan.numColorChans == 0)
uid_data.numColorChans = xfmem.numChan.numColorChans;
if (xfmem.numChan.numColorChans == 0)
{
if (components & VB_HAS_COL0)
out.Write("o.colors_0 = color0;\n");
@ -231,7 +231,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
GenerateLightingShader<T>(out, uid_data.lighting, components, I_MATERIALS, I_LIGHT_COLORS, I_LIGHTS, "color", "o.colors_");
if (xfregs.numChan.numColorChans < 2)
if (xfmem.numChan.numColorChans < 2)
{
if (components & VB_HAS_COL1)
out.Write("o.colors_1 = color1;\n");
@ -244,18 +244,18 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
/*bool texGenSpecialCase =
((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0
(g_VtxDesc.Tex0Coord != NOT_PRESENT) &&
(xfregs.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11);
(xfmem.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11);
*/
// transform texcoords
out.Write("float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n");
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
{
TexMtxInfo& texinfo = xfregs.texMtxInfo[i];
TexMtxInfo& texinfo = xfmem.texMtxInfo[i];
out.Write("{\n");
out.Write("coord = float4(0.0, 0.0, 1.0, 1.0);\n");
uid_data.texMtxInfo[i].sourcerow = xfregs.texMtxInfo[i].sourcerow;
uid_data.texMtxInfo[i].sourcerow = xfmem.texMtxInfo[i].sourcerow;
switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
@ -294,7 +294,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
}
// first transformation
uid_data.texMtxInfo[i].texgentype = xfregs.texMtxInfo[i].texgentype;
uid_data.texMtxInfo[i].texgentype = xfmem.texMtxInfo[i].texgentype;
switch (texinfo.texgentype)
{
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
@ -302,15 +302,15 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
if (components & (VB_HAS_NRM1|VB_HAS_NRM2))
{
// transform the light dir into tangent space
uid_data.texMtxInfo[i].embosslightshift = xfregs.texMtxInfo[i].embosslightshift;
uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift;
uid_data.texMtxInfo[i].embosslightshift = xfmem.texMtxInfo[i].embosslightshift;
uid_data.texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(I_LIGHTS, texinfo.embosslightshift));
out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0);\n", i, texinfo.embosssourceshift);
}
else
{
_assert_(0); // should have normals
uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift;
uid_data.texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift);
}
@ -325,7 +325,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
break;
case XF_TEXGEN_REGULAR:
default:
uid_data.texMtxInfo_n_projection |= xfregs.texMtxInfo[i].projection << i;
uid_data.texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i;
if (components & (VB_HAS_TEXMTXIDX0<<i))
{
out.Write("int tmp = int(tex%d.z);\n", i);
@ -344,13 +344,13 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
break;
}
uid_data.dualTexTrans_enabled = xfregs.dualTexTrans.enabled;
uid_data.dualTexTrans_enabled = xfmem.dualTexTrans.enabled;
// CHECKME: does this only work for regular tex gen types?
if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
if (xfmem.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
{
const PostMtxInfo& postInfo = xfregs.postMtxInfo[i];
const PostMtxInfo& postInfo = xfmem.postMtxInfo[i];
uid_data.postMtxInfo[i].index = xfregs.postMtxInfo[i].index;
uid_data.postMtxInfo[i].index = xfmem.postMtxInfo[i].index;
int postidx = postInfo.index;
out.Write("float4 P0 = " I_POSTTRANSFORMMATRICES"[%d];\n"
"float4 P1 = " I_POSTTRANSFORMMATRICES"[%d];\n"
@ -368,7 +368,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
}
else
{
uid_data.postMtxInfo[i].normalize = xfregs.postMtxInfo[i].normalize;
uid_data.postMtxInfo[i].normalize = xfmem.postMtxInfo[i].normalize;
if (postInfo.normalize)
out.Write("o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i);
@ -432,9 +432,10 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
// Will look better when we bind uniforms in GLSL 1.3
// clipPos/w needs to be done in pixel shader, not here
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i)
out.Write(" uv%d.xyz = o.tex%d;\n", i, i);
out.Write(" clipPos = o.clipPos;\n");
if (g_ActiveConfig.bEnablePixelLighting)
out.Write(" Normal = o.Normal;\n");

View File

@ -131,10 +131,10 @@ static void ViewportCorrectionMatrix(Matrix44& result)
// TODO: ceil, floor or just cast to int?
// TODO: Directly use the floats instead of rounding them?
float intendedX = xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff;
float intendedY = xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff;
float intendedWd = 2.0f * xfregs.viewport.wd;
float intendedHt = -2.0f * xfregs.viewport.ht;
float intendedX = xfmem.viewport.xOrig - xfmem.viewport.wd - scissorXOff;
float intendedY = xfmem.viewport.yOrig + xfmem.viewport.ht - scissorYOff;
float intendedWd = 2.0f * xfmem.viewport.wd;
float intendedHt = -2.0f * xfmem.viewport.ht;
if (intendedWd < 0.f)
{
@ -167,8 +167,7 @@ void VertexShaderManager::Init()
{
Dirty();
memset(&xfregs, 0, sizeof(xfregs));
memset(xfmem, 0, sizeof(xfmem));
memset(&xfmem, 0, sizeof(xfmem));
memset(&constants, 0 , sizeof(constants));
ResetView();
@ -216,7 +215,7 @@ void VertexShaderManager::SetConstants()
{
int startn = nTransformMatricesChanged[0] / 4;
int endn = (nTransformMatricesChanged[1] + 3) / 4;
memcpy(constants.transformmatrices[startn], &xfmem[startn * 4], (endn - startn) * 16);
memcpy(constants.transformmatrices[startn], &xfmem.posMatrices[startn * 4], (endn - startn) * 16);
dirty = true;
nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
}
@ -227,7 +226,7 @@ void VertexShaderManager::SetConstants()
int endn = (nNormalMatricesChanged[1] + 2) / 3;
for (int i=startn; i<endn; i++)
{
memcpy(constants.normalmatrices[i], &xfmem[XFMEM_NORMALMATRICES + 3*i], 12);
memcpy(constants.normalmatrices[i], &xfmem.normalMatrices[3*i], 12);
}
dirty = true;
nNormalMatricesChanged[0] = nNormalMatricesChanged[1] = -1;
@ -237,7 +236,7 @@ void VertexShaderManager::SetConstants()
{
int startn = nPostTransformMatricesChanged[0] / 4;
int endn = (nPostTransformMatricesChanged[1] + 3 ) / 4;
memcpy(constants.posttransformmatrices[startn], &xfmem[XFMEM_POSTMATRICES + startn * 4], (endn - startn) * 16);
memcpy(constants.posttransformmatrices[startn], &xfmem.postMatrices[startn * 4], (endn - startn) * 16);
dirty = true;
nPostTransformMatricesChanged[0] = nPostTransformMatricesChanged[1] = -1;
}
@ -248,7 +247,7 @@ void VertexShaderManager::SetConstants()
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
int istart = nLightsChanged[0] / 0x10;
int iend = (nLightsChanged[1] + 15) / 0x10;
const float* xfmemptr = (const float*)&xfmem[0x10 * istart + XFMEM_LIGHTS];
const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart];
for (int i = istart; i < iend; ++i)
{
@ -286,7 +285,7 @@ void VertexShaderManager::SetConstants()
{
if (nMaterialsChanged & (1 << i))
{
u32 data = *(xfregs.ambColor + i);
u32 data = xfmem.ambColor[i];
constants.materials[i][0] = (data >> 24) & 0xFF;
constants.materials[i][1] = (data >> 16) & 0xFF;
constants.materials[i][2] = (data >> 8) & 0xFF;
@ -298,7 +297,7 @@ void VertexShaderManager::SetConstants()
{
if (nMaterialsChanged & (1 << (i + 2)))
{
u32 data = *(xfregs.matColor + i);
u32 data = xfmem.matColor[i];
constants.materials[i+2][0] = (data >> 24) & 0xFF;
constants.materials[i+2][1] = (data >> 16) & 0xFF;
constants.materials[i+2][2] = (data >> 8) & 0xFF;
@ -314,8 +313,8 @@ void VertexShaderManager::SetConstants()
{
bPosNormalMatrixChanged = false;
const float *pos = (const float *)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
const float *norm = (const float *)xfmem + XFMEM_NORMALMATRICES + 3 * (MatrixIndexA.PosNormalMtxIdx & 31);
const float *pos = (const float *)xfmem.posMatrices + MatrixIndexA.PosNormalMtxIdx * 4;
const float *norm = (const float *)xfmem.normalMatrices + 3 * (MatrixIndexA.PosNormalMtxIdx & 31);
memcpy(constants.posnormalmatrix, pos, 3*16);
memcpy(constants.posnormalmatrix[3], norm, 12);
@ -329,8 +328,10 @@ void VertexShaderManager::SetConstants()
bTexMatricesChanged[0] = false;
const float *fptrs[] =
{
(const float *)xfmem + MatrixIndexA.Tex0MtxIdx * 4, (const float *)xfmem + MatrixIndexA.Tex1MtxIdx * 4,
(const float *)xfmem + MatrixIndexA.Tex2MtxIdx * 4, (const float *)xfmem + MatrixIndexA.Tex3MtxIdx * 4
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex0MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex1MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex2MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex3MtxIdx * 4]
};
for (int i = 0; i < 4; ++i)
@ -344,8 +345,10 @@ void VertexShaderManager::SetConstants()
{
bTexMatricesChanged[1] = false;
const float *fptrs[] = {
(const float *)xfmem + MatrixIndexB.Tex4MtxIdx * 4, (const float *)xfmem + MatrixIndexB.Tex5MtxIdx * 4,
(const float *)xfmem + MatrixIndexB.Tex6MtxIdx * 4, (const float *)xfmem + MatrixIndexB.Tex7MtxIdx * 4
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex4MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex5MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex6MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex7MtxIdx * 4]
};
for (int i = 0; i < 4; ++i)
@ -358,8 +361,8 @@ void VertexShaderManager::SetConstants()
if (bViewportChanged)
{
bViewportChanged = false;
constants.depthparams[0] = xfregs.viewport.farZ / 16777216.0f;
constants.depthparams[1] = xfregs.viewport.zRange / 16777216.0f;
constants.depthparams[0] = xfmem.viewport.farZ / 16777216.0f;
constants.depthparams[1] = xfmem.viewport.zRange / 16777216.0f;
// The console GPU places the pixel center at 7/12 unless antialiasing
// is enabled, while D3D and OpenGL place it at 0.5. See the comment
@ -367,8 +370,8 @@ void VertexShaderManager::SetConstants()
// NOTE: If we ever emulate antialiasing, the sample locations set by
// BP registers 0x01-0x04 need to be considered here.
const float pixel_center_correction = 7.0f / 12.0f - 0.5f;
const float pixel_size_x = 2.f / Renderer::EFBToScaledXf(2.f * xfregs.viewport.wd);
const float pixel_size_y = 2.f / Renderer::EFBToScaledXf(2.f * xfregs.viewport.ht);
const float pixel_size_x = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.wd);
const float pixel_size_y = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.ht);
constants.depthparams[2] = pixel_center_correction * pixel_size_x;
constants.depthparams[3] = pixel_center_correction * pixel_size_y;
dirty = true;
@ -387,9 +390,9 @@ void VertexShaderManager::SetConstants()
{
bProjectionChanged = false;
float *rawProjection = xfregs.projection.rawProjection;
float *rawProjection = xfmem.projection.rawProjection;
switch (xfregs.projection.type)
switch (xfmem.projection.type)
{
case GX_PERSPECTIVE:
@ -483,12 +486,12 @@ void VertexShaderManager::SetConstants()
break;
default:
ERROR_LOG(VIDEO, "Unknown projection type: %d", xfregs.projection.type);
ERROR_LOG(VIDEO, "Unknown projection type: %d", xfmem.projection.type);
}
PRIM_LOG("Projection: %f %f %f %f %f %f\n", rawProjection[0], rawProjection[1], rawProjection[2], rawProjection[3], rawProjection[4], rawProjection[5]);
if ((g_ActiveConfig.bFreeLook || g_ActiveConfig.bAnaglyphStereo ) && xfregs.projection.type == GX_PERSPECTIVE)
if ((g_ActiveConfig.bFreeLook || g_ActiveConfig.bAnaglyphStereo ) && xfmem.projection.type == GX_PERSPECTIVE)
{
Matrix44 mtxA;
Matrix44 mtxB;

View File

@ -30,8 +30,7 @@ static void DoState(PointerWrap &p)
p.DoMarker("CP Memory");
// XF Memory
p.Do(xfregs);
p.DoArray(xfmem, XFMEM_SIZE);
p.Do(xfmem);
p.DoMarker("XF Memory");
// Texture decoder

View File

@ -5,5 +5,4 @@
#include "VideoCommon/XFMemory.h"
// STATE_TO_SAVE
XFRegisters xfregs;
u32 xfmem[XFMEM_SIZE];
XFMemory xfmem;

View File

@ -5,6 +5,7 @@
#pragma once
#include "Common/Common.h"
#include "VideoCommon/CPMemory.h"
// Lighting
@ -50,7 +51,6 @@
#define GX_PERSPECTIVE 0
#define GX_ORTHOGRAPHIC 1
#define XFMEM_SIZE 0x8000
#define XFMEM_POSMATRICES 0x000
#define XFMEM_POSMATRICES_END 0x100
#define XFMEM_NORMALMATRICES 0x400
@ -234,8 +234,15 @@ struct Projection
u32 type; // only GX_PERSPECTIVE or GX_ORTHOGRAPHIC are allowed
};
struct XFRegisters
struct XFMemory
{
u32 posMatrices[256]; // 0x0000 - 0x00ff
u32 unk0[768]; // 0x0100 - 0x03ff
u32 normalMatrices[96]; // 0x0400 - 0x045f
u32 unk1[160]; // 0x0460 - 0x04ff
u32 postMatrices[256]; // 0x0500 - 0x05ff
u32 lights[128]; // 0x0600 - 0x067f
u32 unk2[2432]; // 0x0680 - 0x0fff
u32 error; // 0x1000
u32 diag; // 0x1001
u32 state0; // 0x1002
@ -256,8 +263,8 @@ struct XFRegisters
u32 unk5; // 0x1015
u32 unk6; // 0x1016
u32 unk7; // 0x1017
u32 MatrixIndexA; // 0x1018
u32 MatrixIndexB; // 0x1019
TMatrixIndexA MatrixIndexA; // 0x1018
TMatrixIndexB MatrixIndexB; // 0x1019
Viewport viewport; // 0x101a - 0x101f
Projection projection; // 0x1020 - 0x1026
u32 unk8[24]; // 0x1027 - 0x103e
@ -268,8 +275,7 @@ struct XFRegisters
};
extern XFRegisters xfregs;
extern u32 xfmem[XFMEM_SIZE];
extern XFMemory xfmem;
void LoadXFReg(u32 transferSize, u32 address, u32 *pData);
void LoadIndexedXF(u32 val, int array);

View File

@ -49,7 +49,7 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
break;
case XFMEM_SETNUMCHAN:
if (xfregs.numChan.numColorChans != (newValue & 3))
if (xfmem.numChan.numColorChans != (newValue & 3))
VertexManager::Flush();
break;
@ -57,7 +57,7 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
case XFMEM_SETCHAN1_AMBCOLOR:
{
u8 chan = address - XFMEM_SETCHAN0_AMBCOLOR;
if (xfregs.ambColor[chan] != newValue)
if (xfmem.ambColor[chan] != newValue)
{
VertexManager::Flush();
VertexShaderManager::SetMaterialColorChanged(chan, newValue);
@ -70,7 +70,7 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
case XFMEM_SETCHAN1_MATCOLOR:
{
u8 chan = address - XFMEM_SETCHAN0_MATCOLOR;
if (xfregs.matColor[chan] != newValue)
if (xfmem.matColor[chan] != newValue)
{
VertexManager::Flush();
VertexShaderManager::SetMaterialColorChanged(chan + 2, newValue);
@ -83,12 +83,12 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
case XFMEM_SETCHAN1_COLOR:
case XFMEM_SETCHAN0_ALPHA: // Channel Alpha
case XFMEM_SETCHAN1_ALPHA:
if (((u32*)&xfregs)[address - 0x1000] != (newValue & 0x7fff))
if (((u32*)&xfmem)[address] != (newValue & 0x7fff))
VertexManager::Flush();
break;
case XFMEM_DUALTEX:
if (xfregs.dualTexTrans.enabled != (newValue & 1))
if (xfmem.dualTexTrans.enabled != (newValue & 1))
VertexManager::Flush();
break;
@ -129,7 +129,7 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
break;
case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens
if (xfregs.numTexGen.numTexGens != (newValue & 15))
if (xfmem.numTexGen.numTexGens != (newValue & 15))
VertexManager::Flush();
break;
@ -164,7 +164,7 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
// --------------
// Maybe these are for Normals?
case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
case 0x1048: //xfmem.texcoords[0].nrmmtxinfo.hex = data; break; ??
case 0x1049:
case 0x104a:
case 0x104b:
@ -228,7 +228,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
}
XFMemWritten(xfMemTransferSize, xfMemBase);
memcpy_gc(&xfmem[xfMemBase], pData, xfMemTransferSize * 4);
memcpy_gc((u32*)(&xfmem) + xfMemBase, pData, xfMemTransferSize * 4);
pData += xfMemTransferSize;
}
@ -237,7 +237,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
if (transferSize > 0)
{
XFRegWritten(transferSize, baseAddress, pData);
memcpy_gc((u32*)(&xfregs) + (baseAddress - 0x1000), pData, transferSize * 4);
memcpy_gc((u32*)(&xfmem) + baseAddress, pData, transferSize * 4);
}
}
@ -249,7 +249,7 @@ void LoadIndexedXF(u32 val, int refarray)
int size = ((val >> 12) & 0xF) + 1;
//load stuff from array to address in xf mem
u32* currData = (u32*)(xfmem + address);
u32* currData = (u32*)(&xfmem) + address;
u32* newData = (u32*)Memory::GetPointer(arraybases[refarray] + arraystrides[refarray] * index);
bool changed = false;
for (int i = 0; i < size; ++i)