VideoCommon: split VertexLoaderBase from VertexLoader
This commit is contained in:
parent
a71c8158d9
commit
809117102e
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<VertexLoader>(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<VertexLoaderBase>(m_CurrentLoader);
|
||||
}
|
||||
|
||||
m_VertexSize = m_CurrentLoader->m_VertexSize;
|
||||
|
|
|
@ -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<VertexLoaderUID, std::unique_ptr<VertexLoader>> m_VertexLoaderMap;
|
||||
std::unordered_map<VertexLoaderUID, std::unique_ptr<VertexLoaderBase>> m_VertexLoaderMap;
|
||||
std::vector<u8> m_LoadedVertices;
|
||||
VertexLoader* m_CurrentLoader;
|
||||
VertexLoaderBase* m_CurrentLoader;
|
||||
|
||||
u8 m_attributeIndex;
|
||||
u8 m_primitiveType;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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<VertexLoaderUID>
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2014 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "VideoCommon/CPMemory.h"
|
||||
#include "VideoCommon/DataReader.h"
|
||||
#include "VideoCommon/NativeVertexFormat.h"
|
||||
|
||||
class VertexLoaderUID
|
||||
{
|
||||
std::array<u32, 5> 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<VertexLoaderUID>
|
||||
{
|
||||
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;
|
||||
};
|
|
@ -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<PortableVertexDeclaration, std::unique_ptr<NativeVert
|
|||
static NativeVertexFormatMap s_native_vertex_map;
|
||||
static NativeVertexFormat* s_current_vtx_fmt;
|
||||
|
||||
typedef std::unordered_map<VertexLoaderUID, std::unique_ptr<VertexLoader>> VertexLoaderMap;
|
||||
typedef std::unordered_map<VertexLoaderUID, std::unique_ptr<VertexLoaderBase>> 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<VertexLoader>(loader);
|
||||
loader = VertexLoaderBase::CreateVertexLoader(state->vtx_desc, state->vtx_attr[vtx_attr_group]);
|
||||
s_vertex_loader_map[uid] = std::unique_ptr<VertexLoaderBase>(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)
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
<ClCompile Include="TextureCacheBase.cpp" />
|
||||
<ClCompile Include="TextureConversionShader.cpp" />
|
||||
<ClCompile Include="VertexLoader.cpp" />
|
||||
<ClCompile Include="VertexLoaderBase.cpp" />
|
||||
<ClCompile Include="VertexLoaderManager.cpp" />
|
||||
<ClCompile Include="VertexLoader_Color.cpp" />
|
||||
<ClCompile Include="VertexLoader_Normal.cpp" />
|
||||
|
@ -118,6 +119,7 @@
|
|||
<ClInclude Include="TextureConversionShader.h" />
|
||||
<ClInclude Include="TextureDecoder.h" />
|
||||
<ClInclude Include="VertexLoader.h" />
|
||||
<ClInclude Include="VertexLoaderBase.h" />
|
||||
<ClInclude Include="VertexLoaderManager.h" />
|
||||
<ClInclude Include="VertexLoaderUtils.h" />
|
||||
<ClInclude Include="VertexLoader_Color.h" />
|
||||
|
|
|
@ -119,6 +119,9 @@
|
|||
<ClCompile Include="VertexLoader.cpp">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VertexLoaderBase.cpp">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VertexLoader_Color.cpp">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClCompile>
|
||||
|
@ -263,6 +266,9 @@
|
|||
<ClInclude Include="VertexLoader.h">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VertexLoaderBase.h">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VertexLoader_Color.h">
|
||||
<Filter>Vertex Loading</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -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<u16>(42); Input<u16>(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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue