Source code of Windows XP (NT5)
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.

640 lines
13 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: texspanr.asm
  3. ;
  4. ; Fast replace-mode texturing.
  5. ;
  6. ; Created: 011/15/1995
  7. ; Author: Otto Berkes [ottob]
  8. ;
  9. ; Copyright (c) 1995 Microsoft Corporation
  10. ;----------------------------------------------------------------------;
  11. rMask = ((1 SHL rBits) - 1) SHL rShift
  12. gMask = ((1 SHL gBits) - 1) SHL gShift
  13. bMask = ((1 SHL bBits) - 1) SHL bShift
  14. rRightShiftAdj = 16 - (rShift + rBits)
  15. gRightShiftAdj = 16 - (gShift + gBits)
  16. bRightShiftAdj = 16 - (bShift + bBits)
  17. TMASK_SUBDIV equ [esi].GENGC_tMaskSubDiv
  18. TSHIFT_SUBDIV equ [esi].GENGC_tShiftSubDiv
  19. if FAST_REPLACE
  20. TEXPALETTE equ [esi].GENGC_texImageReplace
  21. if (PALETTE_ONLY)
  22. TEXIMAGE equ [esi].GENGC_texImage
  23. else
  24. TEXIMAGE equ [esi].GENGC_texImageReplace
  25. endif
  26. if PALETTE_ONLY
  27. TEX_BPP_LOG2 = 0
  28. elseif (BPP eq 8)
  29. TEX_BPP_LOG2 = 0
  30. else
  31. TEX_BPP_LOG2 = 1
  32. endif
  33. else
  34. .error
  35. endif
  36. if PALETTE_ONLY
  37. HANDLE_PALETTE MACRO
  38. mov bl, [edx] ; V
  39. and ebx, 0ffh ;U
  40. mov edx, TEXPALETTE ; V
  41. lea edx, [edx+4*ebx] ;U
  42. ENDM
  43. HANDLE_PALETTEX MACRO
  44. mov al, [edx] ; V
  45. and eax, 0ffh ;U
  46. mov ebx, TEXPALETTE ; V
  47. mov edx, TEMP2 ;U
  48. lea ebx, [ebx+4*eax] ; V
  49. mov TEMP2, edx ;U
  50. GET_TEXEL_ACCUM ; V
  51. ;U
  52. ENDM
  53. else
  54. HANDLE_PALETTE MACRO
  55. ENDM
  56. endif
  57. TEMP equ [esi].GENGC_sResult
  58. ;;
  59. ;;
  60. ;; Macros for advancing a single pixel unit
  61. ;;
  62. ;;
  63. if (BPP eq 8)
  64. PIXADVANCE MACRO var
  65. inc var
  66. ENDM
  67. elseif (BPP eq 16)
  68. PIXADVANCE MACRO var
  69. add var, (BPP / 8)
  70. ENDM
  71. else
  72. PIXADVANCE MACRO var
  73. add var, [esi].GENGC_bytesPerPixel
  74. ENDM
  75. endif
  76. ;;
  77. ;; Get pointer to current texel value in EDX:
  78. ;;
  79. GET_TEXEL_ADDRESS MACRO
  80. mov eax, TMASK_SUBDIV ;U
  81. mov edx, [esi].GENGC_tResult ; V
  82. mov ebx, [esi].GENGC_sResult ;U
  83. and edx, eax ; V
  84. shr edx, (6-TEX_BPP_LOG2) ;U
  85. mov ecx, [esi].GENGC_sMask ; V
  86. and ebx, ecx ;U
  87. mov eax, DWORD PTR [esi].GENGC_sResult ; V
  88. shr ebx, (16-TEX_BPP_LOG2) ;U
  89. mov ecx, [esi].GENGC_subDs ; V
  90. add eax, ecx ;U
  91. add edx, ebx ; V
  92. mov ecx, TEXIMAGE ;U
  93. mov ebx, [esi].GENGC_subDt ; V
  94. add edx, ecx ;U
  95. mov ecx, DWORD PTR [esi].GENGC_tResult ; V
  96. add ecx, ebx ;U
  97. mov DWORD PTR [esi].GENGC_sResult, eax ; V
  98. mov DWORD PTR [esi].GENGC_tResult, ecx ;U
  99. HANDLE_PALETTE
  100. ENDM
  101. if (BPP eq 8)
  102. GET_TEXEL MACRO
  103. mov al, [edx] ; V get texel value
  104. ENDM
  105. elseif (BPP eq 16)
  106. GET_TEXEL MACRO
  107. mov ax, [edx]
  108. ENDM
  109. endif
  110. GET_TEXEL_ADDRESS2 MACRO count
  111. ;; input : ecx = GENGC_tResult, edi = GENGC_sResult
  112. ;; output: edx = final texel address
  113. ;; free : ebx, edx are free
  114. mov ebx, TMASK_SUBDIV ;U
  115. mov edx, ecx ; V
  116. mov TEMP, eax ;U
  117. and edx, ebx ; V
  118. mov eax, edi ;U
  119. mov ebx, [esi].GENGC_sMask ; V
  120. shr edx, (6-TEX_BPP_LOG2) ;U
  121. and eax, ebx ; V
  122. shr eax, (16-TEX_BPP_LOG2) ;U
  123. mov ebx, TEXIMAGE ; V
  124. add edx, eax ;U
  125. mov eax, [esi].GENGC_subDs ; V
  126. add edx, ebx ;U
  127. add edi, eax ; V
  128. mov ebx, [esi].GENGC_subDt ;U
  129. mov eax, TEMP ; V
  130. add ecx, ebx ;U
  131. HANDLE_PALETTE
  132. ENDM
  133. if (BPP eq 8)
  134. GET_TEXEL_ACCUM MACRO
  135. mov al, [edx] ; V get texel value
  136. ror eax, BPP ;U
  137. ENDM
  138. elseif (BPP eq 16)
  139. GET_TEXEL_ACCUM MACRO
  140. mov ax, [edx]
  141. ror eax, BPP
  142. ENDM
  143. endif
  144. if (BPP eq 8)
  145. WRITE_TEXEL_DECEBP MACRO
  146. mov al, [edx]
  147. dec ebp
  148. mov [edi-1], al
  149. ENDM
  150. elseif (BPP eq 16)
  151. WRITE_TEXEL_DECEBP MACRO
  152. mov ax, [edx]
  153. dec ebp
  154. mov [edi-2], ax
  155. ENDM
  156. endif
  157. ;;----------------------------------------------------------------------
  158. ;;
  159. ;; This is the start of the texture routine. Kick off the divide, and use
  160. ;; the dead time to set up all of the accumulators and other variables.
  161. ;;
  162. ;;----------------------------------------------------------------------
  163. ;;
  164. ;; Start the divide:
  165. ;;
  166. mov eax, [ecx].GENGC_flags
  167. fld DWORD PTR [ecx].GENGC_SPAN_qw ;qwAccum
  168. fld DWORD PTR [ecx].GENGC_SPAN_qw ;qwAccum qwAccum
  169. test eax, GEN_TEXTURE_ORTHO
  170. jne @f
  171. fdivr __One ;1/qw qwAccum
  172. @@:
  173. ;;
  174. ;; Save the registers that we need to:
  175. ;;
  176. push ebx ;U
  177. push esi ; V
  178. push edi ;U
  179. push ebp ; V
  180. mov esi, ecx ;U
  181. ;;
  182. ;; Set up accumulators:
  183. ;;
  184. mov eax, [ecx].GENGC_SPAN_s ; V
  185. mov ebx, [ecx].GENGC_SPAN_t ;U
  186. mov [ecx].GENGC_sAccum, eax ; V
  187. mov [esi].GENGC_tAccum, ebx ;U
  188. mov ecx, [esi].GENGC_SPAN_qw ; V
  189. mov edi, [esi].GENGC_SPAN_ppix ;U
  190. mov [esi].GENGC_qwAccum, ecx ; V
  191. mov eax, [esi].GENGC_flags ;U
  192. mov ebx, [esi].GENGC_SPAN_x ; V
  193. test eax, SURFACE_TYPE_DIB ;U
  194. jne @f ; V
  195. mov edi, [esi].GENGC_ColorsBits ;U
  196. jmp short @pixAccumDone
  197. @@:
  198. if (BPP eq 8)
  199. add edi, ebx ; V
  200. elseif (BPP eq 16)
  201. lea edi, [edi + 2*ebx]
  202. endif
  203. @pixAccumDone:
  204. mov ebp, [esi].GENGC_SPAN_length ;U
  205. ;;
  206. ;; Before we get into the main loop, do pixel-by-pixel writes until
  207. ;; we're DWORD aligned:
  208. ;;
  209. test edi, 3
  210. je alignmentDone
  211. getAligned:
  212. test eax, GEN_TEXTURE_ORTHO
  213. je @f
  214. mov edx, [esi].GENGC_sAccum
  215. mov eax, [esi].GENGC_tAccum
  216. mov DWORD PTR [esi].GENGC_sResult, edx
  217. mov DWORD PTR [esi].GENGC_tResult, eax
  218. jmp short @stResultDone1
  219. @@:
  220. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  221. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  222. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  223. fmulp ST(2), ST ; s/qw t/qw qwAccum
  224. fistp QWORD PTR [esi].GENGC_sResult ; t/qw qwAccum
  225. fistp QWORD PTR [esi].GENGC_tResult ; qwAccum
  226. fadd DWORD PTR [esi].GENGC_SPAN_dqwdx; qwAccum
  227. fld ST(0) ; qwAccum qwAccum
  228. fdivr __One ; 1/qw qwAccum
  229. @stResultDone1:
  230. mov cl, TSHIFT_SUBDIV ;U
  231. mov edx, [esi].GENGC_tResult ; V
  232. sar edx, cl ;UV (4)
  233. and edx, NOT 7 ;U
  234. mov ebx, [esi].GENGC_sResult ; V
  235. mov [esi].GENGC_tResult, edx ;U
  236. and edx, TMASK_SUBDIV ; V
  237. shr edx, (6-TEX_BPP_LOG2) ;U
  238. and ebx, [esi].GENGC_sMask ; V
  239. shr ebx, (16-TEX_BPP_LOG2) ;U
  240. mov ecx, TEXIMAGE ; V
  241. add edx, ecx ;U
  242. PIXADVANCE edi ; V
  243. add edx, ebx ;U
  244. HANDLE_PALETTE
  245. mov eax, [esi].GENGC_sAccum ; V
  246. mov ebx, [esi].GENGC_tAccum ;U
  247. add eax, [esi].GENGC_SPAN_ds ; V
  248. add ebx, [esi].GENGC_SPAN_dt ;U
  249. mov [esi].GENGC_sAccum, eax ; V
  250. mov [esi].GENGC_tAccum, ebx ;U
  251. WRITE_TEXEL_DECEBP
  252. jle spanExit ; V
  253. test edi, 3
  254. mov eax, [esi].GENGC_flags
  255. jne getAligned
  256. alignmentDone:
  257. ;;
  258. ;; Kick off the next divide:
  259. ;;
  260. test eax, GEN_TEXTURE_ORTHO
  261. je @f
  262. mov edx, [esi].GENGC_sAccum
  263. mov eax, [esi].GENGC_tAccum
  264. mov DWORD PTR [esi].GENGC_sResult, edx
  265. mov DWORD PTR [esi].GENGC_tResult, eax
  266. jmp short @stResultDone2
  267. @@:
  268. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  269. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  270. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  271. fmulp ST(2), ST ; s/qw t/qw qwAccum
  272. fistp QWORD PTR [esi].GENGC_sResult ; t/qw qwAccum
  273. fistp QWORD PTR [esi].GENGC_tResult ; qwAccum
  274. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum
  275. fld ST(0) ; qwAccum qwAccum
  276. fdivr __One ; 1/qw qwAccum
  277. @stResultDone2:
  278. mov eax, [esi].GENGC_sAccum ; V
  279. mov ebx, [esi].GENGC_tAccum ;U
  280. add eax, [esi].GENGC_sStepX ; V
  281. add ebx, [esi].GENGC_tStepX ;U
  282. mov [esi].GENGC_sAccum, eax ; V
  283. mov [esi].GENGC_tAccum, ebx ;U
  284. mov eax, [esi].GENGC_sResult ; V
  285. mov ebx, [esi].GENGC_tResult ;U
  286. mov cl, TSHIFT_SUBDIV ; V
  287. sar ebx, cl ;UV (4)
  288. and ebx, NOT 7 ;U
  289. mov ecx, [esi].GENGC_flags ; V
  290. mov [esi].GENGC_tResult, ebx ;U
  291. test ecx, GEN_TEXTURE_ORTHO ; V
  292. je @f
  293. mov ecx, [esi].GENGC_sAccum
  294. mov edx, [esi].GENGC_tAccum
  295. mov DWORD PTR [esi].GENGC_sResultNew, ecx
  296. mov DWORD PTR [esi].GENGC_tResultNew, edx
  297. jmp short @stResultDone3
  298. ;; We may have to burn some cycles here...
  299. @@:
  300. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  301. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  302. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  303. fmulp ST(2), ST ; s/qw t/qw qwAccum
  304. fistp QWORD PTR [esi].GENGC_sResultNew; t/qw qwAccum
  305. fistp QWORD PTR [esi].GENGC_tResultNew; qwAccum
  306. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum
  307. @stResultDone3:
  308. mov cl, TSHIFT_SUBDIV ;U
  309. mov edx, [esi].GENGC_tResultNew ; V
  310. sar edx, cl ;UV (4)
  311. and edx, NOT 7 ;U
  312. mov ecx, [esi].GENGC_sResultNew ; V
  313. mov [esi].GENGC_tResultNew, edx ;U
  314. sub ecx, eax ; V
  315. sar ecx, 3 ;U
  316. sub edx, ebx ; V
  317. sar edx, 3 ;U
  318. mov [esi].GENGC_subDs, ecx ; V
  319. mov [esi].GENGC_subDt, edx ;U
  320. ;;
  321. ;;
  322. ;;
  323. ;; If we have fewer than 4 (or 2) pixels, just do right edge...
  324. if (BPP eq 8)
  325. test ebp, 0fffch ;U
  326. else
  327. test ebp, 0fffeh ;U
  328. endif
  329. je singlePixels
  330. add ebp, 070000h
  331. mov [esi].GENGC_pixAccum, edi
  332. mov ecx, [esi].GENGC_tResult
  333. mov eax, [esi].GENGC_flags
  334. mov edi, [esi].GENGC_sResult
  335. loopTop:
  336. ;;
  337. ;; This is the start of the outer loop. We come back here on each
  338. ;; subdivision. The key thing is to kick off the next divide:
  339. ;;
  340. test eax, GEN_TEXTURE_ORTHO
  341. jne @f
  342. fld ST(0) ; qwAccum qwAccum
  343. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum+ qwAccum
  344. fxch ST(1) ; qwAccum qwAccum+
  345. fdivr __One ; 1/qw qwAccum+ -- let the divide rip!
  346. @@:
  347. loopTopNoDiv:
  348. ;; If we have fewer than 4 (or 2) pixels, just do right edge...
  349. if (BPP eq 8)
  350. GET_TEXEL_ADDRESS2
  351. GET_TEXEL_ACCUM
  352. GET_TEXEL_ADDRESS2
  353. GET_TEXEL_ACCUM
  354. GET_TEXEL_ADDRESS2
  355. GET_TEXEL_ACCUM
  356. GET_TEXEL_ADDRESS2
  357. mov ebx, [esi].GENGC_pixAccum ; V
  358. add ebx, 4 ;U
  359. GET_TEXEL_ACCUM ; V
  360. ;U
  361. sub ebp, 040004h ; V
  362. mov [esi].GENGC_pixAccum, ebx ;U
  363. mov [ebx-4], eax ; V
  364. else
  365. GET_TEXEL_ADDRESS2
  366. GET_TEXEL_ACCUM
  367. GET_TEXEL_ADDRESS2
  368. mov ebx, [esi].GENGC_pixAccum
  369. add ebx, 4
  370. GET_TEXEL_ACCUM
  371. sub ebp, 020002h
  372. mov [esi].GENGC_pixAccum, ebx
  373. mov [ebx-4], eax
  374. endif
  375. jle doSubDiv ;U
  376. if (BPP eq 8)
  377. test ebp, 0fffch ; V
  378. else
  379. test ebp, 0fffeh
  380. endif
  381. je doRightEdgePixels ;U
  382. jmp loopTopNoDiv ; V
  383. doRightEdgePixels:
  384. test ebp, 0ffffh ; V
  385. je spanExit ;U
  386. mov [esi].GENGC_sResult, edi
  387. mov [esi].GENGC_tResult, ecx
  388. mov edi, [esi].GENGC_pixAccum
  389. rightEdgePixels:
  390. PIXADVANCE edi ;U
  391. GET_TEXEL_ADDRESS
  392. GET_TEXEL
  393. if (BPP eq 8)
  394. sub ebp, 010001h ;U
  395. mov [edi-1], al ; V
  396. elseif (BPP eq 16)
  397. sub ebp, 010001h
  398. mov [edi-2], ax
  399. endif
  400. test ebp, 0ffffh ;U
  401. jne rightEdgePixels ; V
  402. ;;
  403. ;; This is the exit point. We need to pop the unused floating-point
  404. ;; registers off the stack, and return:
  405. ;;
  406. spanExit:
  407. fstp ST(0)
  408. fstp ST(0)
  409. pop ebp
  410. pop edi
  411. pop esi
  412. pop ebx
  413. ret 0
  414. singlePixels:
  415. PIXADVANCE edi ;U
  416. GET_TEXEL_ADDRESS
  417. GET_TEXEL
  418. dec ebp
  419. if (BPP eq 8)
  420. mov [edi-1], al ; V
  421. elseif (BPP eq 16)
  422. mov [edi-2], ax
  423. endif
  424. jg singlePixels ; V
  425. ;;
  426. ;; This is the exit point. We need to pop the unused floating-point
  427. ;; registers off the stack, and return:
  428. ;;
  429. fstp ST(0)
  430. mov eax, [esi].GENGC_flags
  431. pop ebp
  432. pop edi
  433. pop esi
  434. pop ebx
  435. test eax, GEN_TEXTURE_ORTHO
  436. je @f
  437. fstp ST(0)
  438. @@:
  439. ret 0
  440. ;;
  441. ;; This is the subdivision code. After the required number of steps, the
  442. ;; routine will jump here to calculate the next set of interpolants based
  443. ;; on subdivision:
  444. ;;
  445. doSubDiv:
  446. add ebp, 080000h
  447. mov eax, [esi].GENGC_sAccum
  448. if (BPP eq 8)
  449. test ebp, 0fffch ; V
  450. else
  451. test ebp, 0fffeh
  452. endif
  453. je doRightEdgePixels ;U
  454. test ebp, 0ffffh
  455. je spanExit
  456. mov ecx, [esi].GENGC_flags
  457. mov ebx, [esi].GENGC_tAccum
  458. ;;
  459. ;; Increment the big S and T steps:
  460. ;;
  461. add eax, [esi].GENGC_sStepX
  462. add ebx, [esi].GENGC_tStepX
  463. mov [esi].GENGC_sAccum, eax
  464. mov [esi].GENGC_tAccum, ebx
  465. mov edi, [esi].GENGC_sResultNew
  466. mov ebx, [esi].GENGC_tResultNew
  467. test ecx, GEN_TEXTURE_ORTHO
  468. je @f
  469. ;;
  470. ;; Handle ortho case (easy)
  471. ;;
  472. mov edx, DWORD PTR [esi].GENGC_tAccum
  473. mov DWORD PTR [esi].GENGC_sResultNew, eax
  474. mov DWORD PTR [esi].GENGC_tResultNew, edx
  475. jmp short @stResultDone4
  476. ;;
  477. ;; Do the floating-point computation for perspective:
  478. ;;
  479. @@:
  480. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  481. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  482. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  483. fmulp ST(2), ST ; s/qw t/qw qwAccum
  484. fistp QWORD PTR [esi].GENGC_sResultNew; t/qw qwAccum
  485. fistp QWORD PTR [esi].GENGC_tResultNew; qwAccum
  486. @stResultDone4:
  487. ;;
  488. ;; Now, calculate the per-pixel deltas:
  489. ;;
  490. mov cl, TSHIFT_SUBDIV ;U
  491. mov edx, [esi].GENGC_tResultNew ; V
  492. sar edx, cl ;UV (4)
  493. mov ecx, [esi].GENGC_sResultNew ;U
  494. and edx, NOT 7 ; V
  495. sub ecx, edi ;U
  496. mov [esi].GENGC_tResultNew, edx ; V
  497. sar ecx, 3 ;U
  498. sub edx, ebx ; V
  499. sar edx, 3 ;U
  500. mov [esi].GENGC_subDs, ecx ; V
  501. mov [esi].GENGC_subDt, edx ;U
  502. mov ecx, ebx ; V
  503. mov eax, [esi].GENGC_flags ;U
  504. jmp loopTop ; V