diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 8af1994c49..6d7f7a8e02 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -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(gstate.framebufpixformat & 3); + GEBufferFormat fmt = gstate.FrameBufFormat(); int drawing_width, drawing_height; GuessDrawingSize(drawing_width, drawing_height); diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index 2f9391eecb..75c7da9b6b 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -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); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 37b5b7d0a8..e6bc95f768 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -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; diff --git a/GPU/GLES/Spline.cpp b/GPU/GLES/Spline.cpp index 83c1614072..4bc1c9b053 100644 --- a/GPU/GLES/Spline.cpp +++ b/GPU/GLES/Spline.cpp @@ -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(); diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 54ec9358eb..37ddbe6bfc 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -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(); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 3a7b55ab4c..7c36755c33 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -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(); - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { switch (bytesPerIndex) { case 1: DeIndexTexture(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(); - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { switch (bytesPerIndex) { case 1: DeIndexTexture(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() + 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() + 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); diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index cac49d7f9d..de3e423aca 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -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 diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 7fea4f640d..f80c25bf2c 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -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) { diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index e912b19b11..d28a41db0e 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -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); diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index d7b155046c..9fb597b68c 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -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(); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index d2b5f2bd75..de6ab4d1a5 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -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); } } diff --git a/GPU/GPUState.h b/GPU/GPUState.h index f63424d31a..e061eeaf0a 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -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(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(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 }; diff --git a/GPU/GeDisasm.cpp b/GPU/GeDisasm.cpp index e7e34f7864..8c4b92aeeb 100644 --- a/GPU/GeDisasm.cpp +++ b/GPU/GeDisasm.cpp @@ -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: diff --git a/GPU/Null/NullGpu.cpp b/GPU/Null/NullGpu.cpp index 3543ad37b1..58c02dbe66 100644 --- a/GPU/Null/NullGpu.cpp +++ b/GPU/Null/NullGpu.cpp @@ -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; } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 7693957c98..4bb22d9a07 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -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 GetTextureFunctionOutput(const Vec3& prim_color_rgb Vec3 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 GetTextureFunctionOutput(const Vec3& prim_color_rgb static inline bool ColorTestPassed(Vec3 color) { - u32 mask = gstate.colormask&0xFFFFFF; - color = Vec3::FromRGB(color.ToRGB() & mask); - Vec3 ref = Vec3::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 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 diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 756fbad877..9c89a31e26 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -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; } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index b76d8fc10c..8069bba8fe 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -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(uv[0], uv[1]); @@ -113,7 +113,7 @@ static VertexData ReadVertex(VertexReader& vreader) vreader.ReadNrm(normal); vertex.normal = Vec3(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); diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index 32ee05ee40..b36cfb49c0 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -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); };