Merge pull request #3367 from unknownbrackets/gpu-minor

More gstate accessors / typesafety
This commit is contained in:
Henrik Rydgård 2013-08-24 15:43:04 -07:00
commit e860abdd6d
18 changed files with 138 additions and 151 deletions

View file

@ -475,7 +475,7 @@ void FramebufferManager::SetRenderFrameBuffer() {
// As there are no clear "framebuffer width" and "framebuffer height" registers,
// we need to infer the size of the current framebuffer somehow. Let's try the viewport.
GEBufferFormat fmt = static_cast<GEBufferFormat>(gstate.framebufpixformat & 3);
GEBufferFormat fmt = gstate.FrameBufFormat();
int drawing_width, drawing_height;
GuessDrawingSize(drawing_width, drawing_height);

View file

@ -662,7 +662,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
}
if (!Memory::IsValidAddress(gstate_c.vertexAddr)) {
ERROR_LOG(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr);
ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr);
break;
}
@ -672,12 +672,18 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
void *inds = 0;
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
if (!Memory::IsValidAddress(gstate_c.indexAddr)) {
ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr);
ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr);
break;
}
inds = Memory::GetPointer(gstate_c.indexAddr);
}
#ifndef USING_GLES2
if (prim > GE_PRIM_RECTANGLES) {
ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim);
}
#endif
int bytesRead;
transformDraw_.SubmitPrim(verts, inds, prim, count, gstate.vertType, -1, &bytesRead);
@ -714,14 +720,14 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
void *indices = NULL;
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
if (!Memory::IsValidAddress(gstate_c.indexAddr)) {
ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr);
ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr);
break;
}
indices = Memory::GetPointer(gstate_c.indexAddr);
}
if (gstate.getPatchPrimitiveType() != GE_PATCHPRIM_TRIANGLES) {
ERROR_LOG(G3D, "Unsupported patch primitive %x", gstate.patchprimitive&3);
ERROR_LOG_REPORT(G3D, "Unsupported patch primitive %x", gstate.getPatchPrimitiveType());
break;
}
@ -729,7 +735,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
int sp_vcount = (data >> 8) & 0xFF;
int sp_utype = (data >> 16) & 0x3;
int sp_vtype = (data >> 18) & 0x3;
int patchPrim = gstate.patchprimitive & 3;
GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType();
transformDraw_.SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, gstate.vertType);
}
break;
@ -1300,22 +1306,22 @@ void GLES_GPU::DoBlockTransfer() {
//
// etc....
u32 srcBasePtr = (gstate.transfersrc & 0xFFFFF0) | ((gstate.transfersrcw & 0xFF0000) << 8);
u32 srcStride = gstate.transfersrcw & 0x3F8;
u32 srcBasePtr = gstate.getTransferSrcAddress();
u32 srcStride = gstate.getTransferSrcStride();
u32 dstBasePtr = (gstate.transferdst & 0xFFFFF0) | ((gstate.transferdstw & 0xFF0000) << 8);
u32 dstStride = gstate.transferdstw & 0x3F8;
u32 dstBasePtr = gstate.getTransferDstAddress();
u32 dstStride = gstate.getTransferDstStride();
int srcX = gstate.transfersrcpos & 0x3FF;
int srcY = (gstate.transfersrcpos >> 10) & 0x3FF;
int srcX = gstate.getTransferSrcX();
int srcY = gstate.getTransferSrcY();
int dstX = gstate.transferdstpos & 0x3FF;
int dstY = (gstate.transferdstpos >> 10) & 0x3FF;
int dstX = gstate.getTransferDstX();
int dstY = gstate.getTransferDstY();
int width = (gstate.transfersize & 0x3FF) + 1;
int height = ((gstate.transfersize >> 10) & 0x3FF) + 1;
int width = gstate.getTransferWidth();
int height = gstate.getTransferHeight();
int bpp = (gstate.transferstart & 1) ? 4 : 2;
int bpp = gstate.getTransferBpp();
DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY);

View file

@ -113,7 +113,7 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs, bool useHWTransform)
u_view = glGetUniformLocation(program, "u_view");
u_world = glGetUniformLocation(program, "u_world");
u_texmtx = glGetUniformLocation(program, "u_texmtx");
if (gstate.getWeightMask() != 0)
if (gstate.getWeightMask() != GE_VTYPE_WEIGHT_NONE)
numBones = TranslateNumBones(gstate.getNumBoneWeights());
else
numBones = 0;
@ -338,7 +338,7 @@ void LinkedShader::updateUniforms() {
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN) {
static const float rescale[4] = {1.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
float factor = rescale[gstate.getTexCoordMask() >> GE_VTYPE_TC_SHIFT];
uvscaleoff[0] = gstate_c.uv.uScale * factor * widthFactor;
uvscaleoff[1] = gstate_c.uv.vScale * factor * heightFactor;
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;

View file

@ -57,7 +57,7 @@ void TransformDrawEngine::DrawBezier(int ucount, int vcount) {
}
}
if (!(gstate.vertType & GE_VTYPE_TC_MASK)) {
if (!gstate.getTexCoordMask()) {
VertexDecoder *dec = GetVertexDecoder(gstate.vertType);
dec->SetVertexType(gstate.vertType);
u32 newVertType = dec->InjectUVs(decoded2, Memory::GetPointer(gstate_c.vertexAddr), customUV, 16);
@ -92,7 +92,7 @@ void CopyTriangle(u8 *&dest, u8 *v1, u8 *v2, u8 * v3, int vertexSize) {
dest += vertexSize;
}
void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type)
void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type)
{
Flush();

View file

@ -330,7 +330,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
renderHeightFactor = renderHeight / 272.0f;
}
bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0;
bool throughmode = gstate.isModeThrough();
// Scissor
int scissorX1 = gstate.getScissorX1();

View file

@ -254,13 +254,6 @@ void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffe
}
}
static u32 GetClutIndex(u32 index) {
const u32 clutBase = gstate.getClutIndexStartPos();
const u32 clutMask = gstate.getClutIndexMask();
const u8 clutShift = gstate.getClutIndexShift();
return ((index >> clutShift) & clutMask) | clutBase;
}
void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u32 level) {
const u32 rowWidth = (bytesPerPixel > 0) ? (bufw * bytesPerPixel) : (bufw / 2);
const u32 pitch = rowWidth / 4;
@ -346,7 +339,7 @@ inline void DeIndexTexture(ClutT *dest, const IndexT *indexed, int length, const
}
} else {
for (int i = 0; i < length; ++i) {
*dest++ = clut[GetClutIndex(*indexed++)];
*dest++ = clut[gstate.transformClutIndex(*indexed++)];
}
}
}
@ -371,8 +364,8 @@ inline void DeIndexTexture4(ClutT *dest, const u8 *indexed, int length, const Cl
} else {
for (int i = 0; i < length; i += 2) {
u8 index = *indexed++;
dest[i + 0] = clut[GetClutIndex((index >> 0) & 0xf)];
dest[i + 1] = clut[GetClutIndex((index >> 4) & 0xf)];
dest[i + 0] = clut[gstate.transformClutIndex((index >> 0) & 0xf)];
dest[i + 1] = clut[gstate.transformClutIndex((index >> 4) & 0xf)];
}
}
}
@ -424,7 +417,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
tmpTexBuf16.resize(std::max(bufw, w) * h);
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
const u16 *clut = GetCurrentClut<u16>();
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
switch (bytesPerIndex) {
case 1:
DeIndexTexture<u8>(tmpTexBuf16.data(), texaddr, length, clut);
@ -464,7 +457,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
tmpTexBuf32.resize(std::max(bufw, w) * h);
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
const u32 *clut = GetCurrentClut<u32>();
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
switch (bytesPerIndex) {
case 1:
DeIndexTexture<u8>(tmpTexBuf32.data(), texaddr, length, clut);
@ -550,8 +543,8 @@ static const GLuint MagFiltGL[2] = {
void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
int minFilt = gstate.texfilter & 0x7;
int magFilt = (gstate.texfilter>>8) & 1;
bool sClamp = gstate.texwrap & 1;
bool tClamp = (gstate.texwrap>>8) & 1;
bool sClamp = gstate.isTexCoordClampedS();
bool tClamp = gstate.isTexCoordClampedT();
bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0
@ -873,8 +866,8 @@ inline bool TextureCache::TexCacheEntry::Matches(u16 dim2, u8 format2, int maxLe
}
void TextureCache::LoadClut() {
u32 clutAddr = ((gstate.clutaddr & 0xFFFFFF) | ((gstate.clutaddrupper << 8) & 0x0F000000));
clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32;
u32 clutAddr = gstate.getClutAddress();
clutTotalBytes_ = gstate.getClutLoadBytes();
if (Memory::IsValidAddress(clutAddr)) {
Memory::MemcpyUnchecked(clutBufRaw_, clutAddr, clutTotalBytes_);
} else {
@ -1285,7 +1278,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
const u16 *clut = GetCurrentClut<u16>() + clutSharingOffset;
texByteAlign = 2;
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
if (clutAlphaLinear_ && mipmapShareClut) {
DeIndexTexture4Optimal(tmpTexBuf16.data(), texaddr, bufw * h, clutAlphaLinearColor_);
} else {
@ -1309,7 +1302,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
tmpTexBuf32.resize(std::max(bufw, w) * h);
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
const u32 *clut = GetCurrentClut<u32>() + clutSharingOffset;
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
DeIndexTexture4(tmpTexBuf32.data(), texaddr, bufw * h, clut);
finalBuf = tmpTexBuf32.data();
} else {
@ -1366,7 +1359,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
dstFmt = GL_UNSIGNED_SHORT_5_6_5;
texByteAlign = 2;
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
int len = std::max(bufw, w) * h;
tmpTexBuf16.resize(len);
tmpTexBufRearrange.resize(len);
@ -1383,7 +1376,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
if (bufw < 4)
bufw = 4;
dstFmt = GL_UNSIGNED_BYTE;
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
// Special case: if we don't need to deal with packing, we don't need to copy.
if (w == bufw) {
finalBuf = Memory::GetPointer(texaddr);

View file

@ -150,7 +150,7 @@ private:
};
Lighter::Lighter() {
doShadeMapping_ = (gstate.texmapmode & 0x3) == 2;
doShadeMapping_ = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP;
materialEmissive.GetFromRGB(gstate.materialemissive);
materialEmissive.a = 0.0f;
globalAmbient.GetFromRGB(gstate.ambientcolor);
@ -677,16 +677,17 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
((clearColor & 0xFF0000) >> 16) / 255.0f,
((clearColor & 0xFF000000) >> 24) / 255.0f,
};
int target = 0;
if ((gstate.clearmode >> 8) & 3) target |= GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
if ((gstate.clearmode >> 10) & 1) target |= GL_DEPTH_BUFFER_BIT;
bool colorMask = (gstate.clearmode >> 8) & 1;
bool alphaMask = (gstate.clearmode >> 9) & 1;
bool colorMask = gstate.isClearModeColorMask();
bool alphaMask = gstate.isClearModeAlphaMask();
glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);
glstate.stencilTest.set(false);
glstate.scissorTest.set(false);
bool depthMask = (gstate.clearmode >> 10) & 1;
bool depthMask = gstate.isClearModeDepthMask();
int target = 0;
if (colorMask || alphaMask) target |= GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
if (depthMask) target |= GL_DEPTH_BUFFER_BIT;
glClearColor(col[0], col[1], col[2], col[3]);
#ifdef USING_GLES2

View file

@ -98,7 +98,7 @@ public:
virtual ~TransformDrawEngine();
void SubmitPrim(void *verts, void *inds, int prim, int vertexCount, u32 vertexType, int forceIndexType, int *bytesRead);
void DrawBezier(int ucount, int vcount);
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type);
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type);
void DecodeVerts();
void SetShaderManager(ShaderManager *shaderManager) {

View file

@ -336,7 +336,7 @@ void VertexDecoder::Step_NormalS8() const
{
s8 *normal = (s8 *)(decoded_ + decFmt.nrmoff);
u8 xorval = 0;
if (gstate.reversenormals & 1)
if (gstate.areNormalsReversed())
xorval = 0xFF; // Using xor instead of - to handle -128
const s8 *sv = (const s8*)(ptr_ + nrmoff);
for (int j = 0; j < 3; j++)
@ -348,7 +348,7 @@ void VertexDecoder::Step_NormalS16() const
{
s16 *normal = (s16 *)(decoded_ + decFmt.nrmoff);
u16 xorval = 0;
if (gstate.reversenormals & 1)
if (gstate.areNormalsReversed())
xorval = 0xFFFF;
const s16 *sv = (const s16*)(ptr_ + nrmoff);
for (int j = 0; j < 3; j++)
@ -360,7 +360,7 @@ void VertexDecoder::Step_NormalFloat() const
{
float *normal = (float *)(decoded_ + decFmt.nrmoff);
float multiplier = 1.0f;
if (gstate.reversenormals & 1)
if (gstate.areNormalsReversed())
multiplier = -multiplier;
const float *fv = (const float*)(ptr_ + nrmoff);
for (int j = 0; j < 3; j++)
@ -374,7 +374,7 @@ void VertexDecoder::Step_NormalS8Morph() const
for (int n = 0; n < morphcount; n++)
{
float multiplier = gstate_c.morphWeights[n];
if (gstate.reversenormals & 1) {
if (gstate.areNormalsReversed()) {
multiplier = -multiplier;
}
const s8 *bv = (const s8*)(ptr_ + onesize_*n + nrmoff);
@ -391,7 +391,7 @@ void VertexDecoder::Step_NormalS16Morph() const
for (int n = 0; n < morphcount; n++)
{
float multiplier = gstate_c.morphWeights[n];
if (gstate.reversenormals & 1) {
if (gstate.areNormalsReversed()) {
multiplier = -multiplier;
}
const s16 *sv = (const s16 *)(ptr_ + onesize_*n + nrmoff);
@ -408,7 +408,7 @@ void VertexDecoder::Step_NormalFloatMorph() const
for (int n = 0; n < morphcount; n++)
{
float multiplier = gstate_c.morphWeights[n];
if (gstate.reversenormals & 1) {
if (gstate.areNormalsReversed()) {
multiplier = -multiplier;
}
const float *fv = (const float*)(ptr_ + onesize_*n + nrmoff);

View file

@ -60,7 +60,7 @@ void ComputeVertexShaderID(VertexShaderID *id, int prim, bool useHWTransform) {
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0;
bool hasBones = gstate.getWeightMask() != 0;
bool hasBones = gstate.getWeightMask() != GE_VTYPE_WEIGHT_NONE;
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();

View file

@ -566,7 +566,7 @@ void GPUCommon::ProcessEvent(GPUEvent ev) {
break;
default:
ERROR_LOG(G3D, "Unexpected GPU event type: %d", (int)ev);
ERROR_LOG_REPORT(G3D, "Unexpected GPU event type: %d", (int)ev);
}
}

View file

@ -225,6 +225,7 @@ struct GPUgstate
bool isClearModeDepthWriteEnabled() const { return (clearmode&0x400) != 0; }
bool isClearModeColorMask() const { return (clearmode&0x100) != 0; }
bool isClearModeAlphaMask() const { return (clearmode&0x200) != 0; }
bool isClearModeDepthMask() const { return (clearmode&0x400) != 0; }
u32 getClearModeColorMask() const { return ((clearmode&0x100) ? 0xFFFFFF : 0) | ((clearmode&0x200) ? 0xFF000000 : 0); } // TODO: Different convention than getColorMask, confusing!
// Blend
@ -283,11 +284,15 @@ struct GPUgstate
int getTextureEnvColR() const { return texenvcolor&0xFF; }
int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; }
int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; }
u32 getClutAddress() const { return (clutaddr & 0x00FFFFFF) | ((clutaddrupper << 8) & 0x0F000000); }
int getClutLoadBytes() const { return (loadclut & 0x3F) * 32; }
GEPaletteFormat getClutPaletteFormat() { return static_cast<GEPaletteFormat>(clutformat & 3); }
int getClutIndexShift() const { return (clutformat >> 2) & 0x1F; }
int getClutIndexMask() const { return (clutformat >> 8) & 0xFF; }
int getClutIndexStartPos() const { return ((clutformat >> 16) & 0x1F) << 4; }
int transformClutIndex(int index) const { return ((index >> getClutIndexShift()) & getClutIndexMask()) | getClutIndexStartPos(); }
bool isClutIndexSimple() const { return (clutformat & ~3) == 0xC500FF00; } // Meaning, no special mask, shift, or start pos.
bool isTextureSwizzled() const { return texmode & 1; }
// Lighting
bool isLightingEnabled() const { return lightingEnable & 1; }
@ -352,9 +357,24 @@ struct GPUgstate
int getWeightMask() const { return vertType & GE_VTYPE_WEIGHT_MASK; }
int getNumBoneWeights() const { return 1 + ((vertType & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT); }
bool isSkinningEnabled() const { return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE); }
int getTexCoordMask() const { return vertType & GE_VTYPE_TC_MASK; }
bool areNormalsReversed() const { return reversenormals & 1; }
GEPatchPrimType getPatchPrimitiveType() const { return static_cast<GEPatchPrimType>(patchprimitive & 3); }
// Transfers
u32 getTransferSrcAddress() const { return (transfersrc & 0xFFFFF0) | ((transfersrcw & 0xFF0000) << 8); }
u32 getTransferSrcStride() const { return transfersrcw & 0x3F8; }
int getTransferSrcX() const { return (transfersrcpos >> 0) & 0x3FF; }
int getTransferSrcY() const { return (transfersrcpos >> 10) & 0x3FF; }
u32 getTransferDstAddress() const { return (transferdst & 0xFFFFF0) | ((transferdstw & 0xFF0000) << 8); }
u32 getTransferDstStride() const { return transferdstw & 0x3F8; }
int getTransferDstX() const { return (transferdstpos >> 0) & 0x3FF; }
int getTransferDstY() const { return (transferdstpos >> 10) & 0x3FF; }
int getTransferWidth() const { return ((transfersize >> 0) & 0x3FF) + 1; }
int getTransferHeight() const { return ((transfersize >> 10) & 0x3FF) + 1; }
int getTransferBpp() const { return (transferstart & 1) ? 4 : 2; }
// Real data in the context ends here
};

View file

@ -437,7 +437,10 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
case GE_CMD_TRANSFERSRC:
{
sprintf(buffer, "Block transfer src: %06x", data);
if (data & 0xF)
sprintf(buffer, "Block transfer src: %06x (extra: %x)", data & ~0xF, data & 0xF);
else
sprintf(buffer, "Block transfer src: %06x", data);
// Nothing to do, the next one prints
}
break;
@ -445,7 +448,7 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
case GE_CMD_TRANSFERSRCW:
{
u32 xferSrc = (gstate.transfersrc & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
u32 xferSrcW = gstate.transfersrcw & 1023;
u32 xferSrcW = data & 0x3FF;
if (data & ~0xFF03FF)
sprintf(buffer, "Block transfer src: %08x W: %i (extra %x)", xferSrc, xferSrcW, data);
else
@ -456,14 +459,17 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
case GE_CMD_TRANSFERDST:
{
// Nothing to do, the next one prints
sprintf(buffer, "Block transfer dst: %06x", data);
if (data & 0xF)
sprintf(buffer, "Block transfer dst: %06x (extra: %x)", data & ~0xF, data & 0xF);
else
sprintf(buffer, "Block transfer dst: %06x", data);
}
break;
case GE_CMD_TRANSFERDSTW:
{
u32 xferDst = (gstate.transferdst & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
u32 xferDstW = gstate.transferdstw & 1023;
u32 xferDstW = data & 0x3FF;
if (data & ~0xFF03FF)
sprintf(buffer, "Block transfer dest: %08x W: %i (extra %x)", xferDst, xferDstW, data);
else
@ -505,10 +511,10 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
}
case GE_CMD_TRANSFERSTART: // Orphis calls this TRXKICK
if (data)
sprintf(buffer, "Block transfer start: %x", data);
if (data & ~1)
sprintf(buffer, "Block transfer start: %d (extra %x)", data & 1, data & ~1);
else
sprintf(buffer, "Block transfer start");
sprintf(buffer, "Block transfer start: %d", data);
break;
case GE_CMD_TEXSIZE0:

View file

@ -265,7 +265,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_LOADCLUT:
// This could be used to "dirty" textures with clut.
{
u32 clutAddr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
u32 clutAddr = gstate.getClutAddress();
if (clutAddr)
{
DEBUG_LOG(G3D,"DL Clut load: %08x", clutAddr);
@ -282,8 +282,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_TRANSFERSRCW:
{
u32 xferSrc = gstate.transfersrc | ((data&0xFF0000)<<8);
u32 xferSrcW = gstate.transfersrcw & 1023;
u32 xferSrc = (gstate.transfersrc & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
u32 xferSrcW = data & 0x3FF;
DEBUG_LOG(G3D,"Block Transfer Src: %08x W: %i", xferSrc, xferSrcW);
break;
}
@ -291,8 +291,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_TRANSFERDSTW:
{
u32 xferDst= gstate.transferdst | ((data&0xFF0000)<<8);
u32 xferDstW = gstate.transferdstw & 1023;
u32 xferDst = (gstate.transferdst & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
u32 xferDstW = data & 0x3FF;
DEBUG_LOG(G3D,"Block Transfer Dest: %08x W: %i", xferDst, xferDstW);
break;
}

View file

@ -46,7 +46,7 @@ static inline int orient2dIncY(int dX01)
static inline int GetPixelDataOffset(unsigned int texel_size_bits, unsigned int row_pitch_bits, unsigned int u, unsigned int v)
{
if (!(gstate.texmode & 1))
if (!gstate.isTextureSwizzled())
return v * row_pitch_bits *texel_size_bits/8 / 8 + u * texel_size_bits / 8;
int tile_size_bits = 32;
@ -90,13 +90,6 @@ static inline u32 LookupColor(unsigned int index, unsigned int level)
}
}
static inline u32 GetClutIndex(u32 index) {
const u32 clutBase = gstate.getClutIndexStartPos();
const u32 clutMask = gstate.getClutIndexMask();
const u8 clutShift = gstate.getClutIndexShift();
return ((index >> clutShift) & clutMask) | clutBase;
}
static inline void GetTexelCoordinates(int level, float s, float t, unsigned int& u, unsigned int& v)
{
s *= getFloat24(gstate.texscaleu);
@ -185,25 +178,25 @@ static inline u32 SampleNearest(int level, unsigned int u, unsigned int v)
u32 val = srcptr[0] + (srcptr[1] << 8) + (srcptr[2] << 16) + (srcptr[3] << 24);
return LookupColor(GetClutIndex(val), level);
return LookupColor(gstate.transformClutIndex(val), level);
} else if (texfmt == GE_TFMT_CLUT16) {
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
u16 val = srcptr[0] + (srcptr[1] << 8);
return LookupColor(GetClutIndex(val), level);
return LookupColor(gstate.transformClutIndex(val), level);
} else if (texfmt == GE_TFMT_CLUT8) {
srcptr += GetPixelDataOffset(8, texbufwidth*8, u, v);
u8 val = *srcptr;
return LookupColor(GetClutIndex(val), level);
return LookupColor(gstate.transformClutIndex(val), level);
} else if (texfmt == GE_TFMT_CLUT4) {
srcptr += GetPixelDataOffset(4, texbufwidth*8, u, v);
u8 val = (u & 1) ? (srcptr[0] >> 4) : (srcptr[0] & 0xF);
return LookupColor(GetClutIndex(val), level);
return LookupColor(gstate.transformClutIndex(val), level);
} else {
ERROR_LOG(G3D, "Unsupported texture format: %x", texfmt);
return 0;
@ -404,7 +397,7 @@ static inline Vec4<int> GetTextureFunctionOutput(const Vec3<int>& prim_color_rgb
Vec3<int> out_rgb;
int out_a;
bool rgba = (gstate.texfunc & 0x100) != 0;
bool rgba = gstate.isTextureAlphaUsed();
switch (gstate.getTextureFunction()) {
case GE_TEXFUNC_MODULATE:
@ -452,10 +445,10 @@ static inline Vec4<int> GetTextureFunctionOutput(const Vec3<int>& prim_color_rgb
static inline bool ColorTestPassed(Vec3<int> color)
{
u32 mask = gstate.colormask&0xFFFFFF;
color = Vec3<int>::FromRGB(color.ToRGB() & mask);
Vec3<int> ref = Vec3<int>::FromRGB(gstate.colorref & mask);
switch (gstate.colortest & 0x3) {
const u32 mask = gstate.getColorTestMask();
const u32 c = color.ToRGB() & mask;
const u32 ref = gstate.getColorTestRef() & mask;
switch (gstate.getColorTestFunction()) {
case GE_COMP_NEVER:
return false;
@ -463,21 +456,21 @@ static inline bool ColorTestPassed(Vec3<int> color)
return true;
case GE_COMP_EQUAL:
return (color.r() == ref.r() && color.g() == ref.g() && color.b() == ref.b());
return c == ref;
case GE_COMP_NOTEQUAL:
return (color.r() != ref.r() || color.g() != ref.g() || color.b() != ref.b());
return c != ref;
}
return true;
}
static inline bool AlphaTestPassed(int alpha)
{
u8 mask = (gstate.alphatest >> 16) & 0xFF;
u8 ref = (gstate.alphatest >> 8) & mask;
const u8 mask = gstate.getAlphaTestMask() & 0xFF;
const u8 ref = gstate.getAlphaTestRef() & mask;
alpha &= mask;
switch (gstate.alphatest & 0x7) {
switch (gstate.getAlphaTestFunction()) {
case GE_COMP_NEVER:
return false;
@ -726,7 +719,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
// TODO: Fogging
// TODO: Is that the correct way to interpolate?
// With the (u32), this causes an ICE in some versions of gcc.
// Without the (u32), this causes an ICE in some versions of gcc.
u16 z = (u16)(u32)(((float)v0.screenpos.z * w0 + (float)v1.screenpos.z * w1 + (float)v2.screenpos.z * w2) / (w0+w1+w2));
// Depth range test

View file

@ -363,7 +363,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
break;
}
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.patchprimitive&3, gstate.vertType);
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
DEBUG_LOG(G3D,"DL DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype);
}
break;
@ -528,14 +528,14 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_LOADCLUT:
{
u32 clutAddr = ((gstate.clutaddr & 0xFFFFF0) | ((gstate.clutaddrupper << 8) & 0xFF000000));
u32 clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32;
u32 clutAddr = gstate.getClutAddress();
u32 clutTotalBytes = gstate.getClutLoadBytes();
if (Memory::IsValidAddress(clutAddr)) {
Memory::Memcpy(clut, clutAddr, clutTotalBytes_);
Memory::MemcpyUnchecked(clut, clutAddr, clutTotalBytes);
} else {
// TODO: Does this make any sense?
memset(clut, 0xFF, clutTotalBytes_);
memset(clut, 0xFF, clutTotalBytes);
}
if (clutAddr)
@ -549,67 +549,36 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
}
break;
//case GE_CMD_TRANSFERSRC:
// Don't need to do anything, just state for transferstart.
case GE_CMD_TRANSFERSRC:
case GE_CMD_TRANSFERSRCW:
{
u32 xferSrc = gstate.transfersrc | ((data&0xFF0000)<<8);
u32 xferSrcW = gstate.transfersrcw & 1023;
DEBUG_LOG(G3D,"Block Transfer Src: %08x W: %i", xferSrc, xferSrcW);
break;
}
// case GE_CMD_TRANSFERDST:
case GE_CMD_TRANSFERDST:
case GE_CMD_TRANSFERDSTW:
{
u32 xferDst= gstate.transferdst | ((data&0xFF0000)<<8);
u32 xferDstW = gstate.transferdstw & 1023;
DEBUG_LOG(G3D,"Block Transfer Dest: %08x W: %i", xferDst, xferDstW);
break;
}
case GE_CMD_TRANSFERSRCPOS:
{
u32 x = (data & 1023)+1;
u32 y = ((data>>10) & 1023)+1;
DEBUG_LOG(G3D, "DL Block Transfer Src Rect TL: %i, %i", x, y);
break;
}
case GE_CMD_TRANSFERDSTPOS:
{
u32 x = (data & 1023)+1;
u32 y = ((data>>10) & 1023)+1;
DEBUG_LOG(G3D, "DL Block Transfer Dest Rect TL: %i, %i", x, y);
break;
}
case GE_CMD_TRANSFERSIZE:
{
u32 w = (data & 1023)+1;
u32 h = ((data>>10) & 1023)+1;
DEBUG_LOG(G3D, "DL Block Transfer Rect Size: %i x %i", w, h);
break;
}
break;
case GE_CMD_TRANSFERSTART:
{
u32 srcBasePtr = (gstate.transfersrc & 0xFFFFF0) | ((gstate.transfersrcw & 0xFF0000) << 8);
u32 srcStride = gstate.transfersrcw & 0x3F8;
u32 srcBasePtr = gstate.getTransferSrcAddress();
u32 srcStride = gstate.getTransferSrcStride();
u32 dstBasePtr = (gstate.transferdst & 0xFFFFF0) | ((gstate.transferdstw & 0xFF0000) << 8);
u32 dstStride = gstate.transferdstw & 0x3F8;
u32 dstBasePtr = gstate.getTransferDstAddress();
u32 dstStride = gstate.getTransferDstStride();
int srcX = gstate.transfersrcpos & 0x3FF;
int srcY = (gstate.transfersrcpos >> 10) & 0x3FF;
int srcX = gstate.getTransferSrcX();
int srcY = gstate.getTransferSrcY();
int dstX = gstate.transferdstpos & 0x3FF;
int dstY = (gstate.transferdstpos >> 10) & 0x3FF;
int dstX = gstate.getTransferDstX();
int dstY = gstate.getTransferDstY();
int width = (gstate.transfersize & 0x3FF) + 1;
int height = ((gstate.transfersize >> 10) & 0x3FF) + 1;
int width = gstate.getTransferWidth();
int height = gstate.getTransferHeight();
int bpp = (gstate.transferstart & 1) ? 4 : 2;
int bpp = gstate.getTransferBpp();
DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY);
for (int y = 0; y < height; y++) {
const u8 *src = Memory::GetPointer(srcBasePtr + ((y + srcY) * srcStride + srcX) * bpp);
@ -617,7 +586,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
memcpy(dst, src, width * bpp);
}
DEBUG_LOG(G3D, "DL Texture Transfer Start: PixFormat %i", data);
break;
}

View file

@ -102,7 +102,7 @@ static VertexData ReadVertex(VertexReader& vreader)
float pos[3];
vreader.ReadPos(pos);
if (!gstate.isModeClear() && gstate.textureMapEnable && vreader.hasUV()) {
if (!gstate.isModeClear() && gstate.isTextureMapEnabled() && vreader.hasUV()) {
float uv[2];
vreader.ReadUV(uv);
vertex.texturecoords = Vec2<float>(uv[0], uv[1]);
@ -113,7 +113,7 @@ static VertexData ReadVertex(VertexReader& vreader)
vreader.ReadNrm(normal);
vertex.normal = Vec3<float>(normal[0], normal[1], normal[2]);
if (gstate.reversenormals & 1)
if (gstate.areNormalsReversed())
vertex.normal = -vertex.normal;
}
@ -186,7 +186,7 @@ struct SplinePatch {
int type;
};
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type)
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type)
{
VertexDecoder vdecoder;
vdecoder.SetVertexType(vertex_type);

View file

@ -115,6 +115,6 @@ public:
static DrawingCoords ScreenToDrawing(const ScreenCoords& coords);
static ScreenCoords DrawingToScreen(const DrawingCoords& coords);
static void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type);
static void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type);
static void SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type);
};