Move moving things around and preparing for the next step (cached vertexloaders).

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@957 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-10-25 13:27:28 +00:00
parent bc79d22f5e
commit 2f6d41e413
13 changed files with 243 additions and 207 deletions

View File

@ -24,3 +24,6 @@ u32 arraybases[16];
u32 arraystrides[16];
TMatrixIndexA MatrixIndexA;
TMatrixIndexB MatrixIndexB;
TVtxDesc g_VtxDesc;
// Most games only use the first VtxAttr and simply reconfigure it all the time as needed.
VAT g_VtxAttr[8];

View File

@ -248,4 +248,14 @@ extern u32 arraystrides[16];
extern TMatrixIndexA MatrixIndexA;
extern TMatrixIndexB MatrixIndexB;
struct VAT
{
UVAT_group0 g0;
UVAT_group1 g1;
UVAT_group2 g2;
};
extern TVtxDesc g_VtxDesc;
extern VAT g_VtxAttr[8];
#endif

View File

@ -55,17 +55,12 @@ enum {
VB_HAS_UVTEXMTXSHIFT=13,
};
#define LOADERDECL __cdecl
typedef void (LOADERDECL *TPipelineFunction)(const void *);
// This will soon be used in a cache of vertex formats, rather than used in-place.
// The implementation of this class is specific for GL/DX, so NativeVertexFormat.cpp
// is in the respective plugin, not here in VideoCommon.
// This class will also be split into NativeVertexFormat and VertexFormatConverter.
// VertexFormatConverters will be cached, indexed by TVtxDesc+TVtxAttr.
// Note that this class can't just invent arbitrary vertex formats out of its input -
// all the data loading code must always be made compatible.
class NativeVertexFormat
@ -84,6 +79,4 @@ public:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
};
#endif // _NATIVEVERTEXFORMAT_H

View File

@ -32,6 +32,9 @@ static void DoState(PointerWrap &p) {
p.DoArray(arraystrides, 16);
p.Do(MatrixIndexA);
p.Do(MatrixIndexB);
p.Do(g_VtxDesc.Hex);
p.DoArray(g_VtxAttr, 8);
// XF Memory
p.Do(xfregs);
p.DoArray(xfmem, XFMEM_SIZE);

View File

@ -139,8 +139,7 @@ bool FifoCommandRunnable()
{
iCommandSize = 1 + 2;
u16 numVertices = DataPeek16(1);
VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK];
iCommandSize += numVertices * vtxLoader.ComputeVertexSize();
iCommandSize += numVertices * VertexLoaderManager::GetVertexSize(Cmd & GX_VAT_MASK);
}
else
{

View File

@ -80,7 +80,6 @@ int frameCount;
void HandleCgError(CGcontext ctx, CGerror err, void* appdata);
bool Renderer::Create2()
{
bool bSuccess = true;
@ -213,8 +212,9 @@ bool Renderer::Create2()
if (glGetError() != GL_NO_ERROR) {
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight);
s_bHaveStencilBuffer = false;
} else {
s_bHaveStencilBuffer = true;
}
else s_bHaveStencilBuffer = true;
GL_REPORT_ERROR();
@ -244,7 +244,8 @@ bool Renderer::Create2()
nZBufferRender = 0;
GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false;
if (err != GL_NO_ERROR)
bSuccess = false;
s_pfont = new RasterFont();
@ -290,7 +291,6 @@ bool Renderer::Create2()
//glEnable(GL_POLYGON_OFFSET_FILL);
//glEnable(GL_POLYGON_OFFSET_LINE);
//glPolygonOffset(0, 1);
if (!Initialize())
return false;
@ -345,7 +345,6 @@ bool Renderer::Initialize()
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // perspective correct interpolation of colors and tex coords
// setup the default vertex declaration
glDisable(GL_STENCIL_TEST);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, nBackbufferWidth, nBackbufferHeight);
@ -357,9 +356,7 @@ bool Renderer::Initialize()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Renderer::SetZBufferRender();
// legacy multitexturing: select texture channel only
// legacy multitexturing: select texture channel only.
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -547,7 +544,10 @@ bool Renderer::HaveStencilBuffer()
void Renderer::SetZBufferRender()
{
nZBufferRender = 10; // give it 10 frames
GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
GLenum s_drawbuffers[2] = {
GL_COLOR_ATTACHMENT0_EXT,
GL_COLOR_ATTACHMENT1_EXT
};
glDrawBuffers(2, s_drawbuffers);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0);
_assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
@ -568,7 +568,8 @@ void Renderer::FlushZBufferAlphaToTarget()
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget);
TextureMngr::EnableTexRECT(0);
// disable all other stages
for(int i = 1; i < 8; ++i) TextureMngr::DisableStage(i);
for(int i = 1; i < 8; ++i)
TextureMngr::DisableStage(i);
GL_REPORT_ERRORD();
if(g_Config.bStretchToFit)
@ -741,16 +742,12 @@ void Renderer::SwapBuffers()
fpscount = 0;
}
// ---------------------------------------------------------------------------------------
// Write logging data to debugger
// -----------------
if(m_frame)
{
Logging(0);
}
if (g_Config.bOverlayStats) {
char st[2048];
char *p = st;
@ -822,9 +819,6 @@ void Renderer::SwapBuffers()
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer );
// s_nCurTarget = !s_nCurTarget;
// SetRenderTarget(0);
if (nZBufferRender > 0) {
if (--nZBufferRender == 0) {
// turn off
@ -865,7 +859,8 @@ void Renderer::SetCgErrorOutput(bool bOutput)
void HandleGLError()
{
const GLubyte* pstr = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
if (pstr != NULL && pstr[0] != 0 ) {
if (pstr != NULL && pstr[0] != 0)
{
GLint loc = 0;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &loc);
ERROR_LOG("program error at %d: ", loc);
@ -877,12 +872,14 @@ void HandleGLError()
GLenum error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
// if error != GL_FRAMEBUFFER_COMPLETE_EXT, there's an error of some sort
if (error != 0) {
int w, h;
GLint fmt;
glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt);
glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_WIDTH_EXT, (GLint *)&w);
glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_HEIGHT_EXT, (GLint *)&h);
if (!error)
return;
// int w, h;
// GLint fmt;
// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt);
// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_WIDTH_EXT, (GLint *)&w);
// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_HEIGHT_EXT, (GLint *)&h);
switch(error)
{
@ -917,11 +914,11 @@ void HandleGLError()
break;
}
}
}
void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
{
if( s_bOutputCgErrors ) {
if (s_bOutputCgErrors)
{
ERROR_LOG("Cg error: %s\n", cgGetErrorString(err));
const char* listing = cgGetLastListing(g_cgcontext);
if (listing != NULL) {

View File

@ -110,8 +110,6 @@ void LOADERDECL TexMtx_Write_Short3(const void *_p)
#include "VertexLoader_Color.h"
#include "VertexLoader_TextCoord.h"
VertexLoader g_VertexLoaders[8];
VertexLoader::VertexLoader()
{
m_VertexSize = 0;
@ -128,15 +126,15 @@ int VertexLoader::ComputeVertexSize()
{
if (m_AttrDirty == AD_CLEAN) {
// Compare the 33 desc bits.
if (m_VtxDesc.Hex0 == GetVtxDesc().Hex0 &&
(m_VtxDesc.Hex1 & 1) == (GetVtxDesc().Hex1 & 1))
if (m_VtxDesc.Hex0 == g_VtxDesc.Hex0 &&
(m_VtxDesc.Hex1 & 1) == (g_VtxDesc.Hex1 & 1))
return m_VertexSize;
m_VtxDesc.Hex = GetVtxDesc().Hex;
m_VtxDesc.Hex = g_VtxDesc.Hex;
}
else {
// Attributes are dirty so we have to recompute everything anyway.
m_VtxDesc.Hex = GetVtxDesc().Hex;
m_VtxDesc.Hex = g_VtxDesc.Hex;
}
m_AttrDirty = AD_DIRTY;
@ -245,13 +243,13 @@ int VertexLoader::ComputeVertexSize()
}
void VertexLoader::PrepareForVertexFormat()
void VertexLoader::CompileVertexTranslator()
{
if (m_AttrDirty == AD_CLEAN)
{
// Check if local cached desc (in this VL) matches global desc
if (m_VtxDesc.Hex0 == GetVtxDesc().Hex0 &&
(m_VtxDesc.Hex1 & 1) == (GetVtxDesc().Hex1 & 1))
if (m_VtxDesc.Hex0 == g_VtxDesc.Hex0 &&
(m_VtxDesc.Hex1 & 1) == (g_VtxDesc.Hex1 & 1))
{
return; // same
}
@ -261,7 +259,7 @@ void VertexLoader::PrepareForVertexFormat()
m_AttrDirty = AD_CLEAN;
}
m_VtxDesc.Hex = GetVtxDesc().Hex;
m_VtxDesc.Hex = g_VtxDesc.Hex;
// Reset pipeline
m_numPipelineStages = 0;
@ -525,9 +523,9 @@ void VertexLoader::RunVertices(int primitive, int count)
if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != &m_NativeFmt)
{
VertexManager::Flush();
// Also move the Set() here?
}
g_nativeVertexFmt = &m_NativeFmt;
// This has dirty handling - won't actually recompute unless necessary.
ComputeVertexSize();
@ -540,9 +538,7 @@ void VertexLoader::RunVertices(int primitive, int count)
}
// This has dirty handling - won't actually recompute unless necessary.
PrepareForVertexFormat();
g_nativeVertexFmt = &m_NativeFmt;
CompileVertexTranslator();
VertexManager::EnableComponents(m_NativeFmt.m_components);
@ -646,3 +642,66 @@ void VertexLoader::RunPipelineOnce() const
for (int i = 0; i < m_numPipelineStages; i++)
m_PipelineStages[i](&m_VtxAttr);
}
void VertexLoader::SetVAT_group0(u32 _group0)
{
// ignore frac bits - we don't need to recompute if all that's changed was the frac bits.
if ((m_group0.Hex & ~VAT_0_FRACBITS) != (_group0 & ~VAT_0_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group0.Hex = _group0;
m_VtxAttr.PosElements = m_group0.PosElements;
m_VtxAttr.PosFormat = m_group0.PosFormat;
m_VtxAttr.PosFrac = m_group0.PosFrac;
m_VtxAttr.NormalElements = m_group0.NormalElements;
m_VtxAttr.NormalFormat = m_group0.NormalFormat;
m_VtxAttr.color[0].Elements = m_group0.Color0Elements;
m_VtxAttr.color[0].Comp = m_group0.Color0Comp;
m_VtxAttr.color[1].Elements = m_group0.Color1Elements;
m_VtxAttr.color[1].Comp = m_group0.Color1Comp;
m_VtxAttr.texCoord[0].Elements = m_group0.Tex0CoordElements;
m_VtxAttr.texCoord[0].Format = m_group0.Tex0CoordFormat;
m_VtxAttr.texCoord[0].Frac = m_group0.Tex0Frac;
m_VtxAttr.ByteDequant = m_group0.ByteDequant;
m_VtxAttr.NormalIndex3 = m_group0.NormalIndex3;
};
void VertexLoader::SetVAT_group1(u32 _group1)
{
if ((m_group1.Hex & ~VAT_1_FRACBITS) != (_group1 & ~VAT_1_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group1.Hex = _group1;
m_VtxAttr.texCoord[1].Elements = m_group1.Tex1CoordElements;
m_VtxAttr.texCoord[1].Format = m_group1.Tex1CoordFormat;
m_VtxAttr.texCoord[1].Frac = m_group1.Tex1Frac;
m_VtxAttr.texCoord[2].Elements = m_group1.Tex2CoordElements;
m_VtxAttr.texCoord[2].Format = m_group1.Tex2CoordFormat;
m_VtxAttr.texCoord[2].Frac = m_group1.Tex2Frac;
m_VtxAttr.texCoord[3].Elements = m_group1.Tex3CoordElements;
m_VtxAttr.texCoord[3].Format = m_group1.Tex3CoordFormat;
m_VtxAttr.texCoord[3].Frac = m_group1.Tex3Frac;
m_VtxAttr.texCoord[4].Elements = m_group1.Tex4CoordElements;
m_VtxAttr.texCoord[4].Format = m_group1.Tex4CoordFormat;
};
void VertexLoader::SetVAT_group2(u32 _group2)
{
if ((m_group2.Hex & ~VAT_2_FRACBITS) != (_group2 & ~VAT_2_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group2.Hex = _group2;
m_VtxAttr.texCoord[4].Frac = m_group2.Tex4Frac;
m_VtxAttr.texCoord[5].Elements = m_group2.Tex5CoordElements;
m_VtxAttr.texCoord[5].Format = m_group2.Tex5CoordFormat;
m_VtxAttr.texCoord[5].Frac = m_group2.Tex5Frac;
m_VtxAttr.texCoord[6].Elements = m_group2.Tex6CoordElements;
m_VtxAttr.texCoord[6].Format = m_group2.Tex6CoordFormat;
m_VtxAttr.texCoord[6].Frac = m_group2.Tex6Frac;
m_VtxAttr.texCoord[7].Elements = m_group2.Tex7CoordElements;
m_VtxAttr.texCoord[7].Format = m_group2.Tex7CoordFormat;
m_VtxAttr.texCoord[7].Frac = m_group2.Tex7Frac;
};

View File

@ -23,9 +23,6 @@
#include "NativeVertexFormat.h"
// There are 8 of these. Most games only use the first, and just reconfigure it all the time
// as needed, unfortunately.
// TODO - clarify the role of this class. It seems to have taken on some irrelevant stuff.
class VertexLoader
{
public:
@ -44,19 +41,20 @@ private:
AD_VAT_DIRTY = 2,
} m_AttrDirty;
// Flipper vertex format =============
int m_VertexSize; // number of bytes of a raw GC vertex
// Flipper vertex format
// Raw VAttr
UVAT_group0 m_group0;
UVAT_group1 m_group1;
UVAT_group2 m_group2;
TVtxAttr m_VtxAttr; // Decoded into easy format
// Common for all loaders (? then why is it here?)
// Vtx desc
TVtxDesc m_VtxDesc;
// PC vertex format, + converter ======
// PC vertex format, + converter
NativeVertexFormat m_NativeFmt;
// Pipeline. To be JIT compiled in the future.
@ -73,7 +71,7 @@ public:
~VertexLoader();
// run the pipeline
void PrepareForVertexFormat();
void CompileVertexTranslator();
void RunVertices(int primitive, int count);
void WriteCall(TPipelineFunction);
@ -82,70 +80,9 @@ public:
int ComputeVertexSize();
void SetVAT_group0(u32 _group0)
{
// ignore frac bits - we don't need to recompute if all that's changed was the frac bits.
if ((m_group0.Hex & ~VAT_0_FRACBITS) != (_group0 & ~VAT_0_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group0.Hex = _group0;
m_VtxAttr.PosElements = m_group0.PosElements;
m_VtxAttr.PosFormat = m_group0.PosFormat;
m_VtxAttr.PosFrac = m_group0.PosFrac;
m_VtxAttr.NormalElements = m_group0.NormalElements;
m_VtxAttr.NormalFormat = m_group0.NormalFormat;
m_VtxAttr.color[0].Elements = m_group0.Color0Elements;
m_VtxAttr.color[0].Comp = m_group0.Color0Comp;
m_VtxAttr.color[1].Elements = m_group0.Color1Elements;
m_VtxAttr.color[1].Comp = m_group0.Color1Comp;
m_VtxAttr.texCoord[0].Elements = m_group0.Tex0CoordElements;
m_VtxAttr.texCoord[0].Format = m_group0.Tex0CoordFormat;
m_VtxAttr.texCoord[0].Frac = m_group0.Tex0Frac;
m_VtxAttr.ByteDequant = m_group0.ByteDequant;
m_VtxAttr.NormalIndex3 = m_group0.NormalIndex3;
void SetVAT_group0(u32 _group0);
void SetVAT_group1(u32 _group1);
void SetVAT_group2(u32 _group2);
};
void SetVAT_group1(u32 _group1)
{
if ((m_group1.Hex & ~VAT_1_FRACBITS) != (_group1 & ~VAT_1_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group1.Hex = _group1;
m_VtxAttr.texCoord[1].Elements = m_group1.Tex1CoordElements;
m_VtxAttr.texCoord[1].Format = m_group1.Tex1CoordFormat;
m_VtxAttr.texCoord[1].Frac = m_group1.Tex1Frac;
m_VtxAttr.texCoord[2].Elements = m_group1.Tex2CoordElements;
m_VtxAttr.texCoord[2].Format = m_group1.Tex2CoordFormat;
m_VtxAttr.texCoord[2].Frac = m_group1.Tex2Frac;
m_VtxAttr.texCoord[3].Elements = m_group1.Tex3CoordElements;
m_VtxAttr.texCoord[3].Format = m_group1.Tex3CoordFormat;
m_VtxAttr.texCoord[3].Frac = m_group1.Tex3Frac;
m_VtxAttr.texCoord[4].Elements = m_group1.Tex4CoordElements;
m_VtxAttr.texCoord[4].Format = m_group1.Tex4CoordFormat;
};
void SetVAT_group2(u32 _group2)
{
if ((m_group2.Hex & ~VAT_2_FRACBITS) != (_group2 & ~VAT_2_FRACBITS)) {
m_AttrDirty = AD_VAT_DIRTY;
}
m_group2.Hex = _group2;
m_VtxAttr.texCoord[4].Frac = m_group2.Tex4Frac;
m_VtxAttr.texCoord[5].Elements = m_group2.Tex5CoordElements;
m_VtxAttr.texCoord[5].Format = m_group2.Tex5CoordFormat;
m_VtxAttr.texCoord[5].Frac = m_group2.Tex5Frac;
m_VtxAttr.texCoord[6].Elements = m_group2.Tex6CoordElements;
m_VtxAttr.texCoord[6].Format = m_group2.Tex6CoordFormat;
m_VtxAttr.texCoord[6].Frac = m_group2.Tex6Frac;
m_VtxAttr.texCoord[7].Elements = m_group2.Tex7CoordElements;
m_VtxAttr.texCoord[7].Format = m_group2.Tex7CoordFormat;
m_VtxAttr.texCoord[7].Frac = m_group2.Tex7Frac;
};
};
extern VertexLoader g_VertexLoaders[8];
#endif

View File

@ -19,22 +19,24 @@
#include "VertexLoader.h"
#include "VertexLoaderManager.h"
// The one and only vtx_desc
TVtxDesc g_vtx_desc;
// There are 8 vtx_attr structures. They will soon live here.
static bool s_desc_dirty;
static bool s_attr_dirty[8];
const TVtxDesc &GetVtxDesc()
// TODO - change into array of pointers. Keep a map of all seen so far.
static VertexLoader g_VertexLoaders[8];
namespace VertexLoaderManager
{
return g_vtx_desc;
void Init()
{
s_desc_dirty = false;
for (int i = 0; i < 8; i++)
s_attr_dirty[i] = false;
}
namespace VertexLoaderManager {
void Init() {
g_vtx_desc.Hex = 0;
}
void Shutdown() {
void Shutdown()
{
}
@ -42,12 +44,17 @@ void RunVertices(int vtx_attr_group, int primitive, int count)
{
if (!count)
return;
// TODO - grab load the correct vertex loader if anything is dirty.
// TODO - grab & load the correct vertex loader if anything is dirty.
g_VertexLoaders[vtx_attr_group].RunVertices(primitive, count);
}
} // namespace
int GetVertexSize(int vtx_attr_group)
{
// The vertex loaders will soon cache the vertex size.
return g_VertexLoaders[vtx_attr_group].ComputeVertexSize();
}
} // namespace
void LoadCPReg(u32 sub_cmd, u32 value)
{
@ -56,24 +63,51 @@ void LoadCPReg(u32 sub_cmd, u32 value)
case 0x30:
VertexShaderMngr::SetTexMatrixChangedA(value);
break;
case 0x40:
VertexShaderMngr::SetTexMatrixChangedB(value);
break;
case 0x50:
g_vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
g_vtx_desc.Hex |= value;
g_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits
g_VtxDesc.Hex |= value;
s_desc_dirty = true;
break;
case 0x60:
g_vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
g_vtx_desc.Hex |= (u64)value << 17;
g_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits
g_VtxDesc.Hex |= (u64)value << 17;
s_desc_dirty = true;
break;
case 0x70: g_VertexLoaders[sub_cmd & 7].SetVAT_group0(value); _assert_((sub_cmd & 0x0F) < 8); break;
case 0x80: g_VertexLoaders[sub_cmd & 7].SetVAT_group1(value); _assert_((sub_cmd & 0x0F) < 8); break;
case 0x90: g_VertexLoaders[sub_cmd & 7].SetVAT_group2(value); _assert_((sub_cmd & 0x0F) < 8); break;
case 0x70:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g0.Hex = value;
g_VertexLoaders[sub_cmd & 7].SetVAT_group0(value);
s_attr_dirty[sub_cmd & 7] = true;
break;
case 0xA0: arraybases[sub_cmd & 0xF] = value & 0xFFFFFFFF; break;
case 0xB0: arraystrides[sub_cmd & 0xF] = value & 0xFF; break;
case 0x80:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g1.Hex = value;
g_VertexLoaders[sub_cmd & 7].SetVAT_group1(value);
s_attr_dirty[sub_cmd & 7] = true;
break;
case 0x90:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g2.Hex = value;
g_VertexLoaders[sub_cmd & 7].SetVAT_group2(value);
s_attr_dirty[sub_cmd & 7] = true;
break;
// Pointers to vertex arrays in GC RAM
case 0xA0:
arraybases[sub_cmd & 0xF] = value & 0xFFFFFFFF; // huh, why the mask?
break;
case 0xB0:
arraystrides[sub_cmd & 0xF] = value & 0xFF;
break;
}
}

View File

@ -24,15 +24,14 @@ namespace VertexLoaderManager
{
void Init();
void Shutdown();
int GetVertexSize(int vtx_attr_group);
void RunVertices(int vtx_attr_group, int primitive, int count);
// TODO - don't expose these like this.
static u8* s_pCurBufferPointer;
};
const TVtxDesc &GetVtxDesc();
// Might move this into its own file later.
void LoadCPReg(u32 SubCmd, u32 Value);

View File

@ -33,7 +33,6 @@ static u32 s_prevcomponents; // previous state set
u8* s_pCurBufferPointer = NULL;
TVtxDesc s_GlobalVtxDesc;
static const GLenum c_primitiveType[8] =
{

View File

@ -37,6 +37,7 @@
#include "TextureMngr.h"
#include "BPStructs.h"
#include "VertexLoader.h"
#include "VertexLoaderManager.h"
#include "VertexManager.h"
#include "PixelShaderManager.h"
#include "VertexShaderManager.h"
@ -222,10 +223,12 @@ void Video_Prepare(void)
VertexShaderMngr::Init();
PixelShaderMngr::Init();
GL_REPORT_ERRORD();
VertexLoaderManager::Init();
}
void Video_Shutdown(void)
{
VertexLoaderManager::Shutdown();
VertexShaderMngr::Shutdown();
PixelShaderMngr::Shutdown();
Fifo_Shutdown();