diff options
| author | degasus <wickmarkus@web.de> | 2015-10-09 20:50:36 +0200 |
|---|---|---|
| committer | degasus <wickmarkus@web.de> | 2016-01-06 22:10:29 +0100 |
| commit | efbe5bc4b651d1f7f726bb064255e0e2562f7490 (patch) | |
| tree | 6166a471269a9b1eb2bf703a31c915489e428b44 /Source/Core/VideoBackends/Software/SWVertexLoader.cpp | |
| parent | 7fcb5a803b2e6179fe57654496fcea7f6b2ff183 (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.cpp | 168 |
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); -} |
