GSRendererSoft.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:27k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "StdAfx.h"
  22. #include "GSRendererSoft.h"
  23. #include "x86.h"
  24. template <class Vertex>
  25. GSRendererSoft<Vertex>::GSRendererSoft(HWND hWnd, HRESULT& hr)
  26. : GSRenderer<Vertex>(640, 512, hWnd, hr)
  27. {
  28. Reset();
  29. int i = SHRT_MIN, j = 0;
  30. for(; i < 0; i++, j++) m_clip[j] = 0, m_mask[j] = j&255;
  31. for(; i < 256; i++, j++) m_clip[j] = i, m_mask[j] = j&255;
  32. for(; i < SHRT_MAX; i++, j++) m_clip[j] = 255, m_mask[j] = j&255;
  33. m_uv = (uv_wrap_t*)_aligned_malloc(sizeof(uv_wrap_t), 16);
  34. // w00t :P
  35. #define InitATST(iZTST, iATST) 
  36. m_dv[iZTST][iATST] = &GSRendererSoft<Vertex>::DrawVertex<iZTST, iATST>; 
  37. #define InitZTST(iZTST) 
  38. InitATST(iZTST, 0) 
  39. InitATST(iZTST, 1) 
  40. InitATST(iZTST, 2) 
  41. InitATST(iZTST, 3) 
  42. InitATST(iZTST, 4) 
  43. InitATST(iZTST, 5) 
  44. InitATST(iZTST, 6) 
  45. InitATST(iZTST, 7) 
  46. #define InitDV() 
  47. InitZTST(0) 
  48. InitZTST(1) 
  49. InitZTST(2) 
  50. InitZTST(3) 
  51. InitDV();
  52. #define InitTFX(iLOD, bLCM, bTCC, iTFX) 
  53. m_dvtfx[iLOD][bLCM][bTCC][iTFX] = &GSRendererSoft<Vertex>::DrawVertexTFX<iLOD, bLCM, bTCC, iTFX>; 
  54. #define InitTCC(iLOD, bLCM, bTCC) 
  55. InitTFX(iLOD, bLCM, bTCC, 0) 
  56. InitTFX(iLOD, bLCM, bTCC, 1) 
  57. InitTFX(iLOD, bLCM, bTCC, 2) 
  58. InitTFX(iLOD, bLCM, bTCC, 3) 
  59. #define InitLCM(iLOD, bLCM) 
  60. InitTCC(iLOD, bLCM, false) 
  61. InitTCC(iLOD, bLCM, true) 
  62. #define InitLOD(iLOD) 
  63. InitLCM(iLOD, false) 
  64. InitLCM(iLOD, true) 
  65. #define InitDVTFX() 
  66. InitLOD(0) 
  67. InitLOD(1) 
  68. InitLOD(2) 
  69. InitLOD(3) 
  70. InitDVTFX();
  71. }
  72. template <class Vertex>
  73. GSRendererSoft<Vertex>::~GSRendererSoft()
  74. {
  75. _aligned_free(m_uv);
  76. }
  77. template <class Vertex>
  78. HRESULT GSRendererSoft<Vertex>::ResetDevice(bool fForceWindowed)
  79. {
  80. m_pRT[0] = NULL;
  81. m_pRT[1] = NULL;
  82. return __super::ResetDevice(fForceWindowed);
  83. }
  84. template <class Vertex>
  85. void GSRendererSoft<Vertex>::Reset()
  86. {
  87. m_primtype = PRIM_NONE;
  88. m_pTexture = NULL;
  89. __super::Reset();
  90. }
  91. template <class Vertex>
  92. int GSRendererSoft<Vertex>::DrawingKick(bool fSkip)
  93. {
  94. Vertex* pVertices = &m_pVertices[m_nVertices];
  95. int nVertices = 0;
  96. switch(m_PRIM)
  97. {
  98. case 3: // triangle list
  99. m_primtype = PRIM_TRIANGLE;
  100. m_vl.RemoveAt(0, pVertices[nVertices++]);
  101. m_vl.RemoveAt(0, pVertices[nVertices++]);
  102. m_vl.RemoveAt(0, pVertices[nVertices++]);
  103. LOGV((pVertices[0], _T("TriList")));
  104. LOGV((pVertices[1], _T("TriList")));
  105. LOGV((pVertices[2], _T("TriList")));
  106. break;
  107. case 4: // triangle strip
  108. m_primtype = PRIM_TRIANGLE;
  109. m_vl.RemoveAt(0, pVertices[nVertices++]);
  110. m_vl.GetAt(0, pVertices[nVertices++]);
  111. m_vl.GetAt(1, pVertices[nVertices++]);
  112. LOGV((pVertices[0], _T("TriStrip")));
  113. LOGV((pVertices[1], _T("TriStrip")));
  114. LOGV((pVertices[2], _T("TriStrip")));
  115. break;
  116. case 5: // triangle fan
  117. m_primtype = PRIM_TRIANGLE;
  118. m_vl.GetAt(0, pVertices[nVertices++]);
  119. m_vl.RemoveAt(1, pVertices[nVertices++]);
  120. m_vl.GetAt(1, pVertices[nVertices++]);
  121. LOGV((pVertices[0], _T("TriFan")));
  122. LOGV((pVertices[1], _T("TriFan")));
  123. LOGV((pVertices[2], _T("TriFan")));
  124. break;
  125. case 6: // sprite
  126. m_primtype = PRIM_SPRITE;
  127. m_vl.RemoveAt(0, pVertices[nVertices++]);
  128. m_vl.RemoveAt(0, pVertices[nVertices++]);
  129. nVertices += 2;
  130. pVertices[0].p.z = pVertices[1].p.z;
  131. pVertices[0].p.q = pVertices[1].p.q;
  132. pVertices[2] = pVertices[1];
  133. pVertices[3] = pVertices[1];
  134. pVertices[1].p.y = pVertices[0].p.y;
  135. pVertices[1].t.y = pVertices[0].t.y;
  136. pVertices[2].p.x = pVertices[0].p.x;
  137. pVertices[2].t.x = pVertices[0].t.x;
  138. LOGV((pVertices[0], _T("Sprite")));
  139. LOGV((pVertices[1], _T("Sprite")));
  140. LOGV((pVertices[2], _T("Sprite")));
  141. LOGV((pVertices[3], _T("Sprite")));
  142. /*
  143. m_primtype = PRIM_TRIANGLE;
  144. nVertices += 2;
  145. pVertices[5] = pVertices[3];
  146. pVertices[3] = pVertices[1];
  147. pVertices[4] = pVertices[2];
  148. */
  149. break;
  150. case 1: // line
  151. m_primtype = PRIM_LINE;
  152. m_vl.RemoveAt(0, pVertices[nVertices++]);
  153. m_vl.RemoveAt(0, pVertices[nVertices++]);
  154. LOGV((pVertices[0], _T("LineList")));
  155. LOGV((pVertices[1], _T("LineList")));
  156. break;
  157. case 2: // line strip
  158. m_primtype = PRIM_LINE;
  159. m_vl.RemoveAt(0, pVertices[nVertices++]);
  160. m_vl.GetAt(0, pVertices[nVertices++]);
  161. LOGV((pVertices[0], _T("LineStrip")));
  162. LOGV((pVertices[1], _T("LineStrip")));
  163. break;
  164. case 0: // point
  165. m_primtype = PRIM_POINT;
  166. m_vl.RemoveAt(0, pVertices[nVertices++]);
  167. LOGV((pVertices[0], _T("PointList")));
  168. break;
  169. default:
  170. ASSERT(0);
  171. return 0;
  172. }
  173. if(fSkip || !m_rs.IsEnabled(0) && !m_rs.IsEnabled(1))
  174. return 0;
  175. if(!m_pPRIM->IIP)
  176. {
  177. Vertex::Vector c = pVertices[nVertices-1].c;
  178. for(int i = 0; i < nVertices-1; i++) 
  179. pVertices[i].c = c;
  180. }
  181. return nVertices;
  182. }
  183. template <class Vertex>
  184. void GSRendererSoft<Vertex>::FlushPrim()
  185. {
  186. if(m_nVertices > 0)
  187. {
  188. CString fn;
  189. static int s_savenum = 0;
  190. s_savenum++;
  191. if(0)
  192. //if(m_ctxt->FRAME.Block() == 0x008c0 && (DWORD)m_ctxt->TEX0.TBP0 == 0x03a98)
  193. //if(m_ctxt->TEX0.PSM == 0x1b)
  194. if(m_perfmon.GetFrame() >= 200)
  195. {
  196. fn.Format(_T("g:/tmp/%04I64d_%06d_1f_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, m_ctxt->FRAME.Block(), m_ctxt->FRAME.PSM);
  197. m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->FRAME.Block(), m_ctxt->FRAME.FBW, m_ctxt->FRAME.PSM, m_ctxt->FRAME.FBW*64, 224);
  198. if(m_pPRIM->TME)
  199. {
  200. fn.Format(_T("g:/tmp/%04I64d_%06d_2t_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, (DWORD)m_ctxt->TEX0.TBP0, (DWORD)m_ctxt->TEX0.PSM);
  201. m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->TEX0.TBP0, m_ctxt->TEX0.TBW, m_ctxt->TEX0.PSM, 1 << m_ctxt->TEX0.TW, 1 << m_ctxt->TEX0.TH);
  202. }
  203. }
  204. int iZTST = !m_ctxt->TEST.ZTE ? 1 : m_ctxt->TEST.ZTST;
  205. int iATST = !m_ctxt->TEST.ATE ? 1 : m_ctxt->TEST.ATST;
  206. m_pDrawVertex = m_dv[iZTST][iATST];
  207. if(m_pPRIM->TME)
  208. {
  209. int iLOD = (m_ctxt->TEX1.MMAG & 1) + (m_ctxt->TEX1.MMIN & 1);
  210. int bLCM = m_ctxt->TEX1.LCM ? 1 : 0;
  211. int bTCC = m_ctxt->TEX0.TCC ? 1 : 0;
  212. int iTFX = m_ctxt->TEX0.TFX;
  213. if(m_pPRIM->FST)
  214. {
  215. iLOD = 3;
  216. bLCM = m_ctxt->TEX1.K <= 0 && (m_ctxt->TEX1.MMAG & 1) || m_ctxt->TEX1.K > 0 && (m_ctxt->TEX1.MMIN & 1);
  217. }
  218. m_pDrawVertexTFX = m_dvtfx[iLOD][bLCM][bTCC][iTFX];
  219. }
  220. SetupTexture();
  221. m_scissor.SetRect(
  222. max(m_ctxt->SCISSOR.SCAX0, 0),
  223. max(m_ctxt->SCISSOR.SCAY0, 0),
  224. min(m_ctxt->SCISSOR.SCAX1+1, m_ctxt->FRAME.FBW * 64),
  225. min(m_ctxt->SCISSOR.SCAY1+1, 4096));
  226. m_clamp = (m_de.COLCLAMP.CLAMP ? m_clip : m_mask) + 32768;
  227. int nPrims = 0;
  228. Vertex* pVertices = m_pVertices;
  229. switch(m_primtype)
  230. {
  231. case PRIM_SPRITE:
  232. ASSERT(!(m_nVertices&3));
  233. nPrims = m_nVertices / 4;
  234. LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)n"), m_primtype, m_nVertices, nPrims);
  235. for(int i = 0; i < nPrims; i++, pVertices += 4) DrawSprite(pVertices);
  236. break;
  237. case PRIM_TRIANGLE:
  238. ASSERT(!(m_nVertices%3));
  239. nPrims = m_nVertices / 3;
  240. LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)n"), m_primtype, m_nVertices, nPrims);
  241. for(int i = 0; i < nPrims; i++, pVertices += 3) DrawTriangle(pVertices);
  242. break;
  243. case PRIM_LINE: 
  244. ASSERT(!(m_nVertices&1));
  245. nPrims = m_nVertices / 2;
  246. LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)n"), m_primtype, m_nVertices, nPrims);
  247. for(int i = 0; i < nPrims; i++, pVertices += 2) DrawLine(pVertices);
  248. break;
  249. case PRIM_POINT:
  250. nPrims = m_nVertices;
  251. LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)n"), m_primtype, m_nVertices, nPrims);
  252. for(int i = 0; i < nPrims; i++, pVertices++) DrawPoint(pVertices);
  253. break;
  254. default:
  255. ASSERT(m_nVertices == 0);
  256. return;
  257. }
  258. m_perfmon.IncCounter(GSPerfMon::c_prim, nPrims);
  259. if(0)
  260. //if(m_ctxt->FRAME.Block() == 0x008c0 && (DWORD)m_ctxt->TEX0.TBP0 == 0x03a98)
  261. //if(m_ctxt->TEX0.PSM == 0x1b)
  262. if(m_perfmon.GetFrame() >= 200)
  263. {
  264. fn.Format(_T("g:/tmp/%04I64d_%06d_3f_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, m_ctxt->FRAME.Block(), m_ctxt->FRAME.PSM);
  265. m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->FRAME.Block(), m_ctxt->FRAME.FBW, m_ctxt->FRAME.PSM, m_ctxt->FRAME.FBW*64, 224);
  266. }
  267. }
  268. m_primtype = PRIM_NONE;
  269. __super::FlushPrim();
  270. }
  271. template <class Vertex>
  272. void GSRendererSoft<Vertex>::Flip()
  273. {
  274. HRESULT hr;
  275. FlipInfo rt[2];
  276. for(int i = 0; i < countof(rt); i++)
  277. {
  278. if(m_rs.IsEnabled(i))
  279. {
  280. CRect rect = CRect(CPoint(0, 0), m_rs.GetDispRect(i).BottomRight());
  281. //GSLocalMemory::RoundUp(, GSLocalMemory::GetBlockSize(m_rs.DISPFB[i].PSM));
  282. ZeroMemory(&rt[i].rd, sizeof(rt[i].rd));
  283. if(m_pRT[i]) m_pRT[i]->GetLevelDesc(0, &rt[i].rd);
  284. if(rt[i].rd.Width != rect.right || rt[i].rd.Height != rect.bottom)
  285. m_pRT[i] = NULL;
  286. if(!m_pRT[i])
  287. {
  288. CComPtr<IDirect3DTexture9> pRT;
  289. D3DLOCKED_RECT lr;
  290. int nTries = 0, nMaxTries = 10;
  291. do
  292. {
  293. pRT = NULL;
  294. hr = m_pD3DDev->CreateTexture(rect.right, rect.bottom, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pRT, NULL);
  295. if(FAILED(hr)) break;
  296. if(SUCCEEDED(pRT->LockRect(0, &lr, NULL, 0)))
  297. pRT->UnlockRect(0);
  298. m_pRT[i] = pRT;
  299. }
  300. while((((DWORD_PTR)lr.pBits & 0xf) || (lr.Pitch & 0xf)) && ++nTries < nMaxTries);
  301. if(nTries == nMaxTries) continue;
  302. ZeroMemory(&rt[i].rd, sizeof(rt[i].rd));
  303. hr = m_pRT[i]->GetLevelDesc(0, &rt[i].rd);
  304. }
  305. rt[i].pRT = m_pRT[i];
  306. rt[i].scale = scale_t(1, 1);
  307. D3DLOCKED_RECT lr;
  308. if(FAILED(hr = rt[i].pRT->LockRect(0, &lr, NULL, 0)))
  309. continue;
  310. GIFRegTEX0 TEX0;
  311. TEX0.TBP0 = m_rs.DISPFB[i].FBP<<5;
  312. TEX0.TBW = m_rs.DISPFB[i].FBW;
  313. TEX0.PSM = m_rs.DISPFB[i].PSM;
  314. GIFRegCLAMP CLAMP;
  315. CLAMP.WMS = CLAMP.WMT = 1;
  316. #ifdef DEBUG_RENDERTARGETS
  317. if(::GetAsyncKeyState(VK_SPACE)&0x80000000)
  318. {
  319. TEX0.TBP0 = m_ctxt->FRAME.Block();
  320. TEX0.TBW = m_ctxt->FRAME.FBW;
  321. TEX0.PSM = m_ctxt->FRAME.PSM;
  322. }
  323. MSG msg;
  324. ZeroMemory(&msg, sizeof(msg));
  325. while(msg.message != WM_QUIT)
  326. {
  327. if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
  328. {
  329. TranslateMessage(&msg);
  330. DispatchMessage(&msg);
  331. }
  332. else if(!(::GetAsyncKeyState(VK_RCONTROL)&0x80000000))
  333. {
  334. break;
  335. }
  336. }
  337. if(::GetAsyncKeyState(VK_LCONTROL)&0x80000000)
  338. Sleep(500);
  339. #endif
  340. m_lm.ReadTexture(rect, (BYTE*)lr.pBits, lr.Pitch, TEX0, m_de.TEXA, CLAMP);
  341. rt[i].pRT->UnlockRect(0);
  342. }
  343. }
  344. FinishFlip(rt);
  345. }
  346. template <class Vertex>
  347. void GSRendererSoft<Vertex>::EndFrame()
  348. {
  349. }
  350. template <class Vertex>
  351. void GSRendererSoft<Vertex>::RowInit(int x, int y)
  352. {
  353. m_faddr_x0 = (m_ctxt->ftbl->pa)(0, y, m_ctxt->FRAME.FBP<<5, m_ctxt->FRAME.FBW);
  354. m_zaddr_x0 = (m_ctxt->ztbl->pa)(0, y, m_ctxt->ZBUF.ZBP<<5, m_ctxt->FRAME.FBW);
  355. m_faddr_ro = &m_ctxt->ftbl->rowOffset[y&7][x];
  356. m_zaddr_ro = &m_ctxt->ztbl->rowOffset[y&7][x];
  357. m_fx = x-1; // -1 because RowStep() will do +1, yea lame...
  358. m_fy = y;
  359. RowStep();
  360. }
  361. template <class Vertex>
  362. void GSRendererSoft<Vertex>::RowStep()
  363. {
  364. m_fx++;
  365. m_faddr = m_faddr_x0 + *m_faddr_ro++;
  366. m_zaddr = m_zaddr_x0 + *m_zaddr_ro++;
  367. }
  368. template <class Vertex>
  369. void GSRendererSoft<Vertex>::DrawPoint(Vertex* v)
  370. {
  371. CPoint p = *v;
  372. if(!m_scissor.PtInRect(p))
  373. {
  374. RowInit(p.x, p.y);
  375. (this->*m_pDrawVertex)(*v);
  376. }
  377. }
  378. template <class Vertex>
  379. void GSRendererSoft<Vertex>::DrawLine(Vertex* v)
  380. {
  381. Vertex dv = v[1] - v[0];
  382. Vertex::Vector dp = dv.p;
  383. dp.x.abs();
  384. dp.y.abs();
  385. int dx = (int)dp.x;
  386. int dy = (int)dp.y;
  387. if(dx == 0 && dy == 0) return;
  388. int i = dx > dy ? 0 : 1;
  389. Vertex edge = v[0];
  390. Vertex dedge = dv / dp.v[i];
  391. // TODO: clip with the scissor
  392. int steps = (int)dp.v[i];
  393. while(steps-- > 0)
  394. {
  395. CPoint p = edge;
  396. if(m_scissor.PtInRect(p))
  397. {
  398. RowInit(p.x, p.y);
  399. (this->*m_pDrawVertex)(edge);
  400. }
  401. edge += dedge;
  402. }
  403. }
  404. template <class Vertex>
  405. void GSRendererSoft<Vertex>::DrawTriangle(Vertex* v)
  406. {
  407. if(v[1].p.y < v[0].p.y) {Exchange(&v[0], &v[1]);}
  408. if(v[2].p.y < v[0].p.y) {Exchange(&v[0], &v[2]);}
  409. if(v[2].p.y < v[1].p.y) {Exchange(&v[1], &v[2]);}
  410. if(!(v[0].p.y < v[2].p.y)) return;
  411. Vertex v01 = v[1] - v[0];
  412. Vertex v02 = v[2] - v[0];
  413. Vertex::Scalar temp = v01.p.y / v02.p.y;
  414. Vertex::Scalar longest = temp * v02.p.x - v01.p.x;
  415. int ledge, redge;
  416. if(Vertex::Scalar(0) < longest) {ledge = 0; redge = 1; if(longest < Vertex::Scalar(1)) longest = Vertex::Scalar(1);}
  417. else if(longest < Vertex::Scalar(0)) {ledge = 1; redge = 0; if(Vertex::Scalar(-1) < longest) longest = Vertex::Scalar(-1);}
  418. else return;
  419. Vertex edge[2] = {v[0], v[0]};
  420. Vertex dedge[2];
  421. dedge[0].p.y = dedge[1].p.y = Vertex::Scalar(1);
  422. if(Vertex::Scalar(0) < v01.p.y) dedge[ledge] = v01 / v01.p.y;
  423. if(Vertex::Scalar(0) < v02.p.y) dedge[redge] = v02 / v02.p.y;
  424. Vertex scan;
  425. Vertex dscan = (v02 * temp - v01) / longest;
  426. dscan.p.y = 0;
  427. for(int i = 0; i < 2; i++, v++)
  428. int top = edge[0].p.y.ceil_i(), bottom = v[1].p.y.ceil_i();
  429. if(top < m_scissor.top) top = min(m_scissor.top, bottom);
  430. if(bottom > m_scissor.bottom) bottom = m_scissor.bottom;
  431. if(edge[0].p.y < Vertex::Scalar(top)) // for(int j = 0; j < 2; j++) edge[j] += dedge[j] * ((float)top - edge[0].p.y);
  432. {
  433. Vertex::Scalar dy = Vertex::Scalar(top) - edge[0].p.y;
  434. edge[0] += dedge[0] * dy;
  435. edge[1].p.x += dedge[1].p.x * dy;
  436. edge[0].p.y = edge[1].p.y = Vertex::Scalar(top);
  437. }
  438. ASSERT(top >= bottom || (int)((edge[1].p.y - edge[0].p.y) * 10) == 0);
  439. for(; top < bottom; top++)
  440. {
  441. scan = edge[0];
  442. int left = edge[0].p.x.ceil_i(), right = edge[1].p.x.ceil_i();
  443. if(left < m_scissor.left) left = m_scissor.left;
  444. if(right > m_scissor.right) right = m_scissor.right;
  445. if(edge[0].p.x < Vertex::Scalar(left))
  446. {
  447. scan += dscan * (Vertex::Scalar(left) - edge[0].p.x);
  448. scan.p.x = Vertex::Scalar(left);
  449. }
  450. RowInit(left, top);
  451. for(int steps = right - left; steps > 0; steps--)
  452. {
  453. (this->*m_pDrawVertex)(scan);
  454. scan += dscan;
  455. RowStep();
  456. }
  457. // for(int j = 0; j < 2; j++) edge[j] += dedge[j];
  458. edge[0] += dedge[0];
  459. edge[1].p += dedge[1].p;
  460. }
  461. if(v[1].p.y < v[2].p.y)
  462. {
  463. edge[ledge] = v[1];
  464. dedge[ledge] = (v[2] - v[1]) / (v[2].p.y - v[1].p.y);
  465. edge[ledge] += dedge[ledge] * (edge[ledge].p.y.ceil_s() - edge[ledge].p.y);
  466. }
  467. }
  468. }
  469. template <class Vertex>
  470. void GSRendererSoft<Vertex>::DrawSprite(Vertex* v)
  471. {
  472. if(v[2].p.y < v[0].p.y) {Exchange(&v[0], &v[2]); Exchange(&v[1], &v[3]);}
  473. if(v[1].p.x < v[0].p.x) {Exchange(&v[0], &v[1]); Exchange(&v[2], &v[3]);}
  474. if(v[0].p.x == v[1].p.x || v[0].p.y == v[2].p.y) return;
  475. Vertex v01 = v[1] - v[0];
  476. Vertex v02 = v[2] - v[0];
  477. Vertex edge = v[0];
  478. Vertex dedge = v02 / v02.p.y;
  479. Vertex scan;
  480. Vertex dscan = v01 / v01.p.x;
  481. int top = v[0].p.y.ceil_i(), bottom = v[2].p.y.ceil_i();
  482. if(top < m_scissor.top) top = min(m_scissor.top, bottom);
  483. if(bottom > m_scissor.bottom) bottom = m_scissor.bottom;
  484. if(v[0].p.y < Vertex::Scalar(top)) edge += dedge * (Vertex::Scalar(top) - v[0].p.y);
  485. int left = v[0].p.x.ceil_i(), right = v[1].p.x.ceil_i();
  486. if(left < m_scissor.left) left = m_scissor.left;
  487. if(right > m_scissor.right) right = m_scissor.right;
  488. if(v[0].p.x < Vertex::Scalar(left)) edge += dscan * (Vertex::Scalar(left) - v[0].p.x);
  489. if(DrawFilledRect(left, top, right, bottom, edge))
  490. return;
  491. for(; top < bottom; top++)
  492. {
  493. scan = edge;
  494. RowInit(left, top);
  495. for(int steps = right - left; steps > 0; steps--)
  496. {
  497. (this->*m_pDrawVertex)(scan);
  498. scan += dscan;
  499. RowStep();
  500. }
  501. edge += dedge;
  502. }
  503. }
  504. template <class Vertex>
  505. bool GSRendererSoft<Vertex>::DrawFilledRect(int left, int top, int right, int bottom, const Vertex& v)
  506. {
  507. if(left >= right || top >= bottom)
  508. return false;
  509. ASSERT(top >= 0);
  510. ASSERT(bottom >= 0);
  511. if(m_pPRIM->IIP
  512. || m_ctxt->TEST.ZTE && m_ctxt->TEST.ZTST != 1
  513. || m_ctxt->TEST.ATE && m_ctxt->TEST.ATST != 1
  514. || m_ctxt->TEST.DATE
  515. || m_pPRIM->TME
  516. || m_pPRIM->ABE
  517. || m_pPRIM->FGE
  518. || m_de.DTHE.DTHE
  519. || m_ctxt->FRAME.FBMSK)
  520. return false;
  521. DWORD FBP = m_ctxt->FRAME.FBP<<5, FBW = m_ctxt->FRAME.FBW;
  522. DWORD ZBP = m_ctxt->ZBUF.ZBP<<5;
  523. if(!m_ctxt->ZBUF.ZMSK)
  524. {
  525. m_lm.FillRect(CRect(left, top, right, bottom), v.GetZ(), m_ctxt->ZBUF.PSM, ZBP, FBW);
  526. }
  527. __declspec(align(16)) union {struct {short Rf, Gf, Bf, Af;}; UINT64 Cui64;};
  528. Cui64 = v.c;
  529. Rf = m_clamp[Rf];
  530. Gf = m_clamp[Gf];
  531. Bf = m_clamp[Bf];
  532. Af |= m_ctxt->FBA.FBA << 7;
  533. DWORD Cdw;
  534. if(m_ctxt->FRAME.PSM == PSM_PSMCT16 || m_ctxt->FRAME.PSM == PSM_PSMCT16S)
  535. {
  536. Cdw = ((DWORD)(Rf&0xf8) >> 3)
  537. | ((DWORD)(Gf&0xf8) << 2) 
  538. | ((DWORD)(Bf&0xf8) << 7) 
  539. | ((DWORD)(Af&0x80) << 8);
  540. }
  541. else
  542. {
  543. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  544. __m128i r0 = _mm_load_si128((__m128i*)&Cui64);
  545. Cdw = (DWORD)_mm_cvtsi128_si32(_mm_packus_epi16(r0, r0));
  546. #else
  547. Cdw = ((DWORD)(Rf&0xff) << 0)
  548. | ((DWORD)(Gf&0xff) << 8) 
  549. | ((DWORD)(Bf&0xff) << 16) 
  550. | ((DWORD)(Af&0xff) << 24);
  551. #endif
  552. }
  553. m_lm.FillRect(CRect(left, top, right, bottom), Cdw, m_ctxt->FRAME.PSM, FBP, FBW);
  554. return true;
  555. }
  556. template <class Vertex>
  557. template <int iZTST, int iATST>
  558. void GSRendererSoft<Vertex>::DrawVertex(const Vertex& v)
  559. {
  560. DWORD vz;
  561. switch(iZTST)
  562. {
  563. case 0: return;
  564. case 1: break;
  565. case 2: vz = v.GetZ(); if(vz < (m_lm.*m_ctxt->ztbl->rpa)(m_zaddr)) return; break;
  566. case 3: vz = v.GetZ(); if(vz <= (m_lm.*m_ctxt->ztbl->rpa)(m_zaddr)) return; break;
  567. default: __assume(0);
  568. }
  569. union
  570. {
  571. struct {Vertex::Vector Cf, Cd, Ca;};
  572. struct {Vertex::Vector Cfda[3];};
  573. };
  574. Cf = v.c;
  575. if(m_pPRIM->TME)
  576. {
  577. (this->*m_pDrawVertexTFX)(Cf, v);
  578. }
  579. if(m_pPRIM->FGE)
  580. {
  581. Vertex::Scalar a = Cf.a;
  582. Vertex::Vector Cfog((DWORD)m_de.FOGCOL.ai32[0]);
  583. Cf = Cfog + (Cf - Cfog) * v.t.z;
  584. Cf.a = a;
  585. }
  586. BOOL ZMSK = m_ctxt->ZBUF.ZMSK;
  587. DWORD FBMSK = m_ctxt->FRAME.FBMSK;
  588. bool fAlphaPass = true;
  589. BYTE Af = (BYTE)(int)Cf.a;
  590. switch(iATST)
  591. {
  592. case 0: fAlphaPass = false; break;
  593. case 1: fAlphaPass = true; break;
  594. case 2: fAlphaPass = Af < m_ctxt->TEST.AREF; break;
  595. case 3: fAlphaPass = Af <= m_ctxt->TEST.AREF; break;
  596. case 4: fAlphaPass = Af == m_ctxt->TEST.AREF; break;
  597. case 5: fAlphaPass = Af >= m_ctxt->TEST.AREF; break;
  598. case 6: fAlphaPass = Af > m_ctxt->TEST.AREF; break;
  599. case 7: fAlphaPass = Af != m_ctxt->TEST.AREF; break;
  600. default: __assume(0);
  601. }
  602. if(!fAlphaPass)
  603. {
  604. switch(m_ctxt->TEST.AFAIL)
  605. {
  606. case 0: return;
  607. case 1: ZMSK = 1; break; // RGBA
  608. case 2: FBMSK = 0xffffffff; break; // Z
  609. case 3: FBMSK = 0xff000000; ZMSK = 1; break; // RGB
  610. default: __assume(0);
  611. }
  612. }
  613. if(!ZMSK)
  614. {
  615. if(iZTST != 2 && iZTST != 3) vz = v.GetZ(); 
  616. (m_lm.*m_ctxt->ztbl->wpa)(m_zaddr, vz);
  617. }
  618. if(FBMSK != ~0)
  619. {
  620. if(m_ctxt->TEST.DATE && m_ctxt->FRAME.PSM <= PSM_PSMCT16S && m_ctxt->FRAME.PSM != PSM_PSMCT24)
  621. {
  622. BYTE A = (BYTE)((m_lm.*m_ctxt->ftbl->rpa)(m_faddr) >> (m_ctxt->FRAME.PSM == PSM_PSMCT32 ? 31 : 15));
  623. if(A ^ m_ctxt->TEST.DATM) return;
  624. }
  625. // FIXME: for AA1 the value of Af should be calculated from the pixel coverage...
  626. bool fABE = (m_pPRIM->ABE || m_pPRIM->AA1 && (m_pPRIM->PRIM == 1 || m_pPRIM->PRIM == 2)) && (!m_de.PABE.PABE || (int)Cf.a >= 0x80);
  627. if(FBMSK || fABE)
  628. {
  629. GIFRegTEXA TEXA;
  630. /*
  631. TEXA.AEM = 0;
  632. TEXA.TA0 = 0;
  633. TEXA.TA1 = 0x80;
  634. */
  635. TEXA.ai32[0] = 0;
  636. TEXA.ai32[1] = 0x80;
  637. Cd = (m_lm.*m_ctxt->ftbl->rta)(m_faddr, m_ctxt->TEX0, TEXA);
  638. }
  639. if(fABE)
  640. {
  641. Ca = Vertex::Vector(Vertex::Scalar(0));
  642. Ca.a = Vertex::Scalar((int)m_ctxt->ALPHA.FIX);
  643. Vertex::Scalar a = Cf.a;
  644. Cf = ((Cfda[m_ctxt->ALPHA.A] - Cfda[m_ctxt->ALPHA.B]) * Cfda[m_ctxt->ALPHA.C].a >> 7) + Cfda[m_ctxt->ALPHA.D];
  645. Cf.a = a;
  646. }
  647. DWORD Cdw; 
  648. if(m_de.COLCLAMP.CLAMP && !m_de.DTHE.DTHE)
  649. {
  650. Cdw = Cf;
  651. }
  652. else
  653. {
  654. __declspec(align(16)) union {struct {short Rf, Gf, Bf, Af;}; UINT64 Cui64;};
  655. Cui64 = Cf;
  656. if(m_de.DTHE.DTHE)
  657. {
  658. short DMxy = (signed char)((*((WORD*)&m_de.DIMX.i64 + (m_fy&3)) >> ((m_fx&3)<<2)) << 5) >> 5;
  659. Rf += DMxy;
  660. Gf += DMxy;
  661. Bf += DMxy;
  662. }
  663. Rf = m_clamp[Rf];
  664. Gf = m_clamp[Gf];
  665. Bf = m_clamp[Bf];
  666. Af |= m_ctxt->FBA.FBA << 7;
  667. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  668. __m128i r0 = _mm_load_si128((__m128i*)&Cui64);
  669. Cdw = (DWORD)_mm_cvtsi128_si32(_mm_packus_epi16(r0, r0));
  670. #else
  671. Cdw = ((DWORD)(Rf&0xff) << 0)
  672. | ((DWORD)(Gf&0xff) << 8) 
  673. | ((DWORD)(Bf&0xff) << 16) 
  674. | ((DWORD)(Af&0xff) << 24);
  675. #endif
  676. }
  677. if(FBMSK != 0)
  678. {
  679. Cdw = (Cdw & ~FBMSK) | ((DWORD)Cd & FBMSK);
  680. }
  681. (m_lm.*m_ctxt->ftbl->wfa)(m_faddr, Cdw);
  682. }
  683. }
  684. static const float one_over_log2 = 1.0f / log(2.0f);
  685. template <class Vertex>
  686. template <int iLOD, bool bLCM, bool bTCC, int iTFX>
  687. void GSRendererSoft<Vertex>::DrawVertexTFX(typename Vertex::Vector& Cf, const Vertex& v)
  688. {
  689. ASSERT(m_pPRIM->TME);
  690. Vertex::Vector t = v.t;
  691. bool fBiLinear = iLOD == 2; 
  692. if(iLOD == 3)
  693. {
  694. fBiLinear = bLCM;
  695. }
  696. else
  697. {
  698. t.q.rcp();
  699. t *= t.q;
  700. if(iLOD == 1)
  701. {
  702. float lod = (float)(int)m_ctxt->TEX1.K;
  703. if(!bLCM) lod += log(fabs((float)t.q)) * one_over_log2 * (1 << m_ctxt->TEX1.L);
  704. fBiLinear = lod <= 0 && (m_ctxt->TEX1.MMAG & 1) || lod > 0 && (m_ctxt->TEX1.MMIN & 1);
  705. }
  706. }
  707. if(fBiLinear) t -= Vertex::Scalar(0.5f);
  708. __declspec(align(16)) short ituv[8] = {(int)t.x, (int)t.x+1, (int)t.y, (int)t.y+1};
  709. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  710. __m128i uv = _mm_load_si128((__m128i*)ituv);
  711. __m128i mask = _mm_load_si128((__m128i*)m_uv->mask);
  712. __m128i region = _mm_or_si128(_mm_and_si128(uv, *(__m128i*)m_uv->and), *(__m128i*)m_uv->or);
  713. __m128i clamp = _mm_min_epi16(_mm_max_epi16(uv, *(__m128i*)m_uv->min), *(__m128i*)m_uv->max);
  714. _mm_store_si128((__m128i*)ituv, _mm_or_si128(_mm_and_si128(region, mask), _mm_andnot_si128(mask, clamp)));
  715. #else
  716. for(int i = 0; i < 4; i++)
  717. {
  718. short region = (ituv[i] & m_uv->and[i]) | m_uv->or[i];
  719. short clamp = ituv[i] < m_uv->min[i] ? m_uv->min[i] : ituv[i] > m_uv->max[i] ? m_uv->max[i] : ituv[i];
  720. ituv[i] = (region & m_uv->mask[i]) | (clamp & ~m_uv->mask[i]);
  721. }
  722. #endif
  723. Vertex::Vector Ct[4];
  724. if(fBiLinear)
  725. {
  726. if(0 && m_pTexture)
  727. {
  728. Ct[0] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[0]];
  729. Ct[1] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[1]];
  730. Ct[2] = m_pTexture[(ituv[3] << m_ctxt->TEX0.TW) + ituv[0]];
  731. Ct[3] = m_pTexture[(ituv[3] << m_ctxt->TEX0.TW) + ituv[1]];
  732. }
  733. else
  734. {
  735. Ct[0] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[2], m_ctxt->TEX0, m_de.TEXA);
  736. Ct[1] = (m_lm.*m_ctxt->ttbl->rt)(ituv[1], ituv[2], m_ctxt->TEX0, m_de.TEXA);
  737. Ct[2] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[3], m_ctxt->TEX0, m_de.TEXA);
  738. Ct[3] = (m_lm.*m_ctxt->ttbl->rt)(ituv[1], ituv[3], m_ctxt->TEX0, m_de.TEXA);
  739. }
  740. Vertex::Vector ft = t - t.floor();
  741. Ct[0] = Ct[0] + (Ct[1] - Ct[0]) * ft.x;
  742. Ct[2] = Ct[2] + (Ct[3] - Ct[2]) * ft.x;
  743. Ct[0] = Ct[0] + (Ct[2] - Ct[0]) * ft.y;
  744. }
  745. else 
  746. {
  747. if(0 && m_pTexture)
  748. {
  749. Ct[0] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[0]];
  750. }
  751. else
  752. {
  753. Ct[0] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[2], m_ctxt->TEX0, m_de.TEXA);
  754. }
  755. }
  756. Vertex::Scalar a = Cf.a;
  757. switch(iTFX)
  758. {
  759. case 0:
  760. Cf = (Cf * Ct[0] >> 7);
  761. if(!bTCC) Cf.a = a;
  762. break;
  763. case 1:
  764. Cf = Ct[0];
  765. break;
  766. case 2:
  767. Cf = (Cf * Ct[0] >> 7) + Cf.a;
  768. Cf.a = !bTCC ? a : (Ct[0].a + a);
  769. break;
  770. case 3:
  771. Cf = (Cf * Ct[0] >> 7) + Cf.a;
  772. Cf.a = !bTCC ? a : Ct[0].a;
  773. break;
  774. default: 
  775. __assume(0);
  776. }
  777. Cf.sat();
  778. }
  779. template <class Vertex>
  780. void GSRendererSoft<Vertex>::SetupTexture()
  781. {
  782. if(!m_pPRIM->TME) return;
  783. m_lm.SetupCLUT32(m_ctxt->TEX0, m_de.TEXA);
  784. //
  785. int tw = 1 << m_ctxt->TEX0.TW;
  786. int th = 1 << m_ctxt->TEX0.TH;
  787. switch(m_ctxt->CLAMP.WMS)
  788. {
  789. case 0: m_uv->and[0] = tw-1; m_uv->or[0] = 0; m_uv->mask[0] = 0xffff; break;
  790. case 1: m_uv->min[0] = 0; m_uv->max[0] = tw-1; m_uv->mask[0] = 0; break;
  791. case 2: m_uv->min[0] = m_ctxt->CLAMP.MINU; m_uv->max[0] = m_ctxt->CLAMP.MAXU; m_uv->mask[0] = 0; break;
  792. case 3: m_uv->and[0] = m_ctxt->CLAMP.MINU; m_uv->or[0] = m_ctxt->CLAMP.MAXU; m_uv->mask[0] = 0xffff; break;
  793. default: __assume(0);
  794. }
  795. m_uv->and[1] = m_uv->and[0];
  796. m_uv->or[1] = m_uv->or[0];
  797. m_uv->min[1] = m_uv->min[0];
  798. m_uv->max[1] = m_uv->max[0];
  799. m_uv->mask[1] = m_uv->mask[0];
  800. switch(m_ctxt->CLAMP.WMT)
  801. {
  802. case 0: m_uv->and[2] = th-1; m_uv->or[2] = 0; m_uv->mask[2] = 0xffff; break;
  803. case 1: m_uv->min[2] = 0; m_uv->max[2] = th-1; m_uv->mask[2] = 0; break;
  804. case 2: m_uv->min[2] = m_ctxt->CLAMP.MINV; m_uv->max[2] = m_ctxt->CLAMP.MAXV; m_uv->mask[2] = 0; break;
  805. case 3: m_uv->and[2] = m_ctxt->CLAMP.MINV; m_uv->or[2] = m_ctxt->CLAMP.MAXV; m_uv->mask[2] = 0xffff; break;
  806. default: __assume(0);
  807. }
  808. m_uv->and[3] = m_uv->and[2];
  809. m_uv->or[3] = m_uv->or[2];
  810. m_uv->min[3] = m_uv->min[2];
  811. m_uv->max[3] = m_uv->max[2];
  812. m_uv->mask[3] = m_uv->mask[2];
  813. }
  814. //
  815. // GSRendererSoftFP
  816. //
  817. GSRendererSoftFP::GSRendererSoftFP(HWND hWnd, HRESULT& hr)
  818. : GSRendererSoft<GSSoftVertexFP>(hWnd, hr)
  819. {
  820. }
  821. void GSRendererSoftFP::VertexKick(bool fSkip)
  822. {
  823. GSSoftVertexFP& v = m_vl.AddTail();
  824. v.c = (DWORD)m_v.RGBAQ.ai32[0];
  825. v.p.x = (int)m_v.XYZ.X - (int)m_ctxt->XYOFFSET.OFX;
  826. v.p.y = (int)m_v.XYZ.Y - (int)m_ctxt->XYOFFSET.OFY;
  827. v.p *= GSSoftVertexFP::Scalar(1.0f/16);
  828. v.p.z = (float)(m_v.XYZ.Z >> 16);
  829. v.p.q = (float)(m_v.XYZ.Z & 0xffff);
  830. if(m_pPRIM->TME)
  831. {
  832. if(m_pPRIM->FST)
  833. {
  834. v.t.x = (float)(int)m_v.UV.U;
  835. v.t.y = (float)(int)m_v.UV.V;
  836. v.t *= GSSoftVertexFP::Scalar(1.0f/16);
  837. v.t.q = 1.0f;
  838. }
  839. else
  840. {
  841. v.t.x = m_v.ST.S * (1 << m_ctxt->TEX0.TW);
  842. v.t.y = m_v.ST.T * (1 << m_ctxt->TEX0.TH);
  843. v.t.q = m_v.RGBAQ.Q;
  844. }
  845. }
  846. if(m_pPRIM->FGE)
  847. {
  848. v.t.z = (float)m_v.FOG.F * (1.0f/255);
  849. }
  850. __super::VertexKick(fSkip);
  851. }
  852. /*
  853. //
  854. // GSRendererSoftFX
  855. //
  856. GSRendererSoftFX::GSRendererSoftFX(HWND hWnd, HRESULT& hr)
  857. : GSRendererSoft<GSSoftVertexFX>(hWnd, hr)
  858. {
  859. }
  860. void GSRendererSoftFX::VertexKick(bool fSkip)
  861. {
  862. GSSoftVertexFX& v = m_vl.AddTail();
  863. v.c = (DWORD)m_v.RGBAQ.ai32[0];
  864. v.p.x = ((int)m_v.XYZ.X - (int)m_ctxt->XYOFFSET.OFX) << 12;
  865. v.p.y = ((int)m_v.XYZ.Y - (int)m_ctxt->XYOFFSET.OFY) << 12;
  866. v.p.z = (int)((m_v.XYZ.Z & 0xffff0000) >> 1);
  867. v.p.q = (int)((m_v.XYZ.Z & 0x0000ffff) << 15);
  868. if(m_pPRIM->TME)
  869. {
  870. if(m_pPRIM->FST)
  871. {
  872. v.t.x = ((int)m_v.UV.U << (12 >> m_ctxt->TEX0.TW));
  873. v.t.y = ((int)m_v.UV.V << (12 >> m_ctxt->TEX0.TH));
  874. v.t.q = 1<<16;
  875. }
  876. else
  877. {
  878. // TODO
  879. v.t.x = m_v.ST.S;
  880. v.t.y = m_v.ST.T;
  881. v.t.q = m_v.RGBAQ.Q;
  882. }
  883. }
  884. if(m_pPRIM->FGE)
  885. {
  886. v.t.z = (int)m_v.FOG.F << 8;
  887. }
  888. __super::VertexKick(fSkip);
  889. }
  890. */