| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | // 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_POSITION_H
 | 
					
						
							|  |  |  | #define VERTEXLOADER_POSITION_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-26 13:03:50 +00:00
										 |  |  | #include "Common.h"
 | 
					
						
							|  |  |  | #include "VideoCommon.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | #include "VertexLoader.h"
 | 
					
						
							|  |  |  | #include "VertexLoader_Position.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-26 13:03:50 +00:00
										 |  |  | #include "NativeVertexWriter.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern float posScale; | 
					
						
							|  |  |  | extern TVtxAttr *pVtxAttr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Thoughts on the implementation of a vertex loader compiler.
 | 
					
						
							|  |  |  | // s_pCurBufferPointer should definitely be in a register.
 | 
					
						
							|  |  |  | // Could load the position scale factor in XMM7, for example.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // The pointer inside DataReadU8 in another.
 | 
					
						
							|  |  |  | // Let's check out Pos_ReadDirect_UByte(). For Byte, replace MOVZX with MOVSX.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | MOVZX(32, R(EAX), MOffset(ESI, 0)); | 
					
						
							|  |  |  | MOVZX(32, R(EBX), MOffset(ESI, 1)); | 
					
						
							|  |  |  | MOVZX(32, R(ECX), MOffset(ESI, 2)); | 
					
						
							|  |  |  | MOVD(XMM0, R(EAX)); | 
					
						
							|  |  |  | MOVD(XMM1, R(EBX)); | 
					
						
							|  |  |  | MOVD(XMM2, R(ECX));                    | 
					
						
							|  |  |  | CVTDQ2PS(XMM0, XMM0); | 
					
						
							|  |  |  | CVTDQ2PS(XMM1, XMM1); | 
					
						
							|  |  |  | CVTDQ2PS(XMM2, XMM2); | 
					
						
							|  |  |  | MULSS(XMM0, XMM7); | 
					
						
							|  |  |  | MULSS(XMM1, XMM7); | 
					
						
							|  |  |  | MULSS(XMM2, XMM7); | 
					
						
							|  |  |  | MOVSS(MOffset(EDI, 0), XMM0); | 
					
						
							|  |  |  | MOVSS(MOffset(EDI, 4), XMM1); | 
					
						
							|  |  |  | MOVSS(MOffset(EDI, 8), XMM2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Alternatively, lookup table: | 
					
						
							|  |  |  | MOVZX(32, R(EAX), MOffset(ESI, 0)); | 
					
						
							|  |  |  | MOVZX(32, R(EBX), MOffset(ESI, 1)); | 
					
						
							|  |  |  | MOVZX(32, R(ECX), MOffset(ESI, 2)); | 
					
						
							|  |  |  | MOV(32, R(EAX), MComplex(LUTREG, EAX, 4)); | 
					
						
							|  |  |  | MOV(32, R(EBX), MComplex(LUTREG, EBX, 4)); | 
					
						
							|  |  |  | MOV(32, R(ECX), MComplex(LUTREG, ECX, 4)); | 
					
						
							|  |  |  | MOV(MOffset(EDI, 0), XMM0); | 
					
						
							|  |  |  | MOV(MOffset(EDI, 4), XMM1); | 
					
						
							|  |  |  | MOV(MOffset(EDI, 8), XMM2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSE4: | 
					
						
							|  |  |  | PINSRB(XMM0, MOffset(ESI, 0), 0); | 
					
						
							|  |  |  | PINSRB(XMM0, MOffset(ESI, 1), 4); | 
					
						
							|  |  |  | PINSRB(XMM0, MOffset(ESI, 2), 8); | 
					
						
							|  |  |  | CVTDQ2PS(XMM0, XMM0); | 
					
						
							|  |  |  | <two unpacks here to sign extend> | 
					
						
							|  |  |  | MULPS(XMM0, XMM7); | 
					
						
							|  |  |  | MOVUPS(MOffset(EDI, 0), XMM0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 									 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | // Direct
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadDirect_UByte() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = (float)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = (float)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadDirect_Byte() | 
					
						
							|  |  |  | {	 | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s8)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = (float)(s8)DataReadU8() * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadDirect_UShort() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = (float)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = (float)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadDirect_Short() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s16)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = (float)(s16)DataReadU16() * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadDirect_Float() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// No need to use floating point here.
 | 
					
						
							|  |  |  | 	((u32 *)VertexManager::s_pCurBufferPointer)[0] = DataReadU32();  | 
					
						
							|  |  |  | 	((u32 *)VertexManager::s_pCurBufferPointer)[1] = DataReadU32(); | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((u32 *)VertexManager::s_pCurBufferPointer)[2] = DataReadU32(); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | template<class T> | 
					
						
							|  |  |  | inline void Pos_ReadIndex_Byte(int Index) { | 
					
						
							|  |  |  | 	const u8* pData = cached_arraybases[ARRAY_POSITION] + ((u32)Index * arraystrides[ARRAY_POSITION]); | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(T)(*(pData))) * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(T)(*(pData+1))) * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = ((float)(T)(*(pData+2))) * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> | 
					
						
							|  |  |  | inline void Pos_ReadIndex_Short(int Index) { | 
					
						
							|  |  |  | 	const u16* pData = (const u16 *)(cached_arraybases[ARRAY_POSITION] + ((u32)Index * arraystrides[ARRAY_POSITION])); | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(T)Common::swap16(*(pData))) * posScale; | 
					
						
							|  |  |  | 	((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(T)Common::swap16(*(pData+1))) * posScale; | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = ((float)(T)Common::swap16(*(pData+2))) * posScale; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline void Pos_ReadIndex_Float(int Index) { | 
					
						
							|  |  |  | 	const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION])); | 
					
						
							|  |  |  | 	((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(*(pData)); | 
					
						
							|  |  |  | 	((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(*(pData+1)); | 
					
						
							|  |  |  | 	if (pVtxAttr->PosElements) | 
					
						
							|  |  |  | 		((u32*)VertexManager::s_pCurBufferPointer)[2] = Common::swap32(*(pData+2)); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		((float*)VertexManager::s_pCurBufferPointer)[2] = 1.0f; | 
					
						
							|  |  |  | 	LOG_VTX(); | 
					
						
							|  |  |  | 	VertexManager::s_pCurBufferPointer += 12; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | // Index 8
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex8_UByte()  | 
					
						
							|  |  |  | {  | 
					
						
							|  |  |  | 	u8 Index = DataReadU8(); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Byte<u8>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex8_Byte() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 Index = DataReadU8(); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Byte<s8>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex8_UShort() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 Index = DataReadU8(); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Short<u16>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex8_Short() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 Index = DataReadU8(); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Short<s16>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex8_Float() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 Index = DataReadU8(); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Float(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | // Index 16
 | 
					
						
							|  |  |  | // ==============================================================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex16_UByte(){ | 
					
						
							|  |  |  | 	u16 Index = DataReadU16();  | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Byte<u8>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex16_Byte(){ | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	u16 Index = DataReadU16(); | 
					
						
							|  |  |  | 	Pos_ReadIndex_Byte<s8>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex16_UShort(){ | 
					
						
							|  |  |  | 	u16 Index = DataReadU16();  | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Short<u16>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex16_Short() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 Index = DataReadU16();  | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Short<s16>(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LOADERDECL Pos_ReadIndex16_Float() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 Index = DataReadU16();  | 
					
						
							| 
									
										
										
										
											2009-02-09 21:24:32 +00:00
										 |  |  | 	Pos_ReadIndex_Float(Index); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |