Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

723 lines
24 KiB

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ; This file contains texture blending functions.
  4. ;
  5. ; TODO Unpack TexColor[0] and TexColor[1].
  6. ; TODO Change ONLY the alpha part of the value. Two AND's and a OR
  7. ;
  8. ;-----------------------------------------------------------------------------
  9. include(`m4hdr.mh')dnl
  10. include(`cvars.mh')dnl
  11. include(`texblend.mh')dnl
  12. .586
  13. .model flat
  14. .data
  15. PUBLIC MaskOffAlpha
  16. MaskOffAlpha dq 00000ffffffffffffh
  17. PUBLIC ShiftTA
  18. ShiftTA dq 00100000000000000h
  19. PUBLIC Val0x00ff00ff00ff00ff
  20. Val0x00ff00ff00ff00ff dq 000ff00ff00ff00ffh
  21. PUBLIC Val0x000000ff00ff00ff
  22. Val0x000000ff00ff00ff dq 0000000ff00ff00ffh
  23. PUBLIC Val0X0000000001000000
  24. Val0X0000000001000000 dq 00000000001000000h
  25. PUBLIC Val0x0000400040004000
  26. Val0x0000400040004000 dq 00000400040004000h
  27. PUBLIC Val0x4000000000000000
  28. Val0x4000000000000000 dq 04000000000000000h
  29. PUBLIC AlphaVal128
  30. AlphaVal128 dq 04000000000000000h
  31. PUBLIC RGBVal128
  32. RGBVal128 dq 00000400040004000h ; This is actually 64 in the high byte since values needed to be
  33. ; shifted down by one to fake saturation.
  34. .code
  35. INCLUDE iammx.inc
  36. INCLUDE offs_acp.inc
  37. EXTERN Zero:MMWORD
  38. ;-----------------------------------------------------------------------------
  39. ;
  40. ; TexBlend_Tex1_None
  41. ;
  42. ; cPix = cSrc
  43. ; aPix = aSrc
  44. ;
  45. ;-----------------------------------------------------------------------------
  46. ;void TexBlend_Tex1_None(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  47. ; PD3DI_RASTSPAN pS)
  48. ;{
  49. PUBLIC _MMX_TexBlend_Tex1_None
  50. _MMX_TexBlend_Tex1_None:
  51. ; Get ready for next indirect jump
  52. mov eax, XpCtx(pfnTexBlendEnd)
  53. d_TexBlend_Tex1_None(NotMonolithic)
  54. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  55. jmp eax
  56. ;}
  57. ;-----------------------------------------------------------------------------
  58. ;
  59. ; TexBlend_Tex1_Decal
  60. ;
  61. ; cPix = cTex
  62. ; aPix = aTex
  63. ;
  64. ;-----------------------------------------------------------------------------
  65. ;void TexBlend_Tex1_Decal(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  66. ; PD3DI_RASTSPAN pS)
  67. ;{
  68. PUBLIC _MMX_TexBlend_Tex1_Decal
  69. _MMX_TexBlend_Tex1_Decal:
  70. ; Get ready for next indirect jump
  71. mov eax, XpCtx(pfnTexBlendEnd)
  72. d_TexBlend_Tex1_Decal(NotMonolithic)
  73. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  74. jmp eax
  75. ;}
  76. ;-----------------------------------------------------------------------------
  77. ;
  78. ; TexBlend_Tex1_Modulate
  79. ;
  80. ; cPix = cSrc * cTex
  81. ; aPix = aTex
  82. ;
  83. ;-----------------------------------------------------------------------------
  84. ;void TexBlend_Tex1_Modulate(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  85. ; PD3DI_RASTSPAN pS)
  86. ;{
  87. PUBLIC _MMX_TexBlend_Tex1_Modulate
  88. _MMX_TexBlend_Tex1_Modulate:
  89. ; Get ready for next indirect jump
  90. mov eax, XpCtx(pfnTexBlendEnd)
  91. d_TexBlend_Tex1_Modulate(NotMonolithic)
  92. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  93. jmp eax
  94. ;}
  95. ;-----------------------------------------------------------------------------
  96. ;
  97. ; TexBlend_Tex1_ModulateAlphaOVR
  98. ;
  99. ; cPix = cSrc * cTex
  100. ; aPix = aSrc
  101. ;
  102. ;-----------------------------------------------------------------------------
  103. ;void TexBlend_Tex1_ModulateAlphaOVR(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  104. ; PD3DI_RASTSPAN pS)
  105. ;{
  106. PUBLIC _MMX_TexBlend_Tex1_ModulateAlphaOVR
  107. _MMX_TexBlend_Tex1_ModulateAlphaOVR:
  108. ; Get ready for next indirect jump
  109. mov eax, XpCtx(pfnTexBlendEnd)
  110. d_TexBlend_Tex1_ModulateAlphaOVR(NotMonolithic)
  111. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  112. jmp eax
  113. ;}
  114. ;-----------------------------------------------------------------------------
  115. ;
  116. ; TexBlend_Tex1_Gen
  117. ;
  118. ; Calls first set of function pointers to do general texture blending.
  119. ;
  120. ;-----------------------------------------------------------------------------
  121. ;void CMMX_TexBlend_Tex1_Gen(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  122. ; PD3DI_RASTSPAN pS)
  123. ;{
  124. PUBLIC _MMX_TexBlend_Tex1_Gen
  125. _MMX_TexBlend_Tex1_Gen:
  126. ; Initialize input to diffuse color (the default)
  127. ; D3DI_RASTCOLOR Input = *(D3DI_RASTCOLOR*)&pS->uB;
  128. movq mm7, XpS(uB)
  129. ;D3DI_RASTCOLOR Arg1;
  130. ; in MM1
  131. ;D3DI_RASTCOLOR Arg2;
  132. ; in MM2
  133. mov edx, 0
  134. ;pCtx->pfnTexBlendGetAlpha[0](&Arg1, &Arg2, &Input, pCtx, pS, 0);
  135. call dword ptr XpCtx(pfnTexBlendGetAlpha)
  136. ;pCtx->pfnTexBlendOpAlpha[0]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 0);
  137. call dword ptr XpCtx(pfnTexBlendOpAlpha)
  138. ;pCtx->pfnTexBlendGetColor[0](&Arg1, &Arg2, &Input, pCtx, pS, 0);
  139. call dword ptr XpCtx(pfnTexBlendGetColor)
  140. ;pCtx->pfnTexBlendOpColor[0]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 0);
  141. call dword ptr XpCtx(pfnTexBlendOpColor)
  142. ; Get ready for next indirect jump
  143. mov eax, XpCtx(pfnTexBlendEnd)
  144. movq XpCtxSI(uBB), mm4
  145. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  146. jmp eax
  147. ;}
  148. ;-----------------------------------------------------------------------------
  149. ;
  150. ; TexBlend_TexM_Gen
  151. ;
  152. ; Calls all sets of function pointers to do general texture blending.
  153. ;
  154. ;-----------------------------------------------------------------------------
  155. ;void CMMX_TexBlend_TexM_Gen(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  156. ; PD3DI_RASTSPAN pS)
  157. ;{
  158. PUBLIC _MMX_TexBlend_TexM_Gen
  159. _MMX_TexBlend_TexM_Gen:
  160. ; Initialize input to diffuse color (the default)
  161. ; D3DI_RASTCOLOR Input0 = *(D3DI_RASTCOLOR*)&pS->uB;
  162. movq mm7, XpS(uB)
  163. ;D3DI_RASTCOLOR Input1;
  164. ;D3DI_RASTCOLOR Arg1;
  165. ;D3DI_RASTCOLOR Arg2;
  166. ; Set iTex to point to first texture color. Last argument of next 4 calls.
  167. mov edx, 0
  168. ;pCtx->pfnTexBlendGetAlpha[0](&Arg1, &Arg2, &Input0, pCtx, pS, 0);
  169. call dword ptr XpCtx(pfnTexBlendGetAlpha)
  170. ;pCtx->pfnTexBlendOpAlpha[0](&Input1, &Arg1, &Arg2, pCtx, pS, 0);
  171. call dword ptr XpCtx(pfnTexBlendOpAlpha)
  172. ;pCtx->pfnTexBlendGetColor[0](&Arg1, &Arg2, &Input0, pCtx, pS, 0);
  173. call dword ptr XpCtx(pfnTexBlendGetColor)
  174. ;pCtx->pfnTexBlendOpColor[0](&Input1, &Arg1, &Arg2, pCtx, pS, 0);
  175. call dword ptr XpCtx(pfnTexBlendOpColor)
  176. ; Result of first routines is in mm4 and pInput is passed as mm7
  177. movq mm7, mm4
  178. ; Set iTex to point to second texture color. Last argument of next 4 calls.
  179. mov edx, 4
  180. ;pCtx->pfnTexBlendGetAlpha[1](&Arg1, &Arg2, &Input1, pCtx, pS, 1);
  181. call dword ptr XpCtx(pfnTexBlendGetAlpha+4)
  182. ;pCtx->pfnTexBlendOpAlpha[1]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 1);
  183. call dword ptr XpCtx(pfnTexBlendOpAlpha+4)
  184. ;pCtx->pfnTexBlendGetColor[1](&Arg1, &Arg2, &Input1, pCtx, pS, 1);
  185. call dword ptr XpCtx(pfnTexBlendGetColor+4)
  186. ;pCtx->pfnTexBlendOpColor[1]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 1);
  187. call dword ptr XpCtx(pfnTexBlendOpColor+4)
  188. ; Get ready for next indirect jump
  189. mov eax, XpCtx(pfnTexBlendEnd)
  190. movq XpCtxSI(uBB), mm4
  191. ;pCtx->pfnTexBlendEnd(pCtx, pP, pS);
  192. jmp eax
  193. ;}
  194. define(`d_TexBlendGetAlpha', `; void CMMX_TexBlend_Get_Alpha_$1_$2(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput,
  195. ; PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex)
  196. ; {
  197. PUBLIC _MMX_TexBlend_Get_Alpha_$1_$2
  198. _MMX_TexBlend_Get_Alpha_$1_$2:
  199. ifelse(`$1', `TextureAlpha', `
  200. ;pArg1->uA = (UINT8)RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  201. pxor mm5, mm5
  202. movq mm1, XpCtxSI(TexCol+edx)
  203. punpcklbw mm1, mm5
  204. ', `$1', `InvTextureAlpha', `
  205. ;pArg1->uA = (UINT8)~(RGBA_GETALPHA(pCtx->SI.TexCol[iTex]));
  206. pcmpeqd mm5, mm5
  207. movq mm1, XpCtxSI(TexCol+edx)
  208. pxor mm1, mm5
  209. pxor mm5, mm5
  210. punpcklbw mm1, mm5
  211. ')
  212. dnl
  213. ifelse(`$2', `DiffuseAlpha', `
  214. ;pArg2->uA = (UINT8)(pS->uA>>COLOR_SHIFT);
  215. movq mm2, XpS(uB)
  216. psrlw mm2, 8
  217. ', `$2', `InputAlpha', `
  218. ;pArg2->uA = (UINT8)(pInput->uA>>COLOR_SHIFT);
  219. movq mm2, mm7
  220. psrlw mm2, 8
  221. ', `$2', `FactorAlpha', `
  222. ;pArg2->uA = 0;
  223. pxor mm5, mm5
  224. movd mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  225. punpcklbw mm2, mm5
  226. ', `$2', `InvDiffuseAlpha', `
  227. ;pArg2->uA = (UINT8)~((pS->uA>>COLOR_SHIFT));
  228. pcmpeqd mm2, mm2
  229. pxor mm2, XpS(uB)
  230. psrlw mm2, 8
  231. ', `$2', `InvInputAlpha', `
  232. ;pArg2->uA = (UINT8)~((pInput->uA>>COLOR_SHIFT));
  233. pcmpeqd mm2, mm2
  234. pxor mm2, mm7
  235. psrlw mm2, 8
  236. ', `$2', `InvFactorAlpha', `
  237. ;pArg2->uA = (UINT8)~((RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));
  238. pcmpeqd mm5, mm5
  239. movd mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  240. pxor mm2, mm5
  241. pxor mm5, mm5
  242. punpcklbw mm2, mm5
  243. ')
  244. ret
  245. ;}
  246. ')
  247. dnl
  248. d_RepStr(`d_RepStr(`d_TexBlendGetAlpha(AA, BB)',
  249. `AA', TextureAlpha, InvTextureAlpha)',
  250. `BB', DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha)
  251. dnl
  252. dnl
  253. define(`d_TexBlendOpAlpha', `; void CMMX_TexBlend_Op_Alpha_$1(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput,
  254. ; PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex)
  255. ; {
  256. PUBLIC _MMX_TexBlend_Op_Alpha_$1
  257. _MMX_TexBlend_Op_Alpha_$1:
  258. ifelse(`$1', `None', `
  259. ;pOut->uA = pS->uA;
  260. movq mm3, XpS(uB)
  261. ', `$1', `CopyArg1', `
  262. ;pOut->uA = pArg1->uA<<COLOR_SHIFT;
  263. movq mm3, mm1
  264. psllw mm3, 8
  265. ', `$1', `CopyArg2', `
  266. ;pOut->uA = pArg2->uA<<COLOR_SHIFT;
  267. movq mm3, mm2
  268. psllw mm3, 8
  269. ', `$1', `Modulate', `
  270. ;pOut->uA = pArg1->uA*pArg2->uA;
  271. movq mm3, mm1
  272. pmullw mm3, mm2
  273. ', `$1', `Modulate2', `
  274. ;pOut->uA = min(((UINT32)pArg1->uA*pArg2->uA)<<1, 0xffff);
  275. movq mm3, mm1
  276. pmullw mm3, mm2
  277. movq mm4, mm3
  278. psllw mm3, 1
  279. psraw mm4, 15 ; Make mask based on high bit. This is used to make value saturate.
  280. paddusw mm3, mm4 ; This could just as will be an por to set all bits.
  281. ', `$1', `Modulate4', `
  282. ;pOut->uA = min(((UINT32)pArg1->uA*pArg2->uA)<<2, 0xffff);
  283. movq mm3, mm1
  284. pmullw mm3, mm2
  285. movq mm4, mm3
  286. psllw mm3, 2
  287. paddusw mm4, MMWORD PTR Val0x4000000000000000 ; If either of the two upper bits are on,
  288. ; this will turn on the sign bit.
  289. psraw mm4, 15
  290. paddusw mm3, mm4 ; This could just as will be an por to set all bits.
  291. ', `$1', `Add', `
  292. ;pOut->uA = min((UINT32)pArg1->uA+pArg2->uA, 0xffff);
  293. movq mm3, mm1
  294. paddusb mm3, mm2
  295. psllw mm3, 8
  296. ', `$1', `AddSigned', `
  297. ;pOut->uA = max((INT32)pArg1->uA+pArg2->uA-128, 0x0);
  298. movq mm3, mm1
  299. movq mm4, mm2
  300. ; Actually only shifting up by 7 instead of 8.
  301. psllw mm3, 7 ; Shift down by one bit to check to see if there is a carry.
  302. psllw mm4, 7 ; Cant use saturate twice since were doing add and sub and it could mess up result.
  303. paddw mm4, mm3
  304. psubusw mm4, MMWORD PTR AlphaVal128 ; subtract 128 from shifted value. It is really 64 in the upper byte.
  305. movq mm3, mm4
  306. psraw mm4, 15
  307. psllw mm3, 1
  308. por mm3, mm4 ; Could have used paddusw here, but por achieves same effect.
  309. ', `$1', `BlendDiffuseAlpha', `
  310. ;INT32 iA = pS->uA;
  311. ;pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<<COLOR_SHIFT));
  312. movq mm4, XpS(uB)
  313. movq mm3, mm1
  314. psrlw mm4, 8
  315. psubw mm3, mm2
  316. pmullw mm3, mm4
  317. movq mm4, mm2
  318. psllw mm4, 8
  319. paddw mm3, mm4
  320. ', `$1', `BlendTextureAlpha', `
  321. ;INT32 iA = RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  322. ;pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<<8));
  323. movd mm4, XpCtxSI(TexCol+edx)
  324. movq mm3, mm1
  325. punpcklbw mm4, Zero
  326. psubw mm3, mm2
  327. pmullw mm3, mm4
  328. movq mm4, mm2
  329. psllw mm4, 8
  330. paddw mm3, mm4
  331. ', `$1', `BlendFactorAlpha', `
  332. ;INT32 iA = 0;//ATTENTION need Factor
  333. ;pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<<8));
  334. movq mm3, mm1
  335. movq mm4, mm2
  336. psubw mm3, mm4
  337. movd mm4, XpCtx(pdwRenderState+RS_TEXTUREFACTOR)
  338. punpcklbw mm4, Zero
  339. pmullw mm3, mm4
  340. movq mm4, mm2
  341. psllw mm4, 8
  342. paddw mm3, mm4
  343. ', `$1', `BlendTextureAlphaPM', `
  344. ;INT32 iA = 255 - RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  345. ;pOut->uA = min((UINT32)((pArg1->uA<<COLOR_SHIFT) + iA*pArg2->uA), 0xffff);
  346. movd mm4, XpCtxSI(TexCol+edx)
  347. pcmpeqw mm3, mm3 ; These two lines make 255 - TexColAlpha
  348. pxor mm4, mm3
  349. punpcklbw mm4, Zero
  350. movq mm3, mm2
  351. pmullw mm3, mm4
  352. movq mm4, mm1
  353. psllw mm4, 8
  354. paddusw mm3, mm4
  355. ')
  356. ret
  357. ;}
  358. ')
  359. dnl
  360. d_RepStr(`d_TexBlendOpAlpha(AA)',
  361. `AA', None, CopyArg1, CopyArg2, Modulate, Modulate2, Modulate4, Add, AddSigned,
  362. BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha, BlendTextureAlphaPM)
  363. dnl
  364. dnl
  365. define(`d_TexBlendGetColor', `; void CMMX_TexBlend_Get_Color_$1_$2(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput,
  366. ; PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex)
  367. ; {
  368. PUBLIC _MMX_TexBlend_Get_Color_$1_$2
  369. _MMX_TexBlend_Get_Color_$1_$2:
  370. ; Alpha is already done in mm3
  371. ifelse(`$1', `Texture', `
  372. ;pArg1->uB = (UINT8)RGBA_GETBLUE(pCtx->SI.TexCol[iTex]);
  373. ;pArg1->uG = (UINT8)RGBA_GETGREEN(pCtx->SI.TexCol[iTex]);
  374. ;pArg1->uR = (UINT8)RGBA_GETRED(pCtx->SI.TexCol[iTex]);
  375. pxor mm5, mm5
  376. movq mm1, XpCtxSI(TexCol+edx)
  377. punpcklbw mm1, mm5
  378. ', `$1', `InvTexture', `
  379. ;pArg1->uB = (UINT8)~(RGBA_GETBLUE(pCtx->SI.TexCol[iTex]));
  380. ;pArg1->uG = (UINT8)~(RGBA_GETGREEN(pCtx->SI.TexCol[iTex]));
  381. ;pArg1->uR = (UINT8)~(RGBA_GETRED(pCtx->SI.TexCol[iTex]));
  382. pcmpeqd mm5, mm5
  383. movd mm1, XpCtxSI(TexCol+edx)
  384. pxor mm1, mm5
  385. pxor mm5, mm5
  386. punpcklbw mm1, mm5
  387. ', `$1', `TextureAlpha', `
  388. ;pArg1->uB = (UINT8)RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  389. ;pArg1->uG = pArg1->uB;
  390. ;pArg1->uR = pArg1->uB;
  391. pxor mm5, mm5
  392. movd mm1, XpCtxSI(TexCol + edx)
  393. punpcklbw mm1, mm5
  394. punpckhwd mm1, mm1
  395. punpckhdq mm1, mm1
  396. ', `$1', `InvTextureAlpha', `
  397. ;pArg1->uB = (UINT8)~(RGBA_GETALPHA(pCtx->SI.TexCol[iTex]));
  398. ;pArg1->uG = pArg1->uB;
  399. ;pArg1->uR = pArg1->uB;
  400. pcmpeqd mm5, mm5
  401. movq mm1, XpCtxSI(TexCol + edx)
  402. pxor mm1, mm5
  403. pxor mm5, mm5
  404. punpcklbw mm1, mm5
  405. punpckhwd mm1, mm1
  406. punpckhdq mm1, mm1
  407. ')
  408. dnl
  409. ifelse(`$2', `Diffuse', `
  410. ;pArg2->uB = (UINT8)(pS->uB>>COLOR_SHIFT);
  411. ;pArg2->uG = (UINT8)(pS->uG>>COLOR_SHIFT);
  412. ;pArg2->uR = (UINT8)(pS->uR>>COLOR_SHIFT);
  413. movq mm2, XpS(uB)
  414. psrlw mm2, 8
  415. ', `$2', `Input', `
  416. ;pArg2->uB = (UINT8)(pInput->uB>>COLOR_SHIFT);
  417. ;pArg2->uG = (UINT8)(pInput->uG>>COLOR_SHIFT);
  418. ;pArg2->uR = (UINT8)(pInput->uR>>COLOR_SHIFT);
  419. movq mm2, mm7
  420. psrlw mm2, 8
  421. ', `$2', `Factor', `
  422. ;pArg2->uB = 0;//ATTENTION need Factor
  423. ;pArg2->uG = 0;//ATTENTION need Factor
  424. ;pArg2->uR = 0;//ATTENTION need Factor
  425. pxor mm5, mm5
  426. movd mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  427. punpcklbw mm2, mm5
  428. ', `$2', `InvDiffuse', `
  429. ;pArg2->uB = (UINT8)~((pS->uB>>COLOR_SHIFT));
  430. ;pArg2->uG = (UINT8)~((pS->uG>>COLOR_SHIFT));
  431. ;pArg2->uR = (UINT8)~((pS->uR>>COLOR_SHIFT));
  432. pcmpeqd mm2, mm2
  433. pxor mm2, XpS(uB)
  434. pxor mm2, mm5
  435. psrlw mm2, 8
  436. ', `$2', `InvInput', `
  437. ;pArg2->uB = (UINT8)~((pInput->uB>>COLOR_SHIFT));
  438. ;pArg2->uG = (UINT8)~((pInput->uG>>COLOR_SHIFT));
  439. ;pArg2->uR = (UINT8)~((pInput->uR>>COLOR_SHIFT));
  440. movq mm2, mm7
  441. pcmpeqd mm5, mm5
  442. pxor mm2, mm5
  443. psrlw mm2, 8
  444. ', `$2', `InvFactor', `
  445. ;pArg2->uB = (UINT8)~(RGBA_GETBLUE(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));
  446. ;pArg2->uG = (UINT8)~(RGBA_GETGREEN(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));
  447. ;pArg2->uR = (UINT8)~(RGBA_GETRED(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));
  448. pcmpeqd mm5, mm5
  449. movq mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  450. pxor mm2, mm5
  451. pxor mm5, mm5
  452. punpcklbw mm2, mm5
  453. ', `$2', `DiffuseAlpha', `
  454. ;pArg2->uB = (UINT8)(pS->uA>>COLOR_SHIFT);
  455. ;pArg2->uG = pArg2->uB;
  456. ;pArg2->uR = pArg2->uB;
  457. movq mm2, XpS(uB)
  458. psrlw mm2, 8
  459. punpckhwd mm2, mm2
  460. punpckhdq mm2, mm2
  461. ', `$2', `InputAlpha', `
  462. ;pArg2->uB = (UINT8)(pInput->uA);
  463. ;pArg2->uG = pArg2->uB;
  464. ;pArg2->uR = pArg2->uB;
  465. movq mm2, mm7
  466. punpckhwd mm2, mm2
  467. punpckhdq mm2, mm2
  468. psrlw mm2, 8
  469. ', `$2', `FactorAlpha', `
  470. ;pArg2->uB = (UINT8)RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR];
  471. ;pArg2->uG = pArg2->uB;
  472. ;pArg2->uR = pArg2->uB;
  473. pxor mm5, mm5
  474. movq mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  475. punpcklbw mm2, mm5
  476. punpckhwd mm2, mm2
  477. punpckhdq mm2, mm2
  478. ', `$2', `InvDiffuseAlpha', `
  479. ;pArg2->uB = (UINT8)~((pS->uA>>COLOR_SHIFT));
  480. ;pArg2->uG = pArg2->uB;
  481. ;pArg2->uR = pArg2->uB;
  482. pcmpeqd mm2, mm2
  483. pxor mm2, XpS(uB)
  484. psrlw mm2, 8
  485. punpckhwd mm2, mm2
  486. punpckhdq mm2, mm2
  487. ', `$2', `InvInputAlpha', `
  488. ;pArg2->uB = (UINT8)~((pInput->uA));
  489. ;pArg2->uG = pArg2->uB;
  490. ;pArg2->uR = pArg2->uB;
  491. pcmpeqd mm2, mm2
  492. pxor mm2, mm7
  493. psrlw mm2, 8
  494. punpckhwd mm2, mm2
  495. punpckhdq mm2, mm2
  496. ', `$2', `InvFactorAlpha', `
  497. ;pArg2->uB = (UINT8)~(RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));
  498. ;pArg2->uG = pArg2->uB;
  499. ;pArg2->uR = pArg2->uB;
  500. pcmpeqd mm5, mm5
  501. movq mm2, XpCtx(pdwRenderState + RS_TEXTUREFACTOR)
  502. pxor mm2, mm5
  503. pxor mm5, mm5
  504. punpcklbw mm2, mm5
  505. punpckhwd mm2, mm2
  506. punpckhdq mm2, mm2
  507. ')
  508. ret
  509. ;}
  510. ')
  511. dnl
  512. d_RepStr(`d_RepStr(`d_TexBlendGetColor(AA, BB)',
  513. `AA', Texture, InvTexture, TextureAlpha, InvTextureAlpha)',
  514. `BB', Diffuse, Input, Factor, InvDiffuse, InvInput, InvFactor,
  515. DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha)
  516. dnl
  517. dnl
  518. define(`d_TexBlendOpColor', `; void CMMX_TexBlend_Op_Color_$1(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput,
  519. ; PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex)
  520. ; {
  521. PUBLIC _MMX_TexBlend_Op_Color_$1
  522. _MMX_TexBlend_Op_Color_$1:
  523. movq mm6, MMWORD PTR MaskOffAlpha ; 0x0000ffff ffffffff
  524. ifelse(`$1', `None', `
  525. ;pOut->uB = pS->uB;
  526. ;pOut->uG = pS->uG;
  527. ;pOut->uR = pS->uR;
  528. movq mm4, XpS(uB)
  529. ', `$1', `CopyArg1', `
  530. ;pOut->uB = pArg1->uB<<COLOR_SHIFT;
  531. ;pOut->uG = pArg1->uG<<COLOR_SHIFT;
  532. ;pOut->uR = pArg1->uR<<COLOR_SHIFT;
  533. movq mm4, mm1
  534. psllw mm4, 8
  535. ', `$1', `CopyArg2', `
  536. ;pOut->uB = pArg2->uB<<COLOR_SHIFT;
  537. ;pOut->uG = pArg2->uG<<COLOR_SHIFT;
  538. ;pOut->uR = pArg2->uR<<COLOR_SHIFT;
  539. movq mm4, mm2
  540. psllw mm4, 8
  541. ', `$1', `Modulate', `
  542. ;pOut->uB = pArg1->uB*pArg2->uB;
  543. ;pOut->uG = pArg1->uG*pArg2->uG;
  544. ;pOut->uR = pArg1->uR*pArg2->uR;
  545. movq mm4, mm1
  546. movq mm5, mm2
  547. pmullw mm4, mm5
  548. ', `$1', `Modulate2', `
  549. ;pOut->uB = min(((UINT32)pArg1->uB*pArg2->uB)<<1, 0xffff);
  550. ;pOut->uG = min(((UINT32)pArg1->uG*pArg2->uG)<<1, 0xffff);
  551. ;pOut->uR = min(((UINT32)pArg1->uR*pArg2->uR)<<1, 0xffff);
  552. movq mm4, mm1
  553. movq mm5, mm2
  554. pmullw mm4, mm5
  555. movq mm5, mm4
  556. psllw mm4, 1
  557. psraw mm5, 15 ; Make mask based on high bit. This is used to make value saturate.
  558. paddusw mm4, mm5 ; This could just as will be an por to set all bits.
  559. ', `$1', `Modulate4', `
  560. ;pOut->uB = min(((UINT32)pArg1->uB*pArg2->uB)<<2, 0xffff);
  561. ;pOut->uG = min(((UINT32)pArg1->uG*pArg2->uG)<<2, 0xffff);
  562. ;pOut->uR = min(((UINT32)pArg1->uR*pArg2->uR)<<2, 0xffff);
  563. movq mm4, mm1
  564. movq mm5, mm2
  565. pmullw mm4, mm5
  566. movq mm5, mm4
  567. psllw mm4, 2
  568. paddusw mm5, MMWORD PTR Val0x0000400040004000 ; This will set sign bit if either of the upper bits are set.
  569. psraw mm5, 15 ; Shift sign bit down to all bits.
  570. paddusw mm4, mm5 ; This could just as will be an por to set all bits.
  571. ', `$1', `Add', `
  572. ;pOut->uB = min((UINT32)pArg1->uB+pArg2->uB, 0xffff);
  573. ;pOut->uG = min((UINT32)pArg1->uG+pArg2->uG, 0xffff);
  574. ;pOut->uR = min((UINT32)pArg1->uR+pArg2->uR, 0xffff);
  575. movq mm4, mm1
  576. paddusb mm4, mm2
  577. psllw mm4, 8
  578. ', `$1', `AddSigned', `
  579. ;pOut->uB = min(max((INT32)pArg1->uB+pArg2->uB-128, 0x0), 0xff);
  580. ;pOut->uG = min(max((INT32)pArg1->uG+pArg2->uG-128, 0x0), 0xff);
  581. ;pOut->uR = min(max((INT32)pArg1->uR+pArg2->uR-128, 0x0), 0xff);
  582. movq mm4, mm1
  583. movq mm5, mm2
  584. ; Actually only shifting up by 7 instead of 8.
  585. psllw mm4, 7 ; Shift down by one bit to check to see if there is a carry.
  586. psllw mm5, 7 ; Cant use saturate twice since were doing add and sub and it could mess up result.
  587. paddw mm5, mm4
  588. psubusw mm5, MMWORD PTR RGBVal128 ; subtract 128 from shifted value. It is really 64 in the upper byte.
  589. movq mm4, mm5
  590. psraw mm5, 15
  591. psllw mm4, 1
  592. por mm4, mm5 ; Could have used paddusw here, but por achieves same effect.
  593. ', `$1', `BlendDiffuseAlpha', `
  594. ;INT32 iA = pS->uA>>COLOR_SHIFT;
  595. ;pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<<8));
  596. ;pOut->uG = (UINT16)(iA*(pArga1->uG - pArg2->uG) + (pArg2->uG<<8));
  597. ;pOut->uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<<8));
  598. movq mm4, mm1
  599. movq mm5, mm2
  600. psubw mm4, mm5
  601. movq mm5, XpS(uB) ; Set iA = pS->uA
  602. psrlw mm5, 8
  603. punpckhwd mm5, mm5 ; copy iA to high dword.
  604. punpckhdq mm5, mm5 ; copy iA to full register
  605. pmullw mm4, mm5
  606. movq mm5, mm2
  607. psllw mm5, 8
  608. paddw mm4, mm5
  609. ', `$1', `BlendTextureAlpha', `
  610. ;INT32 iA = RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  611. ;pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<<8));
  612. ;pOut->uG = (UINT16)(iA*(pArg1->uG - pArg2->uG) + (pArg2->uG<<8));
  613. ;pOut->uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<<8));
  614. movq mm4, mm1
  615. movq mm5, mm2
  616. psubw mm4, mm5
  617. movd mm5, XpCtxSI(TexCol+edx)
  618. punpcklbw mm5, Zero
  619. punpckhwd mm5, mm5 ; copy iA to high dword.
  620. punpckhdq mm5, mm5 ; copy iA to full register
  621. pmullw mm4, mm5
  622. movq mm5, mm2
  623. psllw mm5, 8
  624. paddw mm4, mm5
  625. ', `$1', `BlendFactorAlpha', `
  626. ;INT32 iA = RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]);
  627. ;pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<<COLOR_SHIFT));
  628. ;pOut->uG = (UINT16)(iA*(pArg1->uG - pArg2->uG) + (pArg2->uG<<COLOR_SHIFT));
  629. ;pOut->uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<<COLOR_SHIFT));
  630. movq mm4, mm1
  631. movq mm5, mm2
  632. psubw mm4, mm5
  633. movd mm5, XpCtx(pdwRenderState+RS_TEXTUREFACTOR)
  634. punpcklbw mm5, Zero
  635. punpckhwd mm5, mm5 ; copy iA to high dword.
  636. punpckhdq mm5, mm5 ; copy iA to full register
  637. pmullw mm4, mm5
  638. movq mm5, mm2
  639. psllw mm5, 8
  640. paddw mm4, mm5
  641. ', `$1', `BlendTextureAlphaPM', `
  642. ;INT32 iA = 255 - RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);
  643. ;pOut->uB = min((UINT32)((pArg1->uB<<COLOR_SHIFT) + iA*pArg2->uB), 0xffff);
  644. ;pOut->uG = min((UINT32)((pArg1->uG<<COLOR_SHIFT) + iA*pArg2->uG), 0xffff);
  645. ;pOut->uR = min((UINT32)((pArg1->uR<<COLOR_SHIFT) + iA*pArg2->uR), 0xffff);
  646. movd mm5, XpCtxSI(TexCol+edx)
  647. pcmpeqw mm4, mm4 ; These two lines make 255 - TexColAlpha
  648. pxor mm5, mm4
  649. punpcklbw mm5, Zero
  650. punpckhwd mm5, mm5 ; copy iA to high dword.
  651. punpckhdq mm5, mm5 ; copy iA to full register
  652. movq mm4, mm2
  653. pmullw mm4, mm5
  654. movq mm5, mm1
  655. psllw mm5, 8
  656. paddusw mm4, mm5
  657. ')
  658. ; Need pOuts alpha value.
  659. pand mm4, mm6
  660. pandn mm6, mm3
  661. por mm4, mm6
  662. ret
  663. ;}
  664. ')
  665. dnl
  666. d_RepStr(`d_TexBlendOpColor(AA)',
  667. `AA', None, CopyArg1, CopyArg2, Modulate, Modulate2, Modulate4, Add, AddSigned,
  668. BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha, BlendTextureAlphaPM)
  669. dnl
  670. END