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.

197 lines
7.8 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // This file contains texture addressing functions.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997.
  6. //
  7. // WARNING WARNING WARNING
  8. // This cpp file generated from mcp file.
  9. // EDIT THE MCP FILE.
  10. // I warned you.
  11. // WARNING WARNING WARNING
  12. //
  13. //-----------------------------------------------------------------------------
  14. include(`m4hdr.mh')dnl
  15. #include "rgb_pch.h"
  16. #pragma hdrstop
  17. #include "ctxa_mh.h"
  18. #include "ctexfilt.h"
  19. #include "cspnutil.h"
  20. include(`ctexaddr.mh')dnl
  21. d_RepStr(`d_RepStr(`d_RepStr(`d_RepStr(`d_TexAddr(0, AA, BB, CC, DD)',
  22. `AA', `TexAddrWrapMirror', `TexAddrAll')',
  23. `BB', `NoPersp', `Persp')',
  24. `CC', ifelse(DD, NoLOD, `Point, Bilinear', `Point, Bilinear, MaybeBilinear'))',
  25. `DD', `NoLOD', `LOD')
  26. // All singing all dancing mip mapping address calculation and filtering.
  27. void C_TexAddr_Filt_All_Mip(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  28. PD3DI_RASTSPAN pS, INT32 iTex)
  29. {
  30. PD3DI_SPANTEX pTex = pCtx->pTexture[iTex];
  31. INT16 iLOD0 = (INT16)(min(max(pS->iLOD >> 11, 0), pTex->cLOD));
  32. // use same LOD for both levels, if magnifying
  33. // ATTENTION the best way to make the magnify go faster is probably to
  34. // have the bead chooser pick a specialized optimized magnify bead
  35. // (which we have anyway) and put it in a pfnTex1AddrMagnify bead pointer.
  36. // Then, we could call it at the top of MipMap based on the sign of the LOD.
  37. INT16 iLOD1 = (INT16)(min(iLOD0+(pS->iLOD > 0), pTex->cLOD));
  38. INT16 iShiftU0 = pTex->iShiftU - iLOD0;
  39. INT16 iShiftU1 = pTex->iShiftU - iLOD1;
  40. INT16 iShiftV0 = pTex->iShiftV - iLOD0;
  41. INT16 iShiftV1 = pTex->iShiftV - iLOD1;
  42. INT32 iU00, iV00, iU10, iV10;
  43. INT32 iUFrac0, iVFrac0, iUFrac1, iVFrac1;
  44. // select filter based on whether we are minifying or magnifying
  45. D3DTEXTUREMINFILTER uFilter;
  46. if (pS->iLOD < 0)
  47. {
  48. // depends on the first two entries (POINT and LINEAR)
  49. // being the same for min and mag
  50. uFilter = (D3DTEXTUREMINFILTER)pTex->uMagFilter;
  51. }
  52. else
  53. {
  54. uFilter = pTex->uMinFilter;
  55. }
  56. if (uFilter == D3DTFG_LINEAR)
  57. {
  58. INT32 iHalf = 1<<(TEX_FINAL_SHIFT - iShiftU0 - 1);
  59. INT32 iUAlign = pCtx->SI.TexUV[iTex].iU - iHalf;
  60. iHalf = 1<<(TEX_FINAL_SHIFT - iShiftV0 - 1);
  61. INT32 iVAlign = pCtx->SI.TexUV[iTex].iV - iHalf;
  62. iU00 = iUAlign >> (TEX_FINAL_SHIFT - iShiftU0);
  63. iV00 = iVAlign >> (TEX_FINAL_SHIFT - iShiftV0);
  64. iUFrac0 = (iUAlign<<iShiftU0) & TEX_FINAL_FRAC_MASK;
  65. iVFrac0 = (iVAlign<<iShiftV0) & TEX_FINAL_FRAC_MASK;
  66. iHalf = 1<<(TEX_FINAL_SHIFT - iShiftU1 - 1);
  67. iUAlign = pCtx->SI.TexUV[iTex].iU - iHalf;
  68. iHalf = 1<<(TEX_FINAL_SHIFT - iShiftV1 - 1);
  69. iVAlign = pCtx->SI.TexUV[iTex].iV - iHalf;
  70. iU10 = iUAlign >> (TEX_FINAL_SHIFT - iShiftU1);
  71. iV10 = iVAlign >> (TEX_FINAL_SHIFT - iShiftV1);
  72. iUFrac1 = (iUAlign<<iShiftU1) & TEX_FINAL_FRAC_MASK;
  73. iVFrac1 = (iVAlign<<iShiftV1) & TEX_FINAL_FRAC_MASK;
  74. }
  75. else
  76. {
  77. // point sampling mip maps
  78. iU00 = (pCtx->SI.TexUV[iTex].iU) >> (TEX_FINAL_SHIFT - iShiftU0);
  79. iV00 = (pCtx->SI.TexUV[iTex].iV) >> (TEX_FINAL_SHIFT - iShiftV0);
  80. iU10 = (pCtx->SI.TexUV[iTex].iU) >> (TEX_FINAL_SHIFT - iShiftU1);
  81. iV10 = (pCtx->SI.TexUV[iTex].iV) >> (TEX_FINAL_SHIFT - iShiftV1);
  82. }
  83. // these need to be computed before texture address wrapping, if bilinear is used
  84. INT32 iU01 = iU00 + 1;
  85. INT32 iV01 = iV00 + 1;
  86. INT32 iU11 = iU10 + 1;
  87. INT32 iV11 = iV10 + 1;
  88. UINT16 uMaskU0 = pTex->uMaskU >> iLOD0;
  89. UINT16 uMaskV0 = pTex->uMaskV >> iLOD0;
  90. UINT16 uMaskU1 = pTex->uMaskU >> iLOD1;
  91. UINT16 uMaskV1 = pTex->uMaskV >> iLOD1;
  92. INT16 iFlip, iClamp1, iClamp2, iClampMinT, iClampMaxT;
  93. INT16 iOoWAdj = (INT16)(pS->iOoW>>23); // 1.31 >> 23 = 1.8
  94. INT16 iUoWAdj = (INT16)(pS->UVoW[iTex].iUoW >> (TEX_SHIFT - 8)); // adjust to match iOoWAdj
  95. INT16 iVoWAdj = (INT16)(pS->UVoW[iTex].iVoW >> (TEX_SHIFT - 8));
  96. d_TexAddrAll(U, iU00, uMaskU0, iUoWAdj, iOoWAdj, iLOD0)
  97. d_TexAddrAll(V, iV00, uMaskV0, iVoWAdj, iOoWAdj, iLOD0)
  98. d_TexAddrAll(U, iU10, uMaskU1, iUoWAdj, iOoWAdj, iLOD1)
  99. d_TexAddrAll(V, iV10, uMaskV1, iVoWAdj, iOoWAdj, iLOD1)
  100. UINT32 uTex0, uTex1; // to put results of bilinear or point filters
  101. if (uFilter == D3DTFG_LINEAR)
  102. {
  103. // bilinear on mip levels
  104. // previously computed iOoWAdj, iUoWAdj, iVoWAdj are still valid
  105. d_TexAddrAll(U, iU01, uMaskU0, iUoWAdj, iOoWAdj, iLOD0)
  106. d_TexAddrAll(V, iV01, uMaskV0, iVoWAdj, iOoWAdj, iLOD0)
  107. d_TexAddrAll(U, iU11, uMaskU1, iUoWAdj, iOoWAdj, iLOD1)
  108. d_TexAddrAll(V, iV11, uMaskV1, iVoWAdj, iOoWAdj, iLOD1)
  109. UINT32 uTex00 = pCtx->pfnTexRead[iTex](iU00, iV00, pTex->iShiftPitch[iLOD0],
  110. pTex->pBits[iLOD0], pTex);
  111. UINT32 uTex10 = pCtx->pfnTexRead[iTex](iU01, iV00, pTex->iShiftPitch[iLOD0],
  112. pTex->pBits[iLOD0], pTex);
  113. UINT32 uTex01 = pCtx->pfnTexRead[iTex](iU00, iV01, pTex->iShiftPitch[iLOD0],
  114. pTex->pBits[iLOD0], pTex);
  115. UINT32 uTex11 = pCtx->pfnTexRead[iTex](iU01, iV01, pTex->iShiftPitch[iLOD0],
  116. pTex->pBits[iLOD0], pTex);
  117. TexFiltBilinear((D3DCOLOR*)&uTex0, iUFrac0, iVFrac0, uTex00, uTex10, uTex01, uTex11);
  118. uTex00 = pCtx->pfnTexRead[iTex](iU10, iV10, pTex->iShiftPitch[iLOD1],
  119. pTex->pBits[iLOD1], pTex);
  120. uTex10 = pCtx->pfnTexRead[iTex](iU11, iV10, pTex->iShiftPitch[iLOD1],
  121. pTex->pBits[iLOD1], pTex);
  122. uTex01 = pCtx->pfnTexRead[iTex](iU10, iV11, pTex->iShiftPitch[iLOD1],
  123. pTex->pBits[iLOD1], pTex);
  124. uTex11 = pCtx->pfnTexRead[iTex](iU11, iV11, pTex->iShiftPitch[iLOD1],
  125. pTex->pBits[iLOD1], pTex);
  126. TexFiltBilinear((D3DCOLOR*)&uTex1, iUFrac1, iVFrac1, uTex00, uTex10, uTex01, uTex11);
  127. }
  128. else
  129. {
  130. // point sample on mip levels
  131. uTex0 = pCtx->pfnTexRead[iTex](iU00, iV00, pTex->iShiftPitch[iLOD0],
  132. pTex->pBits[iLOD0], pTex);
  133. uTex1 = pCtx->pfnTexRead[iTex](iU10, iV10, pTex->iShiftPitch[iLOD1],
  134. pTex->pBits[iLOD1], pTex);
  135. }
  136. INT32 r0, r1;
  137. INT32 g0, g1;
  138. INT32 b0, b1;
  139. INT32 a0, a1;
  140. r0 = RGBA_GETRED(uTex0);
  141. r1 = RGBA_GETRED(uTex1);
  142. g0 = RGBA_GETGREEN(uTex0);
  143. g1 = RGBA_GETGREEN(uTex1);
  144. b0 = RGBA_GETBLUE(uTex0);
  145. b1 = RGBA_GETBLUE(uTex1);
  146. a0 = RGBA_GETALPHA(uTex0);
  147. a1 = RGBA_GETALPHA(uTex1);
  148. INT32 t = pS->iLOD & 0x7ff;
  149. INT32 mt = 0x7ff - t;
  150. r0 = (mt*r0 + t*r1)>>11;
  151. g0 = (mt*g0 + t*g1)>>11;
  152. b0 = (mt*b0 + t*b1)>>11;
  153. a0 = (mt*a0 + t*a1)>>11;
  154. // HACK to see LOD
  155. // scale it so 0 is mid range red
  156. // r0 = (((pS->iLOD & 0xf800) >> 8) + 0x80 ) & 0xff; // map in red
  157. // g0 = (pS->iLOD >> 3) & 0xff; // between maps in green (doesn't show lowest 3 bits)
  158. // b0 = 0;
  159. pCtx->SI.TexCol[iTex] = RGBA_MAKE(r0, g0, b0, a0);
  160. pS->UVoW[iTex].iUoW += pP->DUVoWDX[iTex].iDUoWDX;
  161. pS->UVoW[iTex].iVoW += pP->DUVoWDX[iTex].iDVoWDX;
  162. pS->iLOD += pS->iDLOD;
  163. pCtx->SI.iOoW = pS->iOoW; // save the old OoW for next stage, if needed
  164. pS->iOoW += pP->iDOoWDX;
  165. d_WDivide()
  166. pCtx->SI.TexUV[iTex].iU = d_WTimesUVoW(pS->iW,pS->UVoW[iTex].iUoW);
  167. pCtx->SI.TexUV[iTex].iV = d_WTimesUVoW(pS->iW,pS->UVoW[iTex].iVoW);
  168. }
  169. void C_TexAddr_Wrapper(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP,
  170. PD3DI_RASTSPAN pS)
  171. {
  172. for (INT32 i = 0; i < (INT32)pCtx->cActTex; i++)
  173. {
  174. pCtx->pfnTexAddr[i](pCtx, pP, pS, i);
  175. }
  176. pCtx->pfnTexAddrEnd(pCtx, pP, pS);
  177. }