summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-10-09 20:50:36 +0200
committerdegasus <wickmarkus@web.de>2016-01-06 22:10:29 +0100
commitefbe5bc4b651d1f7f726bb064255e0e2562f7490 (patch)
tree6166a471269a9b1eb2bf703a31c915489e428b44 /Source/Core/VideoBackends/Software/SWVertexLoader.cpp
parent7fcb5a803b2e6179fe57654496fcea7f6b2ff183 (diff)
VideoSW: Use more VideoCommon
Now we require lots of empty functions, but this removes by far more duplicated code.
Diffstat (limited to 'Source/Core/VideoBackends/Software/SWVertexLoader.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/SWVertexLoader.cpp168
1 files changed, 100 insertions, 68 deletions
diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
index bda8714f00..86855db446 100644
--- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
+++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
@@ -7,22 +7,40 @@
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
-#include "VideoBackends/Software/CPMemLoader.h"
+#include "VideoBackends/Software/Clipper.h"
+#include "VideoBackends/Software/DebugUtil.h"
#include "VideoBackends/Software/NativeVertexFormat.h"
+#include "VideoBackends/Software/Rasterizer.h"
#include "VideoBackends/Software/SetupUnit.h"
-#include "VideoBackends/Software/SWStatistics.h"
#include "VideoBackends/Software/SWVertexLoader.h"
+#include "VideoBackends/Software/Tev.h"
#include "VideoBackends/Software/TransformUnit.h"
-#include "VideoBackends/Software/XFMemLoader.h"
+#include "VideoCommon/IndexGenerator.h"
+#include "VideoCommon/OpcodeDecoding.h"
+#include "VideoCommon/PixelShaderManager.h"
+#include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexLoaderBase.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexLoaderUtils.h"
+#include "VideoCommon/XFMemory.h"
+class NullNativeVertexFormat : public NativeVertexFormat
+{
+public:
+ NullNativeVertexFormat(const PortableVertexDeclaration& _vtx_decl) { vtx_decl = _vtx_decl; }
+ void SetupVertexPointers() override {}
+};
+
+NativeVertexFormat* SWVertexLoader::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
+{
+ return new NullNativeVertexFormat(vtx_decl);
+}
-SWVertexLoader::SWVertexLoader() :
- m_VertexSize(0)
+SWVertexLoader::SWVertexLoader()
{
+ LocalVBuffer.resize(MAXVBUFFERSIZE);
+ LocalIBuffer.resize(MAXIBUFFERSIZE);
m_SetupUnit = new SetupUnit;
}
@@ -32,25 +50,89 @@ SWVertexLoader::~SWVertexLoader()
m_SetupUnit = nullptr;
}
-void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
+void SWVertexLoader::ResetBuffer(u32 stride)
{
- memset(&m_Vertex, 0, sizeof(m_Vertex));
+ s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer.data();
+ s_pEndBufferPointer = s_pCurBufferPointer + LocalVBuffer.size();
+ IndexGenerator::Start(GetIndexBuffer());
+}
- m_attributeIndex = attributeIndex;
+void SWVertexLoader::vFlush(bool useDstAlpha)
+{
+ DebugUtil::OnObjectBegin();
- VertexLoaderUID uid(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]);
- m_CurrentLoader = m_VertexLoaderMap[uid].get();
+ u8 primitiveType = 0;
+ switch (current_primitive_type)
+ {
+ case PRIMITIVE_POINTS:
+ primitiveType = GX_DRAW_POINTS;
+ break;
+ case PRIMITIVE_LINES:
+ primitiveType = GX_DRAW_LINES;
+ break;
+ case PRIMITIVE_TRIANGLES:
+ primitiveType = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? GX_DRAW_TRIANGLE_STRIP : GX_DRAW_TRIANGLES;
+ break;
+ }
+
+ m_SetupUnit->Init(primitiveType);
- if (!m_CurrentLoader)
+ // set all states with are stored within video sw
+ Clipper::SetViewOffset();
+ Rasterizer::SetScissor();
+ for (int i = 0; i < 4; i++)
{
- m_VertexLoaderMap[uid] = VertexLoaderBase::CreateVertexLoader(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]);
- m_CurrentLoader = m_VertexLoaderMap[uid].get();
+ Rasterizer::SetTevReg(i, Tev::RED_C, false, PixelShaderManager::constants.colors[i][0]);
+ Rasterizer::SetTevReg(i, Tev::GRN_C, false, PixelShaderManager::constants.colors[i][1]);
+ Rasterizer::SetTevReg(i, Tev::BLU_C, false, PixelShaderManager::constants.colors[i][2]);
+ Rasterizer::SetTevReg(i, Tev::ALP_C, false, PixelShaderManager::constants.colors[i][3]);
+ Rasterizer::SetTevReg(i, Tev::RED_C, true, PixelShaderManager::constants.kcolors[i][0]);
+ Rasterizer::SetTevReg(i, Tev::GRN_C, true, PixelShaderManager::constants.kcolors[i][1]);
+ Rasterizer::SetTevReg(i, Tev::BLU_C, true, PixelShaderManager::constants.kcolors[i][2]);
+ Rasterizer::SetTevReg(i, Tev::ALP_C, true, PixelShaderManager::constants.kcolors[i][3]);
}
- m_VertexSize = m_CurrentLoader->m_VertexSize;
- m_CurrentVat = &g_main_cp_state.vtx_attr[m_attributeIndex];
+ for (u32 i = 0; i < IndexGenerator::GetIndexLen(); i++)
+ {
+ u16 index = LocalIBuffer[i];
+
+ if (index == 0xffff)
+ {
+ // primitive restart
+ m_SetupUnit->Init(primitiveType);
+ continue;
+ }
+ memset(&m_Vertex, 0, sizeof(m_Vertex));
+
+ // Super Mario Sunshine requires those to be zero for those debug boxes.
+ memset(&m_Vertex.color, 0, sizeof(m_Vertex.color));
+
+ // parse the videocommon format to our own struct format (m_Vertex)
+ SetFormat(g_main_cp_state.last_id, primitiveType);
+ ParseVertex(VertexLoaderManager::GetCurrentVertexFormat()->GetVertexDeclaration(), index);
+
+ // transform this vertex so that it can be used for rasterization (outVertex)
+ OutputVertexData* outVertex = m_SetupUnit->GetVertex();
+ TransformUnit::TransformPosition(&m_Vertex, outVertex);
+ memset(&outVertex->normal, 0, sizeof(outVertex->normal));
+ if (VertexLoaderManager::g_current_components & VB_HAS_NRM0)
+ {
+ TransformUnit::TransformNormal(&m_Vertex, (VertexLoaderManager::g_current_components & VB_HAS_NRM2) != 0, outVertex);
+ }
+ TransformUnit::TransformColor(&m_Vertex, outVertex);
+ TransformUnit::TransformTexCoord(&m_Vertex, outVertex, m_TexGenSpecialCase);
+
+ // assemble and rasterize the primitive
+ m_SetupUnit->SetupVertex();
+
+ INCSTAT(stats.thisFrame.numVerticesLoaded)
+ }
+ DebugUtil::OnObjectEnd();
+}
+void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
+{
// matrix index from xf regs or cp memory?
if (xfmem.MatrixIndexA.PosNormalMtxIdx != g_main_cp_state.matrix_index_a.PosNormalMtxIdx ||
xfmem.MatrixIndexA.Tex0MtxIdx != g_main_cp_state.matrix_index_a.Tex0MtxIdx ||
@@ -81,8 +163,6 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
((g_main_cp_state.vtx_desc.Hex & 0x60600L) == g_main_cp_state.vtx_desc.Hex) && // only pos and tex coord 0
(g_main_cp_state.vtx_desc.Tex0Coord != NOT_PRESENT) &&
(xfmem.texMtxInfo[0].projection == XF_TEXPROJ_ST);
-
- m_SetupUnit->Init(primitiveType);
}
template <typename T, typename I>
@@ -138,9 +218,10 @@ static void ReadVertexAttribute(T* dst, DataReader src, const AttributeFormat& f
}
}
-void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec)
+void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec, int index)
{
- DataReader src(m_LoadedVertices.data(), m_LoadedVertices.data() + m_LoadedVertices.size());
+ DataReader src(LocalVBuffer.data(), LocalVBuffer.data() + LocalVBuffer.size());
+ src.Skip(index * vdec.stride);
ReadVertexAttribute<float>(&m_Vertex.position[0], src, vdec.position, 0, 3, false);
@@ -167,52 +248,3 @@ void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec)
ReadVertexAttribute<u8>(&m_Vertex.posMtx, src, vdec.posmtx, 0, 1, false);
}
-
-void SWVertexLoader::LoadVertex()
-{
- const PortableVertexDeclaration& vdec = m_CurrentLoader->m_native_vtx_decl;
-
- // reserve memory for the destination of the vertex loader
- m_LoadedVertices.resize(vdec.stride + 4);
-
- VertexLoaderManager::UpdateVertexArrayPointers();
-
- // convert the vertex from the gc format to the videocommon (hardware optimized) format
- u8* old = g_video_buffer_read_ptr;
- int converted_vertices = m_CurrentLoader->RunVertices(
- DataReader(g_video_buffer_read_ptr, nullptr), // src
- DataReader(m_LoadedVertices.data(), m_LoadedVertices.data() + m_LoadedVertices.size()), // dst
- 1 // vertices
- );
- g_video_buffer_read_ptr = old + m_CurrentLoader->m_VertexSize;
-
- if (converted_vertices == 0)
- return;
-
- // parse the videocommon format to our own struct format (m_Vertex)
- ParseVertex(vdec);
-
- // transform this vertex so that it can be used for rasterization (outVertex)
- OutputVertexData* outVertex = m_SetupUnit->GetVertex();
- TransformUnit::TransformPosition(&m_Vertex, outVertex);
- memset(&outVertex->normal, 0, sizeof(outVertex->normal));
- if (g_main_cp_state.vtx_desc.Normal != NOT_PRESENT)
- {
- TransformUnit::TransformNormal(&m_Vertex, m_CurrentVat->g0.NormalElements, outVertex);
- }
- TransformUnit::TransformColor(&m_Vertex, outVertex);
- TransformUnit::TransformTexCoord(&m_Vertex, outVertex, m_TexGenSpecialCase);
-
- // assemble and rasterize the primitive
- m_SetupUnit->SetupVertex();
-
- INCSTAT(swstats.thisFrame.numVerticesLoaded)
-}
-
-void SWVertexLoader::DoState(PointerWrap &p)
-{
- p.Do(m_VertexSize);
- p.Do(*m_CurrentVat);
- m_SetupUnit->DoState(p);
- p.Do(m_TexGenSpecialCase);
-}