forked from dolphin-emu/dolphin
		
	git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@22 8ced0084-cf51-0410-be5f-012b33b47a6e
		
			
				
	
	
		
			230 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (C) 2003-2008 Dolphin Project.
 | |
| 
 | |
| // This program is free software: you can redistribute it and/or modify
 | |
| // it under the terms of the GNU General Public License as published by
 | |
| // the Free Software Foundation, version 2.0.
 | |
| 
 | |
| // This program is distributed in the hope that it will be useful,
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| // GNU General Public License 2.0 for more details.
 | |
| 
 | |
| // A copy of the GPL 2.0 should have been included with the program.
 | |
| // If not, see http://www.gnu.org/licenses/
 | |
| 
 | |
| // Official SVN repository and contact information can be found at
 | |
| // http://code.google.com/p/dolphin-emu/
 | |
| 
 | |
| #ifndef _VERTEXLOADER_H
 | |
| #define _VERTEXLOADER_H
 | |
| 
 | |
| #include <vector>
 | |
| 
 | |
| #define SHADER_POSMTX_ATTRIB 1
 | |
| #define SHADER_NORM1_ATTRIB 6
 | |
| #define SHADER_NORM2_ATTRIB 7
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| #include "CPMemory.h"
 | |
| 
 | |
| #define LOADERDECL __cdecl
 | |
| typedef void (LOADERDECL *TPipelineFunction)(void*);
 | |
| 
 | |
| /// Use to manage loading and setting vertex buffer data for OpenGL
 | |
| class VertexLoader
 | |
| {
 | |
| public:
 | |
|     enum
 | |
|     {
 | |
|         NRM_ZERO = 0,
 | |
|         NRM_ONE = 1,
 | |
|         NRM_THREE = 3
 | |
|     };
 | |
| 
 | |
|     // m_components
 | |
|     enum {
 | |
|         VB_HAS_POSMTXIDX =(1<<1),
 | |
|         VB_HAS_TEXMTXIDX0=(1<<2),
 | |
|         VB_HAS_TEXMTXIDX1=(1<<3),
 | |
|         VB_HAS_TEXMTXIDX2=(1<<4),
 | |
|         VB_HAS_TEXMTXIDX3=(1<<5),
 | |
|         VB_HAS_TEXMTXIDX4=(1<<6),
 | |
|         VB_HAS_TEXMTXIDX5=(1<<7),
 | |
|         VB_HAS_TEXMTXIDX6=(1<<8),
 | |
|         VB_HAS_TEXMTXIDX7=(1<<9),
 | |
|         VB_HAS_TEXMTXIDXALL=(0xff<<2),
 | |
|         //VB_HAS_POS=0, // Implied, it always has pos! don't bother testing
 | |
|         VB_HAS_NRM0=(1<<10),
 | |
|         VB_HAS_NRM1=(1<<11),
 | |
|         VB_HAS_NRM2=(1<<12),
 | |
|         VB_HAS_NRMALL=(7<<10),
 | |
|         
 | |
|         VB_HAS_COL0=(1<<13),
 | |
|         VB_HAS_COL1=(1<<14),
 | |
| 
 | |
|         VB_HAS_UV0=(1<<15),
 | |
|         VB_HAS_UV1=(1<<16),
 | |
|         VB_HAS_UV2=(1<<17),
 | |
|         VB_HAS_UV3=(1<<18),
 | |
|         VB_HAS_UV4=(1<<19),
 | |
|         VB_HAS_UV5=(1<<20),
 | |
|         VB_HAS_UV6=(1<<21),
 | |
|         VB_HAS_UV7=(1<<22),
 | |
|         VB_HAS_UVALL=(0xff<<15),
 | |
|         VB_HAS_UVTEXMTXSHIFT=13,
 | |
|     };
 | |
| 
 | |
| private:	
 | |
|     TPipelineFunction m_PipelineStates[32];
 | |
|     int m_numPipelineStates;	
 | |
|     int m_VertexSize; // number of bytes of a raw vertex
 | |
|     int m_counter;
 | |
|     int m_VBVertexStride, m_VBStridePad; // stride of a vertex to send to the GPU
 | |
| 
 | |
|     u32 m_components; // VB_HAS_X
 | |
| 
 | |
|     UVAT_group0 m_group0;
 | |
|     UVAT_group1 m_group1;
 | |
|     UVAT_group2 m_group2;
 | |
| 
 | |
|     vector<int> m_vtexmap; // tex index map
 | |
|     TVtxAttr m_VtxAttr; //Decoded into easy format
 | |
| 
 | |
|     u8* m_compiledCode;
 | |
| 
 | |
|     //common for all loaders
 | |
|     TVtxDesc m_VtxDesc;
 | |
| 
 | |
|     // seup the pipeline with this vertex fmt
 | |
|     void SetupColor(int num, int _iMode, int _iFormat, int _iElements);
 | |
|     void SetupTexCoord(int num, int _iMode, int _iFormat, int _iElements, int _iFrac);
 | |
| 
 | |
|     int m_AttrDirty;
 | |
| 
 | |
| public:
 | |
|     // constructor
 | |
|     VertexLoader();
 | |
|     ~VertexLoader();
 | |
|     
 | |
|     // run the pipeline 
 | |
|     void ProcessFormat();
 | |
|     void PrepareRun();
 | |
|     void RunVertices(int primitive, int count);
 | |
|     void WriteCall(void  (LOADERDECL *func)(void *));
 | |
|     
 | |
|     int GetGCVertexSize() const { _assert_( !m_AttrDirty ); return m_VertexSize; }
 | |
|     int GetVBVertexStride() const { _assert_( !m_AttrDirty); return m_VBVertexStride; }
 | |
| 
 | |
|     int ComputeVertexSize();
 | |
| 
 | |
|      // SetVAT_group
 | |
|     // ignore PosFrac, texCoord[i].Frac
 | |
| 
 | |
|     void SetVAT_group0(u32 _group0) 
 | |
|     {
 | |
|         if ((m_group0.Hex&~0x3e0001f0) != (_group0&~0x3e0001f0)) {
 | |
|             m_AttrDirty = 2;
 | |
|         }
 | |
|         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_group1(u32 _group1) 
 | |
|     {
 | |
|         if ((m_group1.Hex&~0x7c3e1f0) != (_group1&~0x7c3e1f0)) {
 | |
|             m_AttrDirty = 2;
 | |
|         }
 | |
|         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&~0xf87c3e1f) != (_group2&~0xf87c3e1f)) {
 | |
|             m_AttrDirty = 2;
 | |
|         }
 | |
|         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;
 | |
|     };
 | |
| };									  
 | |
| 
 | |
| /// Methods to manage and cache the global state of vertex streams and flushing streams
 | |
| /// Also handles processing the CP registers
 | |
| class VertexManager
 | |
| {
 | |
|     static TVtxDesc s_GlobalVtxDesc;
 | |
| 
 | |
| public:
 | |
|     enum Collection
 | |
|     {
 | |
|         C_NOTHING=0,
 | |
|         C_TRIANGLES=1,
 | |
|         C_LINES=2,
 | |
|         C_POINTS=3
 | |
|     };
 | |
| 
 | |
|     static bool Init();
 | |
|     static void Destroy();
 | |
| 
 | |
|     static void ResetBuffer();
 | |
|     static void ResetComponents();
 | |
| 
 | |
|     static void AddVertices(int primitive, int numvertices);
 | |
|     static void Flush(); // flushes the current buffer
 | |
| 
 | |
|     static int GetRemainingSize();
 | |
|     static TVtxDesc &GetVtxDesc() {return s_GlobalVtxDesc; }
 | |
| 
 | |
|     static void LoadCPReg(u32 SubCmd, u32 Value);
 | |
|     static size_t SaveLoadState(char *ptr, BOOL save);
 | |
| 
 | |
|     static u8* s_pCurBufferPointer;
 | |
|     static float shiftLookup[32];
 | |
| };
 | |
| 
 | |
| extern VertexLoader g_VertexLoaders[8];
 | |
| 
 | |
| u8 ReadBuffer8();
 | |
| u16 ReadBuffer16();
 | |
| u32 ReadBuffer32();
 | |
| float ReadBuffer32F();
 | |
| 
 | |
| #endif
 |