diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index af344c344c..a03f8cd61d 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -43,7 +43,6 @@ #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/Statistics.h" -#include "VideoCommon/VertexLoader.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VertexShaderManager.h" diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index 8642d78cc1..6969b97ba4 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -74,7 +74,6 @@ Make AA apply instantly during gameplay if possible #include "VideoCommon/OpcodeDecoding.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" -#include "VideoCommon/VertexLoader.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoConfig.h" diff --git a/Source/Core/VideoBackends/Software/NativeVertexFormat.h b/Source/Core/VideoBackends/Software/NativeVertexFormat.h index ad71e2caf9..c4f140cac4 100644 --- a/Source/Core/VideoBackends/Software/NativeVertexFormat.h +++ b/Source/Core/VideoBackends/Software/NativeVertexFormat.h @@ -7,14 +7,6 @@ #include "Common/ChunkFile.h" #include "VideoBackends/Software/Vec3.h" -#ifdef WIN32 -#define LOADERDECL __cdecl -#else -#define LOADERDECL -#endif - -typedef void (LOADERDECL *TPipelineFunction)(); - struct Vec4 { float x; diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index fecfb94abe..2523b5b01a 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -13,12 +13,8 @@ #include "VideoBackends/Software/TransformUnit.h" #include "VideoBackends/Software/XFMemLoader.h" -#include "VideoCommon/VertexLoader.h" -#include "VideoCommon/VertexLoader_Color.h" -#include "VideoCommon/VertexLoader_Normal.h" -#include "VideoCommon/VertexLoader_Position.h" -#include "VideoCommon/VertexLoader_TextCoord.h" -#include "VideoCommon/VertexManagerBase.h" +#include "VideoCommon/VertexLoaderBase.h" +#include "VideoCommon/VertexLoaderUtils.h" SWVertexLoader::SWVertexLoader() : m_VertexSize(0) @@ -42,8 +38,8 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) if (!m_CurrentLoader) { - m_CurrentLoader = new VertexLoader(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]); - m_VertexLoaderMap[uid] = std::unique_ptr(m_CurrentLoader); + m_CurrentLoader = VertexLoaderBase::CreateVertexLoader(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[m_attributeIndex]); + m_VertexLoaderMap[uid] = std::unique_ptr(m_CurrentLoader); } m_VertexSize = m_CurrentLoader->m_VertexSize; diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.h b/Source/Core/VideoBackends/Software/SWVertexLoader.h index fe4e5347ba..890d1fa52d 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.h +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.h @@ -9,7 +9,7 @@ #include "VideoBackends/Software/CPMemLoader.h" #include "VideoBackends/Software/NativeVertexFormat.h" -#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderBase.h" class PointerWrap; class SetupUnit; @@ -28,9 +28,9 @@ class SWVertexLoader bool m_TexGenSpecialCase; - std::unordered_map> m_VertexLoaderMap; + std::unordered_map> m_VertexLoaderMap; std::vector m_LoadedVertices; - VertexLoader* m_CurrentLoader; + VertexLoaderBase* m_CurrentLoader; u8 m_attributeIndex; u8 m_primitiveType; diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 6c4ad70331..44f6964cfb 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -21,7 +21,6 @@ #include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/TextureDecoder.h" -#include "VideoCommon/VertexLoader.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 95ebaf7433..a450a8e379 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -28,6 +28,7 @@ set(SRCS BoundingBox.cpp TextureConversionShader.cpp TextureDecoder_Common.cpp VertexLoader.cpp + VertexLoaderBase.cpp VertexLoaderManager.cpp VertexLoader_Color.cpp VertexLoader_Normal.cpp diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h index d61fbb02c4..e348f7f38d 100644 --- a/Source/Core/VideoCommon/CPMemory.h +++ b/Source/Core/VideoCommon/CPMemory.h @@ -232,7 +232,7 @@ struct VAT UVAT_group2 g2; }; -class VertexLoader; +class VertexLoaderBase; // STATE_TO_SAVE struct CPState final @@ -247,7 +247,7 @@ struct CPState final // Attributes that actually belong to VertexLoaderManager: BitSet32 attr_dirty; - VertexLoader* vertex_loaders[8]; + VertexLoaderBase* vertex_loaders[8]; }; class PointerWrap; diff --git a/Source/Core/VideoCommon/NativeVertexFormat.h b/Source/Core/VideoCommon/NativeVertexFormat.h index 612f671f5d..024f4f070d 100644 --- a/Source/Core/VideoCommon/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/NativeVertexFormat.h @@ -44,14 +44,6 @@ enum VB_HAS_UVTEXMTXSHIFT=13, }; -#ifdef WIN32 -#define LOADERDECL __cdecl -#else -#define LOADERDECL -#endif - -typedef void (LOADERDECL *TPipelineFunction)(); - enum VarType { VAR_UNSIGNED_BYTE, // GX_U8 = 0 diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index ddf5097986..32cb95607b 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -4,7 +4,6 @@ #include "Common/CommonTypes.h" #include "Common/MemoryUtil.h" -#include "Common/StringUtil.h" #include "Common/x64ABI.h" #include "Common/x64Emitter.h" @@ -109,19 +108,13 @@ static void LOADERDECL TexMtx_Write_Float4() } VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) +: VertexLoaderBase(vtx_desc, vtx_attr) { m_compiledCode = nullptr; - m_numLoadedVertices = 0; - m_VertexSize = 0; - m_native_vertex_format = nullptr; VertexLoader_Normal::Init(); VertexLoader_Position::Init(); VertexLoader_TextCoord::Init(); - m_VtxDesc = vtx_desc; - m_vat = vtx_attr; - SetVAT(vtx_attr); - #ifdef USE_VERTEX_LOADER_JIT AllocCodeSpace(COMPILED_CODE_SIZE); CompileVertexTranslator(); @@ -130,7 +123,6 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) m_numPipelineStages = 0; CompileVertexTranslator(); #endif - } VertexLoader::~VertexLoader() @@ -489,105 +481,3 @@ int VertexLoader::RunVertices(int primitive, int count, DataReader src, DataRead ConvertVertices(count); return count; } - -void VertexLoader::SetVAT(const VAT& vat) -{ - m_VtxAttr.PosElements = vat.g0.PosElements; - m_VtxAttr.PosFormat = vat.g0.PosFormat; - m_VtxAttr.PosFrac = vat.g0.PosFrac; - m_VtxAttr.NormalElements = vat.g0.NormalElements; - m_VtxAttr.NormalFormat = vat.g0.NormalFormat; - m_VtxAttr.color[0].Elements = vat.g0.Color0Elements; - m_VtxAttr.color[0].Comp = vat.g0.Color0Comp; - m_VtxAttr.color[1].Elements = vat.g0.Color1Elements; - m_VtxAttr.color[1].Comp = vat.g0.Color1Comp; - m_VtxAttr.texCoord[0].Elements = vat.g0.Tex0CoordElements; - m_VtxAttr.texCoord[0].Format = vat.g0.Tex0CoordFormat; - m_VtxAttr.texCoord[0].Frac = vat.g0.Tex0Frac; - m_VtxAttr.ByteDequant = vat.g0.ByteDequant; - m_VtxAttr.NormalIndex3 = vat.g0.NormalIndex3; - - m_VtxAttr.texCoord[1].Elements = vat.g1.Tex1CoordElements; - m_VtxAttr.texCoord[1].Format = vat.g1.Tex1CoordFormat; - m_VtxAttr.texCoord[1].Frac = vat.g1.Tex1Frac; - m_VtxAttr.texCoord[2].Elements = vat.g1.Tex2CoordElements; - m_VtxAttr.texCoord[2].Format = vat.g1.Tex2CoordFormat; - m_VtxAttr.texCoord[2].Frac = vat.g1.Tex2Frac; - m_VtxAttr.texCoord[3].Elements = vat.g1.Tex3CoordElements; - m_VtxAttr.texCoord[3].Format = vat.g1.Tex3CoordFormat; - m_VtxAttr.texCoord[3].Frac = vat.g1.Tex3Frac; - m_VtxAttr.texCoord[4].Elements = vat.g1.Tex4CoordElements; - m_VtxAttr.texCoord[4].Format = vat.g1.Tex4CoordFormat; - - m_VtxAttr.texCoord[4].Frac = vat.g2.Tex4Frac; - m_VtxAttr.texCoord[5].Elements = vat.g2.Tex5CoordElements; - m_VtxAttr.texCoord[5].Format = vat.g2.Tex5CoordFormat; - m_VtxAttr.texCoord[5].Frac = vat.g2.Tex5Frac; - m_VtxAttr.texCoord[6].Elements = vat.g2.Tex6CoordElements; - m_VtxAttr.texCoord[6].Format = vat.g2.Tex6CoordFormat; - m_VtxAttr.texCoord[6].Frac = vat.g2.Tex6Frac; - m_VtxAttr.texCoord[7].Elements = vat.g2.Tex7CoordElements; - m_VtxAttr.texCoord[7].Format = vat.g2.Tex7CoordFormat; - m_VtxAttr.texCoord[7].Frac = vat.g2.Tex7Frac; - - if (!m_VtxAttr.ByteDequant) - { - ERROR_LOG(VIDEO, "ByteDequant is set to zero"); - } -}; - -void VertexLoader::AppendToString(std::string *dest) const -{ - dest->reserve(250); - static const char *posMode[4] = { - "Inv", - "Dir", - "I8", - "I16", - }; - static const char *posFormats[5] = { - "u8", "s8", "u16", "s16", "flt", - }; - static const char *colorFormat[8] = { - "565", - "888", - "888x", - "4444", - "6666", - "8888", - "Inv", - "Inv", - }; - - dest->append(StringFromFormat("%ib skin: %i P: %i %s-%s ", - m_VertexSize, (u32)m_VtxDesc.PosMatIdx, - m_VtxAttr.PosElements ? 3 : 2, posMode[m_VtxDesc.Position], posFormats[m_VtxAttr.PosFormat])); - - if (m_VtxDesc.Normal) - { - dest->append(StringFromFormat("Nrm: %i %s-%s ", - m_VtxAttr.NormalElements, posMode[m_VtxDesc.Normal], posFormats[m_VtxAttr.NormalFormat])); - } - - u64 color_mode[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1}; - for (int i = 0; i < 2; i++) - { - if (color_mode[i]) - { - dest->append(StringFromFormat("C%i: %i %s-%s ", i, m_VtxAttr.color[i].Elements, posMode[color_mode[i]], colorFormat[m_VtxAttr.color[i].Comp])); - } - } - u64 tex_mode[8] = { - m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord, - m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord - }; - for (int i = 0; i < 8; i++) - { - if (tex_mode[i]) - { - dest->append(StringFromFormat("T%i: %i %s-%s ", - i, m_VtxAttr.texCoord[i].Elements, posMode[tex_mode[i]], posFormats[m_VtxAttr.texCoord[i].Format])); - } - } - dest->append(StringFromFormat(" - %i v\n", m_numLoadedVertices)); -} diff --git a/Source/Core/VideoCommon/VertexLoader.h b/Source/Core/VideoCommon/VertexLoader.h index 0e1f60792a..0d886735ca 100644 --- a/Source/Core/VideoCommon/VertexLoader.h +++ b/Source/Core/VideoCommon/VertexLoader.h @@ -16,6 +16,7 @@ #include "VideoCommon/CPMemory.h" #include "VideoCommon/DataReader.h" #include "VideoCommon/NativeVertexFormat.h" +#include "VideoCommon/VertexLoaderBase.h" #include "VideoCommon/VertexLoaderUtils.h" #if _M_SSE >= 0x401 @@ -29,6 +30,14 @@ #define USE_VERTEX_LOADER_JIT #endif +#ifdef WIN32 +#define LOADERDECL __cdecl +#else +#define LOADERDECL +#endif + +typedef void (LOADERDECL *TPipelineFunction)(); + // They are used for the communication with the loader functions extern int tcIndex; extern int colIndex; @@ -36,105 +45,31 @@ extern int colElements[2]; GC_ALIGNED128(extern float posScale[4]); GC_ALIGNED64(extern float tcScale[8][2]); -class VertexLoaderUID -{ - u32 vid[5]; - size_t hash; -public: - VertexLoaderUID() - { - } - - VertexLoaderUID(const TVtxDesc& vtx_desc, const VAT& vat) - { - vid[0] = vtx_desc.Hex & 0xFFFFFFFF; - vid[1] = vtx_desc.Hex >> 32; - vid[2] = vat.g0.Hex; - vid[3] = vat.g1.Hex; - vid[4] = vat.g2.Hex; - hash = CalculateHash(); - } - - bool operator == (const VertexLoaderUID& rh) const - { - return hash == rh.hash && std::equal(vid, vid + sizeof(vid) / sizeof(vid[0]), rh.vid); - } - - size_t GetHash() const - { - return hash; - } - -private: - - size_t CalculateHash() - { - size_t h = -1; - - for (auto word : vid) - { - h = h * 137 + word; - } - - return h; - } -}; - -namespace std -{ -template <> struct hash -{ - size_t operator()(const VertexLoaderUID& uid) const - { - return uid.GetHash(); - } -}; -} - // ARMTODO: This should be done in a better way #ifndef _M_GENERIC -class VertexLoader : public Gen::X64CodeBlock +class VertexLoader : public Gen::X64CodeBlock, public VertexLoaderBase #else -class VertexLoader +class VertexLoader : public VertexLoaderBase #endif { public: VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr); ~VertexLoader(); - void SetupRunVertices(int primitive, int const count); - int RunVertices(int primitive, int count, DataReader src, DataReader dst); - - // For debugging / profiling - void AppendToString(std::string *dest) const; - - // per loader public state - int m_VertexSize; // number of bytes of a raw GC vertex - PortableVertexDeclaration m_native_vtx_decl; - u32 m_native_components; - - // used by VertexLoaderManager - NativeVertexFormat* m_native_vertex_format; - int m_numLoadedVertices; + int RunVertices(int primitive, int count, DataReader src, DataReader dst) override; + std::string GetName() const override { return "OldLoader"; } + bool IsInitialized() override { return true; } // This vertex loader supports all formats private: - // GC vertex format - TVtxAttr m_VtxAttr; // VAT decoded into easy format - TVtxDesc m_VtxDesc; // Not really used currently - or well it is, but could be easily avoided. - VAT m_vat; - #ifndef USE_VERTEX_LOADER_JIT // Pipeline. TPipelineFunction m_PipelineStages[64]; // TODO - figure out real max. it's lower. int m_numPipelineStages; #endif - const u8 *m_compiledCode; - - void SetVAT(const VAT& vat); - void CompileVertexTranslator(); void ConvertVertices(int count); + void SetupRunVertices(int primitive, int const count); void WriteCall(TPipelineFunction); @@ -142,6 +77,8 @@ private: void WriteGetVariable(int bits, Gen::OpArg dest, void *address); void WriteSetVariable(int bits, void *address, Gen::OpArg dest); #endif + + const u8 *m_compiledCode; }; #if _M_SSE >= 0x301 diff --git a/Source/Core/VideoCommon/VertexLoaderBase.cpp b/Source/Core/VideoCommon/VertexLoaderBase.cpp new file mode 100644 index 0000000000..4372729506 --- /dev/null +++ b/Source/Core/VideoCommon/VertexLoaderBase.cpp @@ -0,0 +1,139 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "Common/StringUtil.h" + +#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderBase.h" + +VertexLoaderBase::VertexLoaderBase(const TVtxDesc &vtx_desc, const VAT &vtx_attr) +{ + m_numLoadedVertices = 0; + m_VertexSize = 0; + m_native_vertex_format = nullptr; + + SetVAT(vtx_attr); + m_VtxDesc = vtx_desc; + m_vat = vtx_attr; +} + +void VertexLoaderBase::SetVAT(const VAT& vat) +{ + m_VtxAttr.PosElements = vat.g0.PosElements; + m_VtxAttr.PosFormat = vat.g0.PosFormat; + m_VtxAttr.PosFrac = vat.g0.PosFrac; + m_VtxAttr.NormalElements = vat.g0.NormalElements; + m_VtxAttr.NormalFormat = vat.g0.NormalFormat; + m_VtxAttr.color[0].Elements = vat.g0.Color0Elements; + m_VtxAttr.color[0].Comp = vat.g0.Color0Comp; + m_VtxAttr.color[1].Elements = vat.g0.Color1Elements; + m_VtxAttr.color[1].Comp = vat.g0.Color1Comp; + m_VtxAttr.texCoord[0].Elements = vat.g0.Tex0CoordElements; + m_VtxAttr.texCoord[0].Format = vat.g0.Tex0CoordFormat; + m_VtxAttr.texCoord[0].Frac = vat.g0.Tex0Frac; + m_VtxAttr.ByteDequant = vat.g0.ByteDequant; + m_VtxAttr.NormalIndex3 = vat.g0.NormalIndex3; + + m_VtxAttr.texCoord[1].Elements = vat.g1.Tex1CoordElements; + m_VtxAttr.texCoord[1].Format = vat.g1.Tex1CoordFormat; + m_VtxAttr.texCoord[1].Frac = vat.g1.Tex1Frac; + m_VtxAttr.texCoord[2].Elements = vat.g1.Tex2CoordElements; + m_VtxAttr.texCoord[2].Format = vat.g1.Tex2CoordFormat; + m_VtxAttr.texCoord[2].Frac = vat.g1.Tex2Frac; + m_VtxAttr.texCoord[3].Elements = vat.g1.Tex3CoordElements; + m_VtxAttr.texCoord[3].Format = vat.g1.Tex3CoordFormat; + m_VtxAttr.texCoord[3].Frac = vat.g1.Tex3Frac; + m_VtxAttr.texCoord[4].Elements = vat.g1.Tex4CoordElements; + m_VtxAttr.texCoord[4].Format = vat.g1.Tex4CoordFormat; + + m_VtxAttr.texCoord[4].Frac = vat.g2.Tex4Frac; + m_VtxAttr.texCoord[5].Elements = vat.g2.Tex5CoordElements; + m_VtxAttr.texCoord[5].Format = vat.g2.Tex5CoordFormat; + m_VtxAttr.texCoord[5].Frac = vat.g2.Tex5Frac; + m_VtxAttr.texCoord[6].Elements = vat.g2.Tex6CoordElements; + m_VtxAttr.texCoord[6].Format = vat.g2.Tex6CoordFormat; + m_VtxAttr.texCoord[6].Frac = vat.g2.Tex6Frac; + m_VtxAttr.texCoord[7].Elements = vat.g2.Tex7CoordElements; + m_VtxAttr.texCoord[7].Format = vat.g2.Tex7CoordFormat; + m_VtxAttr.texCoord[7].Frac = vat.g2.Tex7Frac; + + if (!m_VtxAttr.ByteDequant) + { + ERROR_LOG(VIDEO, "ByteDequant is set to zero"); + } +}; + +void VertexLoaderBase::AppendToString(std::string *dest) const +{ + dest->reserve(250); + + dest->append(GetName()); + dest->append(": "); + + static const char *posMode[4] = { + "Inv", + "Dir", + "I8", + "I16", + }; + static const char *posFormats[5] = { + "u8", "s8", "u16", "s16", "flt", + }; + static const char *colorFormat[8] = { + "565", + "888", + "888x", + "4444", + "6666", + "8888", + "Inv", + "Inv", + }; + + dest->append(StringFromFormat("%ib skin: %i P: %i %s-%s ", + m_VertexSize, (u32)m_VtxDesc.PosMatIdx, + m_VtxAttr.PosElements ? 3 : 2, posMode[m_VtxDesc.Position], posFormats[m_VtxAttr.PosFormat])); + + if (m_VtxDesc.Normal) + { + dest->append(StringFromFormat("Nrm: %i %s-%s ", + m_VtxAttr.NormalElements, posMode[m_VtxDesc.Normal], posFormats[m_VtxAttr.NormalFormat])); + } + + u64 color_mode[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1}; + for (int i = 0; i < 2; i++) + { + if (color_mode[i]) + { + dest->append(StringFromFormat("C%i: %i %s-%s ", i, m_VtxAttr.color[i].Elements, posMode[color_mode[i]], colorFormat[m_VtxAttr.color[i].Comp])); + } + } + u64 tex_mode[8] = { + m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord, + m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord + }; + for (int i = 0; i < 8; i++) + { + if (tex_mode[i]) + { + dest->append(StringFromFormat("T%i: %i %s-%s ", + i, m_VtxAttr.texCoord[i].Elements, posMode[tex_mode[i]], posFormats[m_VtxAttr.texCoord[i].Format])); + } + } + dest->append(StringFromFormat(" - %i v\n", m_numLoadedVertices)); +} + +VertexLoaderBase* VertexLoaderBase::CreateVertexLoader(const TVtxDesc& vtx_desc, const VAT& vtx_attr) +{ + VertexLoaderBase* loader; + + // last try: The old VertexLoader + loader = new VertexLoader(vtx_desc, vtx_attr); + if (loader->IsInitialized()) + return loader; + delete loader; + + PanicAlert("No Vertex Loader found."); + return nullptr; +} diff --git a/Source/Core/VideoCommon/VertexLoaderBase.h b/Source/Core/VideoCommon/VertexLoaderBase.h new file mode 100644 index 0000000000..7da2d866f9 --- /dev/null +++ b/Source/Core/VideoCommon/VertexLoaderBase.h @@ -0,0 +1,103 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +#include "Common/CommonTypes.h" + +#include "VideoCommon/CPMemory.h" +#include "VideoCommon/DataReader.h" +#include "VideoCommon/NativeVertexFormat.h" + +class VertexLoaderUID +{ + std::array vid; + size_t hash; +public: + VertexLoaderUID() + { + } + + VertexLoaderUID(const TVtxDesc& vtx_desc, const VAT& vat) + { + vid[0] = vtx_desc.Hex & 0xFFFFFFFF; + vid[1] = vtx_desc.Hex >> 32; + vid[2] = vat.g0.Hex; + vid[3] = vat.g1.Hex; + vid[4] = vat.g2.Hex; + hash = CalculateHash(); + } + + bool operator == (const VertexLoaderUID& rh) const + { + return vid == rh.vid; + } + + size_t GetHash() const + { + return hash; + } + +private: + + size_t CalculateHash() const + { + size_t h = -1; + + for (auto word : vid) + { + h = h * 137 + word; + } + + return h; + } +}; + +namespace std +{ +template <> struct hash +{ + size_t operator()(const VertexLoaderUID& uid) const + { + return uid.GetHash(); + } +}; +} + +class VertexLoaderBase +{ +public: + static VertexLoaderBase* CreateVertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr); + virtual ~VertexLoaderBase() {}; + + virtual int RunVertices(int primitive, int count, DataReader src, DataReader dst) = 0; + + virtual bool IsInitialized() = 0; + + // For debugging / profiling + void AppendToString(std::string *dest) const; + + virtual std::string GetName() const = 0; + + // per loader public state + int m_VertexSize; // number of bytes of a raw GC vertex + PortableVertexDeclaration m_native_vtx_decl; + u32 m_native_components; + + // used by VertexLoaderManager + NativeVertexFormat* m_native_vertex_format; + int m_numLoadedVertices; + +protected: + VertexLoaderBase(const TVtxDesc &vtx_desc, const VAT &vtx_attr); + void SetVAT(const VAT& vat); + + // GC vertex format + TVtxAttr m_VtxAttr; // VAT decoded into easy format + TVtxDesc m_VtxDesc; // Not really used currently - or well it is, but could be easily avoided. + VAT m_vat; +}; diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 98f92e3d10..0ab87b323d 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -15,7 +15,7 @@ #include "VideoCommon/BPMemory.h" #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/Statistics.h" -#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderBase.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderManager.h" @@ -30,7 +30,7 @@ typedef std::unordered_map> VertexLoaderMap; +typedef std::unordered_map> VertexLoaderMap; static std::mutex s_vertex_loader_map_lock; static VertexLoaderMap s_vertex_loader_map; // TODO - change into array of pointers. Keep a map of all seen so far. @@ -93,9 +93,9 @@ void MarkAllDirty() g_preprocess_cp_state.attr_dirty = BitSet32::AllTrue(8); } -static VertexLoader* RefreshLoader(int vtx_attr_group, CPState* state) +static VertexLoaderBase* RefreshLoader(int vtx_attr_group, CPState* state) { - VertexLoader* loader; + VertexLoaderBase* loader; if (state->attr_dirty[vtx_attr_group]) { VertexLoaderUID uid(state->vtx_desc, state->vtx_attr[vtx_attr_group]); @@ -107,8 +107,8 @@ static VertexLoader* RefreshLoader(int vtx_attr_group, CPState* state) } else { - loader = new VertexLoader(state->vtx_desc, state->vtx_attr[vtx_attr_group]); - s_vertex_loader_map[uid] = std::unique_ptr(loader); + loader = VertexLoaderBase::CreateVertexLoader(state->vtx_desc, state->vtx_attr[vtx_attr_group]); + s_vertex_loader_map[uid] = std::unique_ptr(loader); // search for a cached native vertex format const PortableVertexDeclaration& format = loader->m_native_vtx_decl; @@ -139,7 +139,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo CPState* state = &g_main_cp_state; - VertexLoader* loader = RefreshLoader(vtx_attr_group, state); + VertexLoaderBase* loader = RefreshLoader(vtx_attr_group, state); int size = count * loader->m_VertexSize; if ((int)src.size() < size) diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index 65488aa4fa..b4db374e28 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -65,6 +65,7 @@ + @@ -118,6 +119,7 @@ + diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index cd4901f303..d00ee5518c 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -119,6 +119,9 @@ Vertex Loading + + Vertex Loading + Vertex Loading @@ -263,6 +266,9 @@ Vertex Loading + + Vertex Loading + Vertex Loading diff --git a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp index d1032ae6f9..601e90dcc2 100644 --- a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp +++ b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp @@ -2,7 +2,7 @@ #include "Common/Common.h" #include "VideoCommon/DataReader.h" -#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderBase.h" // Needs to be included later because it defines a TEST macro that conflicts // with a TEST method definition in x64Emitter.h. @@ -93,7 +93,7 @@ TEST_F(VertexLoaderTest, PositionDirectFloatXYZ) m_vtx_attr.g0.PosElements = 1; // XYZ m_vtx_attr.g0.PosFormat = 4; // Float - VertexLoader* loader = new VertexLoader(m_vtx_desc, m_vtx_attr); + VertexLoaderBase* loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); ASSERT_EQ(3 * sizeof (float), (u32)loader->m_native_vtx_decl.stride); ASSERT_EQ(3 * sizeof (float), (u32)loader->m_VertexSize); @@ -118,7 +118,7 @@ TEST_F(VertexLoaderTest, PositionDirectFloatXYZ) // Test that scale does nothing for floating point inputs. Input(1.0f); Input(2.0f); Input(4.0f); m_vtx_attr.g0.PosFrac = 1; - loader = new VertexLoader(m_vtx_desc, m_vtx_attr); + loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); count = loader->RunVertices(7, 1, src, dst); src.Skip(1 * loader->m_VertexSize); dst.Skip(count * loader->m_native_vtx_decl.stride); @@ -132,7 +132,7 @@ TEST_F(VertexLoaderTest, PositionDirectU16XY) m_vtx_attr.g0.PosElements = 0; // XY m_vtx_attr.g0.PosFormat = 2; // U16 - VertexLoader* loader = new VertexLoader(m_vtx_desc, m_vtx_attr); + VertexLoaderBase* loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); ASSERT_EQ(3 * sizeof (float), (u32)loader->m_native_vtx_decl.stride); ASSERT_EQ(2 * sizeof (u16), (u32)loader->m_VertexSize); @@ -159,7 +159,7 @@ TEST_F(VertexLoaderTest, PositionDirectU16XY) // Test that scale works on U16 inputs. Input(42); Input(24); m_vtx_attr.g0.PosFrac = 1; - loader = new VertexLoader(m_vtx_desc, m_vtx_attr); + loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); count = loader->RunVertices(7, 1, src, dst); src.Skip(1 * loader->m_VertexSize); dst.Skip(count * loader->m_native_vtx_decl.stride); @@ -173,18 +173,19 @@ TEST_F(VertexLoaderTest, PositionDirectFloatXYZSpeed) m_vtx_attr.g0.PosElements = 1; // XYZ m_vtx_attr.g0.PosFormat = 4; // Float - VertexLoader loader(m_vtx_desc, m_vtx_attr); + VertexLoaderBase* loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); - ASSERT_EQ(3 * sizeof (float), (u32)loader.m_native_vtx_decl.stride); - ASSERT_EQ(3 * sizeof (float), (u32)loader.m_VertexSize); + ASSERT_EQ(3 * sizeof (float), (u32)loader->m_native_vtx_decl.stride); + ASSERT_EQ(3 * sizeof (float), (u32)loader->m_VertexSize); for (int i = 0; i < 1000; ++i) { ResetPointers(); - int count = loader.RunVertices(7, 100000, src, dst); - src.Skip(100000 * loader.m_VertexSize); - dst.Skip(count * loader.m_native_vtx_decl.stride); + int count = loader->RunVertices(7, 100000, src, dst); + src.Skip(100000 * loader->m_VertexSize); + dst.Skip(count * loader->m_native_vtx_decl.stride); } + delete loader; } TEST_F(VertexLoaderTest, PositionDirectU16XYSpeed) @@ -193,18 +194,19 @@ TEST_F(VertexLoaderTest, PositionDirectU16XYSpeed) m_vtx_attr.g0.PosElements = 0; // XY m_vtx_attr.g0.PosFormat = 2; // U16 - VertexLoader loader(m_vtx_desc, m_vtx_attr); + VertexLoaderBase* loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); - ASSERT_EQ(3 * sizeof (float), (u32)loader.m_native_vtx_decl.stride); - ASSERT_EQ(2 * sizeof (u16), (u32)loader.m_VertexSize); + ASSERT_EQ(3 * sizeof (float), (u32)loader->m_native_vtx_decl.stride); + ASSERT_EQ(2 * sizeof (u16), (u32)loader->m_VertexSize); for (int i = 0; i < 1000; ++i) { ResetPointers(); - int count = loader.RunVertices(7, 100000, src, dst); - src.Skip(100000 * loader.m_VertexSize); - dst.Skip(count * loader.m_native_vtx_decl.stride); + int count = loader->RunVertices(7, 100000, src, dst); + src.Skip(100000 * loader->m_VertexSize); + dst.Skip(count * loader->m_native_vtx_decl.stride); } + delete loader; } TEST_F(VertexLoaderTest, LargeFloatVertexSpeed) @@ -257,15 +259,16 @@ TEST_F(VertexLoaderTest, LargeFloatVertexSpeed) m_vtx_attr.g2.Tex7CoordElements = 1; // ST m_vtx_attr.g2.Tex7CoordFormat = 4; // Float - VertexLoader loader(m_vtx_desc, m_vtx_attr); + VertexLoaderBase* loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); // This test is only done 100x in a row since it's ~20x slower using the // current vertex loader implementation. for (int i = 0; i < 100; ++i) { ResetPointers(); - int count = loader.RunVertices(7, 100000, src, dst); - src.Skip(100000 * loader.m_VertexSize); - dst.Skip(count * loader.m_native_vtx_decl.stride); + int count = loader->RunVertices(7, 100000, src, dst); + src.Skip(100000 * loader->m_VertexSize); + dst.Skip(count * loader->m_native_vtx_decl.stride); } + delete loader; }