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.

658 lines
21 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: fastfill.asm
  3. ;
  4. ; Draws fast unclipped, non-complex polygons.
  5. ;
  6. ; Copyright (c) 1994 Microsoft Corporation
  7. ;-----------------------------------------------------------------------;
  8. .386
  9. .model small,c
  10. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  11. assume fs:nothing,gs:nothing
  12. .xlist
  13. include stdcall.inc ;calling convention cmacros
  14. include i386\strucs.inc
  15. include i386\hw.inc
  16. .list
  17. .data
  18. ; The number of FIFO slots that are empty after we've done an
  19. ; IO_FIFO_WAIT(8):
  20. IO_ALL_EMPTY_FIFO_COUNT equ 8
  21. ; All the state information for running an edge DDA:
  22. EDGEDATA struc
  23. ed_x dd ?
  24. ed_dx dd ?
  25. ed_lError dd ?
  26. ed_lErrorUp dd ?
  27. ed_lErrorDown dd ?
  28. ed_pptfx dd ?
  29. ed_dptfx dd ?
  30. ed_cy dd ?
  31. EDGEDATA ends
  32. .code
  33. ;---------------------------Public-Routine------------------------------;
  34. ; BOOL bIoFastFill(cEdges, pptfxFirst, ulHwForeMix, ulHwBackMix,
  35. ; iSolidColor, prb)
  36. ;
  37. ; Draws fast polygons. Or at least attempts to.
  38. ;
  39. ; This routine could take great advantage of the ATI SCAN_TO_X
  40. ; instruction. Alas, but I have limited time...
  41. ;
  42. ; Input:
  43. ;
  44. ; ppdev - Points to the PDEV.
  45. ; cEdges - Number of edges in 'pptfxFirst' buffer, including the
  46. ; 'close figure' edge (so it's also the same as the number
  47. ; of points in the list).
  48. ; pptfxFirst - Points to buffer of edges. The last point in not
  49. ; necessarily coincident with the first.
  50. ; ulHwForeMix - Foreground hardware mix.
  51. ; ulHwBackMix - Background hardware mix.
  52. ; iSolidColor - Fill colour.
  53. ; prb - Not used.
  54. ;
  55. ; Output:
  56. ;
  57. ; eax - Returns 1 if the polygon was drawn, 0 if the polygon was
  58. ; too complex.
  59. ;-----------------------------------------------------------------------;
  60. cProc bIoFastFill,28,< \
  61. uses esi edi ebx, \
  62. ppdev: ptr, \
  63. cEdges: dword,\
  64. pptfxFirst: ptr, \
  65. ulHwForeMix: dword,\
  66. ulHwBackMix: dword,\
  67. iSolidColor: dword,\
  68. prb: ptr >
  69. local edLeft[size EDGEDATA]: byte ;DDA state for left edge
  70. local edRight[size EDGEDATA]: byte ;DDA state for right edge
  71. local yTrapezoid: dword ;Current scan of trapezoid, in
  72. ; ABSOLUTE coordinates
  73. local cyTrapezoid: dword ;Scans remaining to be drawn in
  74. ; current trapezoid
  75. local pptfxLast: dword ;Points to last point in buffer
  76. local iEdge: dword ;Edge number for DDA loop
  77. local cFifoEmpty: dword ;Number of remaining free FIFOs
  78. local xOffset: dword ;DFB 'x' offset
  79. local yOffset: dword ;DFB 'y' offset
  80. mov esi,pptfxFirst
  81. mov ecx,cEdges
  82. dec ecx
  83. mov edi,esi ;edi = pptfxTop = pptfxFirst
  84. lea eax,[esi+ecx*8]
  85. mov pptfxLast,eax ;pptfxLast = pptfxFirst + cEdges - 1
  86. mov eax,[esi].ptl_y
  87. mov ebx,[esi+8].ptl_y
  88. mov edx,eax ;edx = pptfxFirst->y
  89. cmp ebx,eax
  90. jle short io_u_collect_all_ups
  91. io_d_collect_all_downs:
  92. dec ecx
  93. jz short io_setup_for_filling
  94. add esi,8
  95. mov eax,ebx
  96. mov ebx,[esi+8].ptl_y
  97. cmp ebx,eax
  98. jge short io_d_collect_all_downs
  99. io_d_collect_all_ups:
  100. dec ecx
  101. jz short io_setup_for_filling_check
  102. add esi,8
  103. mov eax,ebx
  104. mov ebx,[esi+8].ptl_y
  105. cmp ebx,eax
  106. jle short io_d_collect_all_ups
  107. mov edi,esi ;edi = pptfxTop = pptfxScan
  108. io_d_collect_all_downs_again:
  109. cmp ebx,edx
  110. jg short io_return_false
  111. dec ecx
  112. jz short io_setup_for_filling
  113. add esi,8
  114. mov eax,ebx
  115. mov ebx,[esi+8].ptl_y
  116. cmp ebx,eax
  117. jge short io_d_collect_all_downs_again
  118. io_return_false:
  119. sub eax,eax
  120. cRet bIoFastFill
  121. io_u_collect_all_ups:
  122. add edi,8
  123. dec ecx
  124. jz io_setup_for_filling
  125. mov eax,ebx
  126. mov ebx,[edi+8].ptl_y
  127. cmp ebx,eax
  128. jle short io_u_collect_all_ups
  129. mov esi,edi ;esi = pptfxScan = pptfxTop
  130. io_u_collect_all_downs:
  131. dec ecx
  132. jz io_setup_for_filling
  133. add esi,8
  134. mov eax,ebx
  135. mov ebx,[esi+8].ptl_y
  136. cmp ebx,eax
  137. jge short io_u_collect_all_downs
  138. io_u_collect_all_ups_again:
  139. cmp ebx,edx
  140. jl short io_return_false
  141. dec ecx
  142. jz io_setup_for_filling
  143. add esi,8
  144. mov eax,ebx
  145. mov ebx,[esi+8].ptl_y
  146. cmp ebx,eax
  147. jle short io_u_collect_all_ups_again
  148. sub eax,eax
  149. cRet bIoFastFill
  150. io_setup_for_filling_check:
  151. cmp ebx,edx
  152. jge short io_setup_for_filling
  153. lea edi,[esi+8]
  154. public io_setup_for_filling
  155. io_setup_for_filling::
  156. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  157. ;; Some initialization
  158. ; edi = pptfxTop
  159. mov ecx,[edi].ptl_y
  160. add ecx,15
  161. sar ecx,4
  162. mov yTrapezoid,ecx ;yTrapezoid = (pptfxTop->y + 15) >> 4
  163. mov edLeft.ed_cy,0
  164. mov edLeft.ed_dptfx,-8
  165. mov edLeft.ed_pptfx,edi
  166. mov edRight.ed_cy,0
  167. mov edRight.ed_dptfx,8
  168. mov edRight.ed_pptfx,edi
  169. mov esi,ppdev ;esi = ppdev
  170. ; ecx = yTrapezoid
  171. ; esi = ppdev
  172. mov eax,[esi].pdev_yOffset
  173. mov yOffset,eax ;yOffset = ppdev->yOffset
  174. add ecx,eax ;ecx = yTrapezoid += yOffset
  175. mov yTrapezoid,ecx ;yTrapezoid is kept in absolute
  176. ; coordinates
  177. mov ebx,[esi].pdev_xOffset
  178. mov xOffset,ebx ;xOffset = ppdev->xOffset
  179. ; This will guarantee that we have IO_ALL_EMPTY_FIFO_COUNT slots
  180. ; available.
  181. mov edx,CMD
  182. @@: in ax,dx
  183. and eax,FIFO_8_EMPTY ;IO_FIFO_WAIT(8)
  184. jnz short @b
  185. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  186. ;; Setup hardware for a solid colour
  187. public io_initialize_solid
  188. io_initialize_solid::
  189. ;ecx = yTrapezoid
  190. ;esi = ppdev
  191. mov cFifoEmpty,IO_ALL_EMPTY_FIFO_COUNT - 4
  192. mov eax,ulHwForeMix
  193. or eax,FOREGROUND_COLOR
  194. mov edx,[esi].pdev_ioFrgd_mix
  195. out dx,ax ;IO_FRGD_MIX(FOREGROUND_COLOR |
  196. ; ulHwForeMix)
  197. mov eax,DATA_EXTENSION
  198. mov edx,PIX_CNTL
  199. out dx,ax ;IO_PIX_CNTL(ALL_ONES)
  200. mov eax,RECT_HEIGHT
  201. out dx,ax ;IO_MIN_AXIS_PCNT(0)
  202. mov eax,iSolidColor
  203. mov edx,[esi].pdev_ioFrgd_color
  204. out dx,ax ;IO_FRGD_COLOR(iSolidColor)
  205. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  206. ;; DDA initialization
  207. public io_new_trapezoid
  208. io_new_trapezoid::
  209. lea edi,[edLeft+size EDGEDATA]
  210. mov iEdge,1
  211. io_other_edge:
  212. sub edi,size EDGEDATA
  213. cmp [edi].ed_cy,0
  214. jg io_check_if_another_edge
  215. io_need_new_dda:
  216. dec cEdges
  217. jl io_return_true
  218. mov edx,[edi].ed_pptfx ;edx = ped->pptfx
  219. mov ebx,[edx].ptl_x ;ebx = xStart = ped->pptfx->x
  220. mov ecx,[edx].ptl_y ;ecx = yStart = ped->pptfx->y
  221. add edx,[edi].ed_dptfx ;edx += ped->ed_dptfx
  222. cmp edx,pptfxFirst ;See if edx wrapped around ends of
  223. jae short @f ; the buffer
  224. mov edx,pptfxLast
  225. @@: cmp edx,pptfxLast
  226. jbe short @f
  227. mov edx,pptfxFirst
  228. @@:
  229. mov [edi].ed_pptfx,edx ;ped->pptfx = edx
  230. mov eax,[edx].ptl_y
  231. add eax,15
  232. sar eax,4
  233. add eax,yOffset ;Convert to absolute coordinates
  234. sub eax,yTrapezoid ;eax = ((ped->pptfx->y + 15) >> 4)
  235. ; - yTrapezoid
  236. jle short io_need_new_dda ;Edge has to cross a scan
  237. mov [edi].ed_cy,eax ;ped->cy = eax
  238. public io_calculate_deltas
  239. io_calculate_deltas::
  240. mov esi,[edx].ptl_y
  241. sub esi,ecx ;esi = dN = ped->pptfx->y - yStart
  242. mov [edi].ed_lErrorDown,esi ;ped->lErrorDown = dN
  243. mov eax,[edx].ptl_x
  244. sub eax,ebx ;eax = dM = ped->pptfx->x - xStart
  245. jge short io_to_right
  246. neg eax ;eax = dM = -dM
  247. cmp eax,esi
  248. jge short io_x_major_to_left
  249. sub esi,eax
  250. mov edx,esi ;edx = lErrorUp = dN - dM
  251. mov eax,-1 ;eax = dx = -1
  252. jmp short io_calc_rest_of_dda
  253. io_x_major_to_left:
  254. sub edx,edx
  255. div esi ;edx = lErrorUp = dM % dN
  256. neg eax ;eax = dx = - dM / dN
  257. test edx,edx
  258. jz short io_calc_rest_of_dda
  259. sub esi,edx
  260. mov edx,esi ;edx = lErrorUp = dN - (dM % dN)
  261. dec eax ;eax = dx = (-dM / dN) - 1
  262. jmp short io_calc_rest_of_dda
  263. io_to_right:
  264. cmp eax,esi
  265. jge short io_x_major_io_to_right
  266. mov edx,eax ;edx = lErrorUp = dM
  267. sub eax,eax ;eax = dx = 0
  268. jmp short io_calc_rest_of_dda
  269. io_x_major_io_to_right:
  270. sub edx,edx
  271. div esi ;edx = lErrorUp = dM % dN
  272. ;eax = dx = dM / dN
  273. public io_calc_rest_of_dda
  274. io_calc_rest_of_dda::
  275. mov [edi].ed_lErrorUp,edx ;ped->lErrorUp = lErrorUp
  276. mov [edi].ed_dx,eax ;ped->dx = dx
  277. mov esi,-1 ;esi = lError = -1 (meaning that the
  278. ; initial error is zero)
  279. ; eax = dx
  280. ; ebx = xStart ('x' position of start point of edge)
  281. ; ecx = yStart ('y' position of start point of edge)
  282. ; edx = lErrorUp
  283. ; esi = lError
  284. ; edi = ped
  285. and ecx,15
  286. jz short io_on_integer_row
  287. xor ecx,0fh ;ecx = 15 - (yStart & 15)
  288. io_advance_to_integer_row:
  289. add ebx,eax ;ebx = x += ped->dx
  290. add esi,edx ;esi = lError += lErrorUp
  291. jl short @f
  292. sub esi,[edi].ed_lErrorDown ;esi = lError -= lErrorDown
  293. inc ebx ;ebx = x++
  294. @@:
  295. dec ecx
  296. jge short io_advance_to_integer_row
  297. io_on_integer_row:
  298. mov edx,ebx ;edx = ebx = x
  299. and edx,15 ;edx = (x & 15)
  300. jz short io_on_integer_column
  301. xor edx,0fh
  302. inc edx ;edx = 16 - (x & 15)
  303. imul edx,[edi].ed_lErrorDown
  304. sub esi,edx ;esi = lError -= lErrorDown
  305. ; * (16 - (x & 15))
  306. add ebx,15 ;ebx = x += 15
  307. io_on_integer_column:
  308. sar ebx,4
  309. sar esi,4
  310. add ebx,xOffset
  311. mov [edi].ed_x,ebx ;ped->x = (x >> 4) + ppdev->xOffset
  312. mov [edi].ed_lError,esi ;ped->lError = (lError >> 4)
  313. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  314. ;; Get ready to do the DDAs
  315. public io_check_if_another_edge
  316. io_check_if_another_edge::
  317. dec iEdge
  318. jge io_other_edge
  319. ; This obtuse chunk of code calculates:
  320. ;
  321. ; cyTrapezoid = min(edLeft.ed_cy, edRight.ed_cy)
  322. ; edLeft.ed_cy -= original edRight.ed_cy
  323. ; edRight.ed_cy -= original edLeft.ed_cy
  324. mov eax,edLeft.ed_cy
  325. mov ebx,edRight.ed_cy
  326. sub eax,ebx
  327. sbb ecx,ecx
  328. mov edLeft.ed_cy,eax
  329. neg eax
  330. mov edRight.ed_cy,eax
  331. and ecx,eax
  332. sub ebx,ecx
  333. mov cyTrapezoid,ebx
  334. ; We bias the right edge by one because the S3 always expects
  335. ; widths to be the actual width less one:
  336. mov ebx,edLeft.ed_x
  337. mov esi,edRight.ed_x
  338. dec esi
  339. mov ecx,edLeft.ed_lError
  340. mov edi,edRight.ed_lError
  341. ;----------------------------------------------------------------------;
  342. ; Solid draw
  343. ;----------------------------------------------------------------------;
  344. public io_solid_draw
  345. io_solid_draw::
  346. ; eax =
  347. ; ebx = edLeft.ed_x
  348. ; ecx = edLeft.ed_lError
  349. ; esi = edRight.ed_x - 1
  350. ; edi = edRight.ed_lError
  351. cmp edLeft.ed_lErrorUp,0
  352. jnz io_solid_dda
  353. cmp edRight.ed_lErrorUp,0
  354. jnz io_solid_dda
  355. cmp edLeft.ed_dx,0
  356. jnz io_solid_dda
  357. cmp edRight.ed_dx,0
  358. jnz io_solid_dda
  359. cmp cyTrapezoid,1
  360. je io_solid_dda
  361. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  362. ;; Vertical-edge special case for solid colours
  363. public io_solid_vertical
  364. io_solid_vertical::
  365. mov eax,esi
  366. sub eax,ebx
  367. jl short io_solid_vertical_zero_or_less_width
  368. sub cFifoEmpty,5 ;NOTE: If this count is changed, change
  369. ; io_solid_vertical_wait_for_fifo!
  370. jl short io_solid_vertical_wait_for_fifo
  371. io_solid_vertical_fifo_clear:
  372. mov edx,MAJ_AXIS_PCNT
  373. out dx,ax ;IO_MAJ_AXIS_PCNT(
  374. ; edRight.x - edLeft.x - 1)
  375. mov eax,yTrapezoid
  376. mov edx,CUR_Y
  377. out dx,ax ;IO_CUR_Y(yTrapezoid)
  378. mov eax,cyTrapezoid
  379. add yTrapezoid,eax ;yTrapezoid += cyTrapezoid
  380. dec eax
  381. or eax,RECT_HEIGHT
  382. mov edx,MIN_AXIS_PCNT
  383. out dx,ax ;IO_MIN_AXIS_PCNT(cyTrapezoid - 1)
  384. mov eax,ebx
  385. mov edx,CUR_X
  386. out dx,ax ;IO_CUR_X(edLeft.x)
  387. mov eax,(RECTANGLE_FILL + DRAWING_DIR_TBLRXM + \
  388. DRAW + WRITE)
  389. mov edx,CMD
  390. out dx,ax ;IO_CMD(...)
  391. mov eax,RECT_HEIGHT
  392. mov edx,MIN_AXIS_PCNT
  393. out dx,ax ;IO_MIN_AXIS_PCNT(0)
  394. ; Save our register variables because an edge can continue into
  395. ; the next trapezoid (this is significant if we swapped edges):
  396. inc esi ;undo right bias
  397. mov edLeft.ed_x,ebx
  398. mov edRight.ed_x,esi
  399. jmp io_new_trapezoid
  400. io_solid_vertical_wait_for_fifo:
  401. push eax
  402. mov edx,CMD
  403. @@: in ax,dx
  404. and eax,FIFO_8_EMPTY ;IO_FIFO_WAIT(8)
  405. jnz short @b
  406. mov cFifoEmpty,IO_ALL_EMPTY_FIFO_COUNT - 6
  407. pop eax
  408. jmp short io_solid_vertical_fifo_clear
  409. io_solid_vertical_zero_or_less_width:
  410. inc eax
  411. jnz short io_solid_vertical_swap_edges
  412. mov eax,cyTrapezoid
  413. add yTrapezoid,eax ;yTrapezoid += cyTrapezoid
  414. jmp io_new_trapezoid
  415. io_solid_vertical_swap_edges:
  416. push offset io_solid_vertical
  417. jmp io_swap_edges
  418. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  419. ;; Run the DDAs for solid colours
  420. public io_solid_dda_loop
  421. io_solid_dda_loop::
  422. dec cyTrapezoid
  423. jz io_solid_dda_ret
  424. public io_solid_dda
  425. io_solid_dda::
  426. mov eax,esi
  427. sub eax,ebx
  428. jl short io_solid_dda_zero_or_less_width
  429. sub cFifoEmpty,4 ;NOTE: If this count is changed, change
  430. ; io_solid_wait_for_fifo!
  431. jl short io_solid_wait_for_fifo
  432. io_solid_dda_fifo_clear:
  433. mov edx,MAJ_AXIS_PCNT
  434. out dx,ax ;IO_MAJ_AXIS_PCNT(
  435. ; edRight.x - edLeft.x - 1)
  436. mov eax,ebx
  437. mov edx,CUR_X
  438. out dx,ax ;IO_CUR_X(edLeft.x)
  439. mov eax,yTrapezoid
  440. mov edx,CUR_Y
  441. out dx,ax ;IO_CUR_Y(yTrapezoid)
  442. inc eax
  443. mov yTrapezoid,eax ;yTrapezoid++
  444. mov eax,(RECTANGLE_FILL + DRAWING_DIR_TBLRXM + \
  445. DRAW + WRITE)
  446. mov edx,CMD
  447. out dx,ax ;IO_CMD(...)
  448. io_solid_dda_continue_after_zero:
  449. add ebx,edLeft.ed_dx
  450. add ecx,edLeft.ed_lErrorUp
  451. jl short @f
  452. inc ebx
  453. sub ecx,edLeft.ed_lErrorDown
  454. @@:
  455. add esi,edRight.ed_dx
  456. add edi,edRight.ed_lErrorUp
  457. jl short io_solid_dda_loop
  458. inc esi
  459. sub edi,edRight.ed_lErrorDown
  460. dec cyTrapezoid
  461. jnz short io_solid_dda
  462. io_solid_dda_ret:
  463. inc esi ;undo right bias
  464. ; Save our register variables because an edge can continue into
  465. ; the next trapezoid:
  466. mov edLeft.ed_x,ebx
  467. mov edLeft.ed_lError,ecx
  468. mov edRight.ed_x,esi
  469. mov edRight.ed_lError,edi
  470. jmp io_new_trapezoid
  471. public io_solid_wait_for_fifo
  472. io_solid_wait_for_fifo::
  473. push eax
  474. mov edx,CMD
  475. @@: in ax,dx
  476. and eax,FIFO_8_EMPTY ;IO_FIFO_WAIT(8)
  477. jnz short @b
  478. mov cFifoEmpty,IO_ALL_EMPTY_FIFO_COUNT - 4
  479. pop eax
  480. jmp short io_solid_dda_fifo_clear
  481. io_solid_dda_zero_or_less_width:
  482. inc eax
  483. jnz short io_solid_dda_swap_edges
  484. inc yTrapezoid ;yTrapezoid++
  485. jmp short io_solid_dda_continue_after_zero
  486. io_solid_dda_swap_edges:
  487. push offset io_solid_dda
  488. jmp io_swap_edges
  489. ;----------------------------------------------------------------------;
  490. ; Swap edges
  491. ;----------------------------------------------------------------------;
  492. public io_swap_edges
  493. io_swap_edges::
  494. mov eax,edLeft.ed_cy
  495. mov edx,edRight.ed_cy
  496. mov edRight.ed_cy,eax
  497. mov edLeft.ed_cy,edx ;xchg 'cy'
  498. mov eax,edLeft.ed_dptfx
  499. mov edx,edRight.ed_dptfx
  500. mov edRight.ed_dptfx,eax
  501. mov edLeft.ed_dptfx,edx ;xchg 'dptfx'
  502. mov eax,edLeft.ed_pptfx
  503. mov edx,edRight.ed_pptfx
  504. mov edRight.ed_pptfx,eax
  505. mov edLeft.ed_pptfx,edx ;xchg 'pptfx'
  506. mov eax,edLeft.ed_dx
  507. mov edx,edRight.ed_dx
  508. mov edRight.ed_dx,eax
  509. mov edLeft.ed_dx,edx ;xchg 'dx'
  510. mov eax,edLeft.ed_lErrorUp
  511. mov edx,edRight.ed_lErrorUp
  512. mov edRight.ed_lErrorUp,eax
  513. mov edLeft.ed_lErrorUp,edx ;xchg 'lErrorUp'
  514. mov eax,edLeft.ed_lErrorDown
  515. mov edx,edRight.ed_lErrorDown
  516. mov edRight.ed_lErrorDown,eax
  517. mov edLeft.ed_lErrorDown,edx;xchg 'lErrorDown'
  518. xchg ecx,edi ;xchg 'lError'
  519. xchg ebx,esi ;xchg 'x'
  520. inc ebx
  521. dec esi ;don't forget right bias
  522. PLAIN_RET
  523. io_return_true:
  524. mov eax,1
  525. cRet bIoFastFill
  526. endProc bIoFastFill
  527. end