700 lines
14 KiB
NASM
700 lines
14 KiB
NASM
;---------------------------Module-Header------------------------------;
|
|
; Module Name: span.asm
|
|
;
|
|
; Created: 2/3/94
|
|
; Author: Otto Berkes [ottob]
|
|
;
|
|
; Get serious about drawing scanlines.
|
|
;
|
|
; Copyright (c) 1994 Microsoft Corporation
|
|
;----------------------------------------------------------------------;
|
|
|
|
|
|
.386
|
|
|
|
.model small,c
|
|
|
|
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
|
|
assume fs:nothing,gs:nothing
|
|
|
|
.xlist
|
|
include gli386.inc
|
|
.list
|
|
|
|
|
|
.data
|
|
|
|
NOP_CODE = 090h ;nop
|
|
JMP_CODE = 0EBh ;short jump
|
|
|
|
;; 4x4 (Bayer) dither matrix (Foley & van Dam 13.15) biased for
|
|
;; fractional values between 0 and 0ffh
|
|
|
|
Dither_4x4 dd 0008020a0h
|
|
dd 0c040e060h
|
|
dd 030b01090h
|
|
dd 0f070d050h
|
|
|
|
.code
|
|
|
|
;; Z-test function opcodes. The assembled operands required for the
|
|
;; selected z-comparison are inserted into the loaded span routine
|
|
|
|
|
|
ztest_fail_functions_short::
|
|
psZtest_never:
|
|
db 2 dup (NOP_CODE)
|
|
psZtest_l:
|
|
jb short @target
|
|
psZtest_e:
|
|
je short @target
|
|
psZtest_le:
|
|
jbe short @target
|
|
psZtest_g:
|
|
ja short @target
|
|
psZtest_ne:
|
|
jne short @target
|
|
psZtest_ge:
|
|
jae short @target
|
|
psZtest_always:
|
|
jmp short $+2
|
|
|
|
|
|
ztest_pass_functions_short::
|
|
fsZtest_never:
|
|
db 2 dup (NOP_CODE)
|
|
fsZtest_ge:
|
|
jae short @target
|
|
fsZtest_ne:
|
|
jne short @target
|
|
fsZtest_g:
|
|
ja short @target
|
|
fsZtest_le:
|
|
jbe short @target
|
|
fsZtest_e:
|
|
je short @target
|
|
fsZtest_l:
|
|
jb short @target
|
|
fsZtest_always:
|
|
jmp short $+2
|
|
|
|
@target:
|
|
|
|
ztest_fail_functions::
|
|
pZtest_never:
|
|
db 6 dup (NOP_CODE)
|
|
pZtest_l:
|
|
jb near ptr @target
|
|
pZtest_e:
|
|
je near ptr @target
|
|
pZtest_le:
|
|
jbe near ptr @target
|
|
pZtest_g:
|
|
ja near ptr @target
|
|
pZtest_ne:
|
|
jne near ptr @target
|
|
pZtest_ge:
|
|
jae near ptr @target
|
|
pZtest_always:
|
|
jmp $+6
|
|
|
|
|
|
ztest_pass_functions::
|
|
fZtest_never:
|
|
db 6 dup (NOP_CODE)
|
|
fZtest_ge:
|
|
jae near ptr @target
|
|
fZtest_ne:
|
|
jne near ptr @target
|
|
fZtest_g:
|
|
ja near ptr @target
|
|
fZtest_le:
|
|
jbe near ptr @target
|
|
fZtest_e:
|
|
je near ptr @target
|
|
fZtest_l:
|
|
jb near ptr @target
|
|
fZtest_always:
|
|
jmp $+6
|
|
|
|
|
|
;----------------------------------------------------------------------
|
|
; int __fastProcsSize
|
|
;
|
|
; Returns size needed for function/data storage. This could be done as
|
|
; a global...
|
|
;----------------------------------------------------------------------
|
|
|
|
__fastProcsSize PROC
|
|
mov eax, size __FASTFUNCSINTERNAL
|
|
ret
|
|
__fastProcsSize ENDP
|
|
|
|
|
|
;----------------------------------------------------------------------
|
|
; __fastDepthTestSpan
|
|
;
|
|
; Run the z interpolation for the supplied span.
|
|
;----------------------------------------------------------------------
|
|
|
|
|
|
zspan_begin::
|
|
|
|
__fastDepthTestSpan PROC uses ebx edx esi edi, GLCONTEXT: ptr
|
|
LOCAL deltazx: dword
|
|
LOCAL scan_len: dword
|
|
LOCAL scan_len_org: dword
|
|
LOCAL mask_addr: dword
|
|
|
|
mov esi, GLCONTEXT
|
|
|
|
mov edi, [esi].CTX_polygon.POLY_shader.SHADE_zbuf ; edi points to z-buffer
|
|
mov eax, [esi].CTX_polygon.POLY_shader.SHADE_spanLength
|
|
mov scan_len, eax
|
|
mov scan_len_org, eax
|
|
mov eax, [esi].CTX_polygon.POLY_shader.SHADE_dzdx
|
|
mov deltazx, eax
|
|
mov eax, [esi].CTX_polygon.POLY_shader.SHADE_stipplePat
|
|
mov mask_addr, eax
|
|
; eax is initial z value
|
|
mov eax, [esi].CTX_polygon.POLY_shader.SHADE_frag.FRAG_z
|
|
xor esi, esi ; esi maintains "fail" count
|
|
|
|
align 4
|
|
z_loop:
|
|
mov ecx, scan_len
|
|
sub scan_len, 32
|
|
test ecx, ecx
|
|
jle z_done
|
|
|
|
cmp ecx, 32
|
|
jle short small_zfrag
|
|
mov ecx, 32
|
|
small_zfrag:
|
|
|
|
;; alternative for above?
|
|
;; mov eax, 32 ; ecx = min(ecx-1, 31)
|
|
;; cmp eax, ecx
|
|
;; sbb ah, 0
|
|
;; dec ecx
|
|
;; or cl, ch
|
|
;; and ecx, 01fh
|
|
|
|
mov edx, 07fffffffh ; mask bit
|
|
mov ebx, -1 ; initial mask value is all 1's
|
|
|
|
align 4
|
|
zrep_pass: ; case for test pass
|
|
cmp eax, [edi]
|
|
zspan_pass_op::
|
|
jae short zcmp_fail_r1
|
|
zspan_write::
|
|
zcmp_pass_r1:
|
|
mov [edi],eax
|
|
add eax, deltazx
|
|
add edi, __GlzValueSize
|
|
ror edx, 1
|
|
dec ecx
|
|
jg short zrep_pass
|
|
|
|
mov ecx, mask_addr
|
|
mov [ecx], ebx
|
|
add ecx, 4
|
|
mov mask_addr, ecx
|
|
jmp short z_loop
|
|
|
|
align 4
|
|
zrep_fail: ; case for test fail
|
|
cmp eax, [edi]
|
|
zspan_fail_op::
|
|
jb short zcmp_pass_r1
|
|
zcmp_fail_r1:
|
|
add eax, deltazx
|
|
and ebx, edx
|
|
inc esi ; increment fail count
|
|
add edi, __GLzValueSize
|
|
ror edx, 1
|
|
dec ecx
|
|
jg short zrep_fail
|
|
|
|
mov ecx, mask_addr
|
|
mov [ecx], ebx
|
|
add ecx, 4
|
|
mov mask_addr, ecx
|
|
jmp short z_loop
|
|
|
|
z_done:
|
|
xor eax, eax
|
|
cmp esi, 0
|
|
jne z_fails
|
|
ret
|
|
z_fails:
|
|
inc eax
|
|
xor ebx, ebx
|
|
cmp esi, scan_len_org
|
|
jne z_fails_some
|
|
mov esi, GLCONTEXT
|
|
mov dword ptr [esi].CTX_polygon.POLY_shader.SHADE_done, 1
|
|
z_fails_some:
|
|
ret
|
|
|
|
__fastDepthTestSpan ENDP
|
|
|
|
zspan_end::
|
|
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset target - offset zspan_begin
|
|
ENDM
|
|
|
|
;----------------------------------------------------------------------
|
|
; __fastDepthTestSpanSetup(GLCONTEXT *)
|
|
;
|
|
; Copy the span depth-test span routine from the template and modify it
|
|
; to reflect the current z mode.
|
|
;----------------------------------------------------------------------
|
|
|
|
|
|
__fastDepthTestSpanSetup PROC uses ebx edx esi edi, GLCONTEXT: ptr
|
|
LOCAL funcAddr: dword
|
|
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanZFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastDepthTestSpan
|
|
mov ecx, (zspan_end - zspan_begin + 3) / 4
|
|
rep movsd
|
|
|
|
mov esi, GLCONTEXT
|
|
mov edx, [esi].CTX_drawBuffer
|
|
|
|
;; z-test conditions
|
|
|
|
mov ebx, [esi].CTX_state.ATTR_depth.DEPTH_testFunc
|
|
and ebx, 3
|
|
add ebx, ebx ; 2 bytes/short jump
|
|
|
|
;; z-test pass condition
|
|
|
|
mov al, byte ptr ztest_pass_functions_short[ebx]
|
|
XOFS zspan_pass_op
|
|
mov [edi], al
|
|
|
|
;; z-test fail condition
|
|
|
|
mov al, byte ptr ztest_fail_functions_short[ebx]
|
|
XOFS zspan_fail_op
|
|
mov [edi], al
|
|
|
|
|
|
;; z write-enable
|
|
|
|
test dword ptr [esi].CTX_state.ATTR_depth.DEPTH_writeEnable, 1
|
|
jne @zwriteEnabled
|
|
|
|
XOFS zspan_write
|
|
mov byte ptr [edi], NOP_CODE
|
|
mov byte ptr [edi]+1, NOP_CODE
|
|
|
|
mov eax, funcAddr
|
|
@zwriteEnabled:
|
|
ret
|
|
__fastDepthTestSpanSetup ENDP
|
|
|
|
|
|
;----------------------------------------------------------------------
|
|
; __fastDeltaSpan(GLCONTEXT *)
|
|
;
|
|
; Set up the scan x delta values for subsequent spans.
|
|
;----------------------------------------------------------------------
|
|
|
|
|
|
__fastDeltaSpan PROC uses ebx esi edi, GLCONTEXT: ptr, SCANDELTA: ptr
|
|
|
|
mov esi, GLCONTEXT
|
|
mov ebx, [esi].CTX_polygon.POLY_shader.SHADE_modeFlags
|
|
mov edi, [esi].GENCTX_pPrivateArea
|
|
mov edi, [edi]
|
|
mov esi, SCANDELTA
|
|
|
|
test ebx, __GL_SHADE_RGB
|
|
jne @doRGB
|
|
|
|
mov eax, __spanFlatFunc
|
|
test ebx, __GL_SHADE_SMOOTH
|
|
je @flatI
|
|
mov ecx, [esi].SPANREC_r
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_r, ecx
|
|
cmp ecx, 0
|
|
je @flatI
|
|
mov eax, __spanSmoothFunc
|
|
@flatI:
|
|
mov ecx, [esi].SPANREC_z
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_z, ecx
|
|
mov esi, GLCONTEXT
|
|
add eax, [esi].GENCTX_pPrivateArea
|
|
mov [edi].FASTFUNCS_fastSpanFuncPtr, eax
|
|
ret
|
|
|
|
@doRGB:
|
|
mov eax, __spanFlatFunc
|
|
test ebx, __GL_SHADE_SMOOTH
|
|
je @flatRGB
|
|
mov ecx, [esi].SPANREC_r
|
|
mov edx, ecx
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_r, ecx
|
|
mov ecx, [esi].SPANREC_g
|
|
or edx, ecx
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_g, ecx
|
|
mov ecx, [esi].SPANREC_b
|
|
or edx, ecx
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_b, ecx
|
|
je @flatRGB
|
|
mov eax, offset __spanSmoothFunc
|
|
@flatRGB:
|
|
mov ecx, [esi].SPANREC_z
|
|
mov [edi].FASTFUNCS_spanDelta.SPANREC_z, ecx
|
|
mov esi, GLCONTEXT
|
|
add eax, [esi].GENCTX_pPrivateArea
|
|
mov [edi].FASTFUNCS_fastSpanFuncPtr, eax
|
|
ret
|
|
|
|
__fastDeltaSpan ENDP
|
|
|
|
|
|
;======================================================================
|
|
; Smooth-shaded dithered RGB spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastRGB&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_ssrgb_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanSmoothFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastRGBSmoothSpan
|
|
mov ecx, (pix_ssrgb_end - pix_ssrgb_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_ssrgb_&target - offset pix_ssrgb_begin
|
|
;; Note: the assembler produces an error if we try to combine the
|
|
;; above into a single operation due to "mismatched segments". Arg!
|
|
ENDM
|
|
|
|
DITHER = 1
|
|
RGBMODE = 1
|
|
|
|
;=================
|
|
INCLUDE span_s.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Flat-shaded dithered RGB spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastRGB&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_fsrgb_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanFlatFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastRGBFlatSpan
|
|
mov ecx, (pix_fsrgb_end - pix_fsrgb_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_fsrgb_&target - offset pix_fsrgb_begin
|
|
ENDM
|
|
|
|
DITHER = 1
|
|
RGBMODE = 1
|
|
|
|
;=================
|
|
INCLUDE span_f.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Smooth-shaded dithered CI spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastCI&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_ssci_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanSmoothFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastCISmoothSpan
|
|
mov ecx, (pix_ssci_end - pix_ssci_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_ssci_&target - offset pix_ssci_begin
|
|
ENDM
|
|
|
|
DITHER = 1
|
|
RGBMODE = 0
|
|
|
|
;=================
|
|
INCLUDE span_s.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Flat-shaded dithered CI spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastCI&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_fsci_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanFlatFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastCIFlatSpan
|
|
mov ecx, (pix_fsci_end - pix_fsci_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_fsci_&target - offset pix_fsci_begin
|
|
ENDM
|
|
|
|
DITHER = 1
|
|
RGBMODE = 0
|
|
|
|
;=================
|
|
INCLUDE span_f.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
;======================================================================
|
|
;
|
|
; Non-dithered routines
|
|
;
|
|
;======================================================================
|
|
;======================================================================
|
|
|
|
|
|
;======================================================================
|
|
; Smooth-shaded non-dithered RGB spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastRGBND&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_ssrgbnd_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanSmoothFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastRGBNDSmoothSpan
|
|
mov ecx, (pix_ssrgbnd_end - pix_ssrgbnd_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_ssrgbnd_&target - offset pix_ssrgbnd_begin
|
|
;; Note: the assembler produces an error if we try to combine the
|
|
;; above into a single operation due to "mismatched segments". Arg!
|
|
ENDM
|
|
|
|
DITHER = 0
|
|
RGBMODE = 1
|
|
|
|
;=================
|
|
INCLUDE span_s.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Flat-shaded non-dithered RGB spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastRGBND&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_fsrgbnd_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanFlatFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastRGBNDFlatSpan
|
|
mov ecx, (pix_fsrgbnd_end - pix_fsrgbnd_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_fsrgbnd_&target - offset pix_fsrgbnd_begin
|
|
ENDM
|
|
|
|
DITHER = 0
|
|
RGBMODE = 1
|
|
|
|
;=================
|
|
INCLUDE span_f.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Smooth-shaded non-dithered CI spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastCIND&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_sscind_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanSmoothFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastCINDSmoothSpan
|
|
mov ecx, (pix_sscind_end - pix_sscind_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_sscind_&target - offset pix_sscind_begin
|
|
ENDM
|
|
|
|
DITHER = 0
|
|
RGBMODE = 0
|
|
|
|
;=================
|
|
INCLUDE span_s.asm
|
|
;=================
|
|
|
|
|
|
;======================================================================
|
|
; Flat-shaded non-dithered CI spans.
|
|
;======================================================================
|
|
|
|
|
|
PROCNAME MACRO name
|
|
__fastCIND&name
|
|
ENDM
|
|
|
|
XNAME MACRO name
|
|
pix_fscind_&name
|
|
ENDM
|
|
|
|
COPYPROC MACRO
|
|
mov edi, GLCONTEXT
|
|
mov edi, [edi].GENCTX_pPrivateArea
|
|
add edi, __spanFlatFunc
|
|
mov funcAddr, edi
|
|
mov esi, offset __fastCINDFlatSpan
|
|
mov ecx, (pix_fscind_end - pix_fscind_begin + 3) / 4
|
|
rep movsd
|
|
ENDM
|
|
|
|
;;Macro to compute relative offset between a base and target
|
|
|
|
XOFS MACRO target
|
|
mov edi, funcAddr
|
|
add edi, offset pix_fscind_&target - offset pix_fscind_begin
|
|
ENDM
|
|
|
|
DITHER = 0
|
|
RGBMODE = 0
|
|
|
|
;=================
|
|
INCLUDE span_f.asm
|
|
;=================
|
|
|
|
|
|
.data
|
|
|
|
|
|
__FASTFUNCSINTERNAL struct
|
|
__funcsPtr dd ?
|
|
align 4
|
|
__spanZFunc db (zspan_end - zspan_begin + 3) dup (0)
|
|
align 4
|
|
__spanSmoothFunc db (pix_ssrgb_end - pix_ssrgb_begin + 3) dup (0)
|
|
align 4
|
|
__spanFlatFunc db (pix_fsrgb_end - pix_fsrgb_begin + 3) dup (0)
|
|
align 4
|
|
__pad dd ?
|
|
__FASTFUNCSINTERNAL ENDS
|
|
|
|
END
|