diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index fbe60c175698..2066defced53 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -26,6 +26,8 @@ #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/Common/ShaderCommon.h" +#include "GPU/GPUCommon.h" + #if PPSSPP_ARCH(ARM) #include "Common/ArmEmitter.h" #elif PPSSPP_ARCH(ARM64) @@ -78,30 +80,6 @@ struct DecVtxFormat { void ComputeID(); }; -struct TransformedVertex -{ - union { - struct { - float x, y, z, fog; // in case of morph, preblend during decode - }; - float pos[4]; - }; - union { - struct { - float u; float v; float w; // scaled by uscale, vscale, if there - }; - float uv[3]; - }; - union { - u8 color0[4]; // prelit - u32 color0_32; - }; - union { - u8 color1[4]; // prelit - u32 color1_32; - }; -}; - void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBound, u16 *indexUpperBound); inline int RoundUp4(int x) { diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 4a836550f183..23d9577725e8 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -303,16 +303,16 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData }, // Vertex Screen/Texture/Color - { GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VSCX }, + { GE_CMD_VSCY }, + { GE_CMD_VSCZ }, + { GE_CMD_VTCS }, + { GE_CMD_VTCT }, + { GE_CMD_VTCQ }, + { GE_CMD_VCV }, + { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_ImmVertexAlphaPrim }, + { GE_CMD_VFC }, + { GE_CMD_VSCV }, // "Missing" commands (gaps in the sequence) { GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, @@ -1808,6 +1808,32 @@ void GPUCommon::Execute_MorphWeight(u32 op, u32 diff) { gstate_c.morphWeights[(op >> 24) - GE_CMD_MORPHWEIGHT0] = getFloat24(op); } +void GPUCommon::Execute_ImmVertexAlphaPrim(u32 op, u32 diff) { + uint32_t data = op & 0xFFFFFF; + TransformedVertex &v = immBuffer_[immCount_++]; + + // Formula deduced from ThrillVille's clear. + int offsetX = gstate.getOffsetX16(); + int offsetY = gstate.getOffsetY16(); + v.x = ((gstate.imm_vscx & 0xFFFFFF) - offsetX) / 16.0f; + v.y = ((gstate.imm_vscy & 0xFFFFFF) - offsetY) / 16.0f; + v.z = gstate.imm_vscz & 0xFFFF; + v.u = 0.0f; // we have no information about the scale here + v.v = 0.0f; // we have no information about the scale here + v.w = 0.0f; // we have no information about the scale here + v.color0_32 = (gstate.imm_cv & 0xFFFFFF) | (gstate.imm_ap << 24); + v.fog = 0.0f; // we have no information about the scale here + v.color1_32 = gstate.imm_scv & 0xFFFFFF; + int prim = (op >> 8) & 0xF; + if (prim != 7) { + immPrim_ = prim; + } else { + // Time to submit! This can go through the software transform path but skipping the actual transform... + // drawEngineCommon_->SubmitImm(immBuffer_, immCount_); + immCount_ = 0; + } +} + void GPUCommon::ExecuteOp(u32 op, u32 diff) { const u32 cmd = op >> 24; diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index c4d22dc904da..41db2a9f3f08 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -39,6 +39,29 @@ enum { FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both! }; +struct TransformedVertex { + union { + struct { + float x, y, z, fog; // in case of morph, preblend during decode + }; + float pos[4]; + }; + union { + struct { + float u; float v; float w; // scaled by uscale, vscale, if there + }; + float uv[3]; + }; + union { + u8 color0[4]; // prelit + u32 color0_32; + }; + union { + u8 color1[4]; // prelit + u32 color1_32; + }; +}; + class GPUCommon : public GPUInterface, public GPUDebugInterface { public: GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw); @@ -124,6 +147,8 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface { void Execute_MorphWeight(u32 op, u32 diff); + void Execute_ImmVertexAlphaPrim(u32 op, u32 diff); + void Execute_Unknown(u32 op, u32 diff); int EstimatePerVertexCost(); @@ -291,6 +316,15 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface { DrawType lastDraw_; GEPrimitiveType lastPrim_; + // No idea how big this buffer needs to be. + enum { + MAX_IMMBUFFER_SIZE = 32, + }; + + TransformedVertex immBuffer_[MAX_IMMBUFFER_SIZE]; + int immCount_ = 0; + int immPrim_ = 0; + private: // Debug stats. double timeSteppingStarted_; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a78aa10307e2..cd41c10a76d1 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -185,8 +185,18 @@ struct GPUgstate { transfersrcpos, transferdstpos, pad99, - transfersize; // 0xEE - + transfersize, // 0xEE + pad100, // 0xEF + imm_vscx, // 0xF0 + imm_vscy, + imm_vscz, + imm_vtcs, + imm_vtct, + imm_vtcq, + imm_cv, + imm_ap, + imm_fc, + imm_scv; u32 pad05[0xFF- 0xEE]; }; };