From 39d439fc48ef44d0a28113a10cb796cd8989f944 Mon Sep 17 00:00:00 2001 From: magumagu Date: Thu, 8 May 2014 16:53:18 -0700 Subject: [PATCH 1/2] Opcode decoding: handle missing opcodes 0x88 etc. Hardware testing shows that they do the same thing as the 0x80 family of opcodes: they draw quads. --- .../VideoBackends/Software/OpcodeDecoder.h | 5 +++- .../Core/VideoBackends/Software/SetupUnit.cpp | 1 + Source/Core/VideoCommon/IndexGenerator.cpp | 26 ++++++++++--------- Source/Core/VideoCommon/OpcodeDecoding.h | 6 +++-- Source/Core/VideoCommon/VertexManagerBase.cpp | 4 ++- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoBackends/Software/OpcodeDecoder.h b/Source/Core/VideoBackends/Software/OpcodeDecoder.h index 3d33b18d40..bec71af23f 100644 --- a/Source/Core/VideoBackends/Software/OpcodeDecoder.h +++ b/Source/Core/VideoBackends/Software/OpcodeDecoder.h @@ -27,8 +27,11 @@ namespace OpcodeDecoder #define GX_PRIMITIVE_SHIFT 3 #define GX_VAT_MASK 0x07 - //these are defined 1/8th of their real values and without their top bit + // These values are the values extracted using GX_PRIMITIVE_MASK + // and GX_PRIMITIVE_SHIFT. + // GX_DRAW_QUADS_2 behaves the same way as GX_DRAW_QUADS. #define GX_DRAW_QUADS 0x0 //0x80 + #define GX_DRAW_QUADS_2 0x1 //0x88 #define GX_DRAW_TRIANGLES 0x2 //0x90 #define GX_DRAW_TRIANGLE_STRIP 0x3 //0x98 #define GX_DRAW_TRIANGLE_FAN 0x4 //0xA0 diff --git a/Source/Core/VideoBackends/Software/SetupUnit.cpp b/Source/Core/VideoBackends/Software/SetupUnit.cpp index 560e1d4863..da62490c50 100644 --- a/Source/Core/VideoBackends/Software/SetupUnit.cpp +++ b/Source/Core/VideoBackends/Software/SetupUnit.cpp @@ -25,6 +25,7 @@ void SetupUnit::SetupVertex() switch (m_PrimType) { case GX_DRAW_QUADS: + case GX_DRAW_QUADS_2: SetupQuad(); break; case GX_DRAW_TRIANGLES: diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index 949ee342b1..f9838a1daa 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -6,6 +6,7 @@ #include "Common/Common.h" #include "VideoCommon/IndexGenerator.h" +#include "VideoCommon/OpcodeDecoding.h" #include "VideoCommon/VideoConfig.h" //Init @@ -21,22 +22,23 @@ void IndexGenerator::Init() { if (g_Config.backend_info.bSupportsPrimitiveRestart) { - primitive_table[0] = IndexGenerator::AddQuads; - primitive_table[2] = IndexGenerator::AddList; - primitive_table[3] = IndexGenerator::AddStrip; - primitive_table[4] = IndexGenerator::AddFan; + primitive_table[GX_DRAW_QUADS] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_TRIANGLES] = IndexGenerator::AddList; + primitive_table[GX_DRAW_TRIANGLE_STRIP] = IndexGenerator::AddStrip; + primitive_table[GX_DRAW_TRIANGLE_FAN] = IndexGenerator::AddFan; } else { - primitive_table[0] = IndexGenerator::AddQuads; - primitive_table[2] = IndexGenerator::AddList; - primitive_table[3] = IndexGenerator::AddStrip; - primitive_table[4] = IndexGenerator::AddFan; + primitive_table[GX_DRAW_QUADS] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_TRIANGLES] = IndexGenerator::AddList; + primitive_table[GX_DRAW_TRIANGLE_STRIP] = IndexGenerator::AddStrip; + primitive_table[GX_DRAW_TRIANGLE_FAN] = IndexGenerator::AddFan; } - primitive_table[1] = nullptr; - primitive_table[5] = &IndexGenerator::AddLineList; - primitive_table[6] = &IndexGenerator::AddLineStrip; - primitive_table[7] = &IndexGenerator::AddPoints; + primitive_table[GX_DRAW_LINES] = &IndexGenerator::AddLineList; + primitive_table[GX_DRAW_LINE_STRIP] = &IndexGenerator::AddLineStrip; + primitive_table[GX_DRAW_POINTS] = &IndexGenerator::AddPoints; } void IndexGenerator::Start(u16* Indexptr) diff --git a/Source/Core/VideoCommon/OpcodeDecoding.h b/Source/Core/VideoCommon/OpcodeDecoding.h index bdc4976825..baf44bd40f 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.h +++ b/Source/Core/VideoCommon/OpcodeDecoding.h @@ -22,15 +22,17 @@ #define GX_PRIMITIVE_SHIFT 3 #define GX_VAT_MASK 0x07 -//these are defined 1/8th of their real values and without their top bit +// These values are the values extracted using GX_PRIMITIVE_MASK +// and GX_PRIMITIVE_SHIFT. +// GX_DRAW_QUADS_2 behaves the same way as GX_DRAW_QUADS. #define GX_DRAW_QUADS 0x0 // 0x80 +#define GX_DRAW_QUADS_2 0x1 // 0x88 #define GX_DRAW_TRIANGLES 0x2 // 0x90 #define GX_DRAW_TRIANGLE_STRIP 0x3 // 0x98 #define GX_DRAW_TRIANGLE_FAN 0x4 // 0xA0 #define GX_DRAW_LINES 0x5 // 0xA8 #define GX_DRAW_LINE_STRIP 0x6 // 0xB0 #define GX_DRAW_POINTS 0x7 // 0xB8 -#define GX_DRAW_NONE 0x1; // This is a fake value to used in the backends extern bool g_bRecordFifoData; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 624631b805..29feabef4b 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -28,7 +28,7 @@ bool VertexManager::IsFlushed; static const PrimitiveType primitive_from_gx[8] = { PRIMITIVE_TRIANGLES, // GX_DRAW_QUADS - PRIMITIVE_TRIANGLES, // GX_DRAW_NONE + PRIMITIVE_TRIANGLES, // GX_DRAW_QUADS_2 PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLES PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLE_STRIP PRIMITIVE_TRIANGLES, // GX_DRAW_TRIANGLE_FAN @@ -93,6 +93,7 @@ u32 VertexManager::GetRemainingIndices(int primitive) switch (primitive) { case GX_DRAW_QUADS: + case GX_DRAW_QUADS_2: return index_len / 5 * 4; case GX_DRAW_TRIANGLES: return index_len / 4 * 3; @@ -118,6 +119,7 @@ u32 VertexManager::GetRemainingIndices(int primitive) switch (primitive) { case GX_DRAW_QUADS: + case GX_DRAW_QUADS_2: return index_len / 6 * 4; case GX_DRAW_TRIANGLES: return index_len; From 9b82d720705c8e6fd34c336a92dde5a8b10471b9 Mon Sep 17 00:00:00 2001 From: magumagu Date: Sat, 17 May 2014 11:55:32 -0700 Subject: [PATCH 2/2] Video backends: warn on usage of GL_DRAW_QUADS_2. It's not normally used, so if it shows up, it could indicate a CPU emulation bug. --- Source/Core/VideoBackends/Software/SetupUnit.cpp | 3 +++ Source/Core/VideoCommon/IndexGenerator.cpp | 10 ++++++++-- Source/Core/VideoCommon/IndexGenerator.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoBackends/Software/SetupUnit.cpp b/Source/Core/VideoBackends/Software/SetupUnit.cpp index da62490c50..171350db60 100644 --- a/Source/Core/VideoBackends/Software/SetupUnit.cpp +++ b/Source/Core/VideoBackends/Software/SetupUnit.cpp @@ -25,7 +25,10 @@ void SetupUnit::SetupVertex() switch (m_PrimType) { case GX_DRAW_QUADS: + SetupQuad(); + break; case GX_DRAW_QUADS_2: + WARN_LOG(VIDEO, "Non-standard primitive drawing command GL_DRAW_QUADS_2"); SetupQuad(); break; case GX_DRAW_TRIANGLES: diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index f9838a1daa..1e713185a5 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -23,7 +23,7 @@ void IndexGenerator::Init() if (g_Config.backend_info.bSupportsPrimitiveRestart) { primitive_table[GX_DRAW_QUADS] = IndexGenerator::AddQuads; - primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads_nonstandard; primitive_table[GX_DRAW_TRIANGLES] = IndexGenerator::AddList; primitive_table[GX_DRAW_TRIANGLE_STRIP] = IndexGenerator::AddStrip; primitive_table[GX_DRAW_TRIANGLE_FAN] = IndexGenerator::AddFan; @@ -31,7 +31,7 @@ void IndexGenerator::Init() else { primitive_table[GX_DRAW_QUADS] = IndexGenerator::AddQuads; - primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads; + primitive_table[GX_DRAW_QUADS_2] = IndexGenerator::AddQuads_nonstandard; primitive_table[GX_DRAW_TRIANGLES] = IndexGenerator::AddList; primitive_table[GX_DRAW_TRIANGLE_STRIP] = IndexGenerator::AddStrip; primitive_table[GX_DRAW_TRIANGLE_FAN] = IndexGenerator::AddFan; @@ -198,6 +198,12 @@ template u16* IndexGenerator::AddQuads(u16 *Iptr, u32 numVerts, u32 in return Iptr; } +template u16* IndexGenerator::AddQuads_nonstandard(u16 *Iptr, u32 numVerts, u32 index) +{ + WARN_LOG(VIDEO, "Non-standard primitive drawing command GL_DRAW_QUADS_2"); + return AddQuads(Iptr, numVerts, index); +} + // Lines u16* IndexGenerator::AddLineList(u16 *Iptr, u32 numVerts, u32 index) { diff --git a/Source/Core/VideoCommon/IndexGenerator.h b/Source/Core/VideoCommon/IndexGenerator.h index e5d09c8d96..c15ef75829 100644 --- a/Source/Core/VideoCommon/IndexGenerator.h +++ b/Source/Core/VideoCommon/IndexGenerator.h @@ -31,6 +31,7 @@ private: template static u16* AddStrip(u16 *Iptr, u32 numVerts, u32 index); template static u16* AddFan(u16 *Iptr, u32 numVerts, u32 index); template static u16* AddQuads(u16 *Iptr, u32 numVerts, u32 index); + template static u16* AddQuads_nonstandard(u16 *Iptr, u32 numVerts, u32 index); // Lines static u16* AddLineList(u16 *Iptr, u32 numVerts, u32 index);