windows-nt/Source/XPSP1/NT/multimedia/opengl/server/generic/i386/span.asm
2020-09-26 16:20:57 +08:00

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