Merged identical VertexManager code from DX9/DX11/OGL plugins into VideoCommon. Still...
[dolphin.git] / Source / Core / VideoCommon / Src / XFStructs.cpp
blob0b93599967bbca06db71c1df2c6cfda38301d169
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include "Common.h"
19 #include "VideoCommon.h"
20 #include "XFMemory.h"
21 #include "CPMemory.h"
22 #include "VertexManagerBase.h"
23 #include "VertexShaderManager.h"
24 #include "PixelShaderManager.h"
26 // LoadXFReg 0x10
27 void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
29 u32 address = baseAddress;
30 for (int i = 0; i < (int)transferSize; i++)
32 address = baseAddress + i;
34 // Setup a Matrix
35 if (address < XFMEM_ERROR)
37 VertexManager::Flush();
38 VertexShaderManager::InvalidateXFRange(address, address + transferSize);
39 PixelShaderManager::InvalidateXFRange(address, address + transferSize);
40 //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
42 memcpy_gc((u32*)&xfmem[address], &pData[i], transferSize*4);
43 i += transferSize;
45 else if (address >= XFMEM_SETTEXMTXINFO && address <= XFMEM_SETTEXMTXINFO+7)
47 xfregs.texcoords[address - XFMEM_SETTEXMTXINFO].texmtxinfo.hex = pData[i];
49 else if (address >= XFMEM_SETPOSMTXINFO && address <= XFMEM_SETPOSMTXINFO+7)
51 xfregs.texcoords[address - XFMEM_SETPOSMTXINFO].postmtxinfo.hex = pData[i];
53 else if (address >= XFMEM_SETVIEWPORT && address <= XFMEM_SETVIEWPORT+5)
55 VertexManager::Flush();
56 u32 Index = address - XFMEM_SETVIEWPORT;
57 VertexShaderManager::SetViewport((float*)&pData[i],Index);
58 PixelShaderManager::SetViewport((float*)&pData[i],Index);
59 if(Index == 0)
61 i += 5;
65 else if (address >= XFMEM_SETPROJECTION && address <= XFMEM_SETPROJECTION+7)
67 VertexManager::Flush();
68 u32 Index = address - XFMEM_SETPROJECTION;
69 VertexShaderManager::SetProjection((float*)&pData[i],Index);
70 if(Index == 0)
72 i += 7;
75 else if (address < 0x2000)
77 u32 data = pData[i];
78 switch (address)
80 case XFMEM_ERROR:
81 case XFMEM_DIAG:
82 case XFMEM_STATE0: // internal state 0
83 case XFMEM_STATE1: // internal state 1
84 case XFMEM_CLOCK:
85 case XFMEM_SETGPMETRIC:
86 break;
88 case XFMEM_CLIPDISABLE:
89 //if (data & 1) {} // disable clipping detection
90 //if (data & 2) {} // disable trivial rejection
91 //if (data & 4) {} // disable cpoly clipping acceleration
92 break;
94 case XFMEM_VTXSPECS: //__GXXfVtxSpecs, wrote 0004
95 xfregs.hostinfo = *(INVTXSPEC*)&data;
96 break;
98 case XFMEM_SETNUMCHAN:
99 if ((u32)xfregs.nNumChans != (data & 3))
101 VertexManager::Flush();
102 xfregs.nNumChans = data & 3;
104 break;
106 case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
107 case XFMEM_SETCHAN1_AMBCOLOR:
109 u8 chan = address - XFMEM_SETCHAN0_AMBCOLOR;
110 if (xfregs.colChans[chan].ambColor != data)
112 VertexManager::Flush();
113 xfregs.colChans[chan].ambColor = data;
114 VertexShaderManager::SetMaterialColor(chan, data);
115 PixelShaderManager::SetMaterialColor(chan, data);
117 break;
120 case XFMEM_SETCHAN0_MATCOLOR: // Channel Material Color
121 case XFMEM_SETCHAN1_MATCOLOR:
123 u8 chan = address - XFMEM_SETCHAN0_MATCOLOR;
124 if (xfregs.colChans[chan].matColor != data)
126 VertexManager::Flush();
127 xfregs.colChans[chan].matColor = data;
128 VertexShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data);
129 PixelShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data);
131 break;
134 case XFMEM_SETCHAN0_COLOR: // Channel Color
135 case XFMEM_SETCHAN1_COLOR:
137 u8 chan = address - XFMEM_SETCHAN0_COLOR;
138 if (xfregs.colChans[chan].color.hex != (data & 0x7fff))
140 VertexManager::Flush();
141 xfregs.colChans[chan].color.hex = data;
143 break;
146 case XFMEM_SETCHAN0_ALPHA: // Channel Alpha
147 case XFMEM_SETCHAN1_ALPHA:
149 u8 chan = address - XFMEM_SETCHAN0_ALPHA;
150 if (xfregs.colChans[chan].alpha.hex != (data & 0x7fff))
152 VertexManager::Flush();
153 xfregs.colChans[chan].alpha.hex = data;
155 break;
158 case XFMEM_DUALTEX:
159 if (xfregs.bEnableDualTexTransform != (data & 1))
161 VertexManager::Flush();
162 xfregs.bEnableDualTexTransform = data & 1;
164 break;
167 case XFMEM_SETMATRIXINDA:
168 //_assert_msg_(GX_XF, 0, "XF matrixindex0");
169 VertexShaderManager::SetTexMatrixChangedA(data); // ?
170 break;
171 case XFMEM_SETMATRIXINDB:
172 //_assert_msg_(GX_XF, 0, "XF matrixindex1");
173 VertexShaderManager::SetTexMatrixChangedB(data); // ?
174 break;
175 case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens
176 if ((u32)xfregs.numTexGens != data)
178 VertexManager::Flush();
179 xfregs.numTexGens = data;
181 break;
183 // --------------
184 // Unknown Regs
185 // --------------
187 // Maybe these are for Normals?
188 case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
189 case 0x1049:
190 case 0x104a:
191 case 0x104b:
192 case 0x104c:
193 case 0x104d:
194 case 0x104e:
195 case 0x104f:
196 DEBUG_LOG(VIDEO, "Possible Normal Mtx XF reg?: %x=%x\n", address, data);
197 break;
199 case 0x1013:
200 case 0x1014:
201 case 0x1015:
202 case 0x1016:
203 case 0x1017:
205 default:
206 WARN_LOG(VIDEO, "Unknown XF Reg: %x=%x\n", address, data);
207 break;
213 // TODO - verify that it is correct. Seems to work, though.
214 void LoadIndexedXF(u32 val, int array)
216 int index = val >> 16;
217 int address = val & 0xFFF; // check mask
218 int size = ((val >> 12) & 0xF) + 1;
219 //load stuff from array to address in xf mem
221 VertexManager::Flush();
222 VertexShaderManager::InvalidateXFRange(address, address+size);
223 PixelShaderManager::InvalidateXFRange(address, address+size);
224 //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size);
226 for (int i = 0; i < size; i++)
227 xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4);