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.
171 lines
4.8 KiB
171 lines
4.8 KiB
;-----------------------------------------------------------------------------
|
|
;
|
|
; This file contains the alpha test functions.
|
|
;
|
|
; Copyright (C) Microsoft Corporation, 1997.
|
|
;
|
|
;
|
|
;-----------------------------------------------------------------------------
|
|
INCLUDE iammx.inc
|
|
INCLUDE offs_acp.inc
|
|
|
|
|
|
include(`m4hdr.mh')dnl
|
|
include(`cvars.mh')dnl
|
|
|
|
.586
|
|
.model flat
|
|
.code
|
|
|
|
EXTERN g_uDitherValue:MMWORD
|
|
|
|
; Alpha Test compare macro
|
|
;#define ACMP(p, g, b) \
|
|
;((((((INT32)(g) - (INT32)(b)) & (p)->iAAndMask) - (p)->iANeg) >= 0) ^ (p)->iAXorMask)
|
|
|
|
define(`d_LabelCounter', 0)dnl
|
|
dnl
|
|
dnl d_DoZWrite
|
|
dnl
|
|
dnl Inserts conditional Z Defered write code
|
|
dnl $1 the function type, $2 is the format of the Z buffer.
|
|
dnl
|
|
define(`d_DoZWrite', `
|
|
ifelse(`$1', `NoZWrite', `', `
|
|
ifelse(`$2', `16', `
|
|
; *((UINT16*)pS->pZ) = (UINT16)pCtx->SI.uZDeferred;
|
|
mov esi, XpS(pZ)
|
|
movzx edx, word ptr XpCtxSI(uZDeferred)
|
|
mov word ptr [esi], dx
|
|
', `
|
|
;*((UINT32*)pS->pZ) = pCtx->SI.uZDeferred;
|
|
mov esi, XpS(pZ)
|
|
mov edx, dword ptr XpCtxSI(uZDeferred)
|
|
mov dword ptr [esi], edx
|
|
')dnl if 16
|
|
')dnl if NoZWrite
|
|
')dnl d_DoZWrite define
|
|
dnl d_DoAlphaDitherTest
|
|
dnl
|
|
dnl
|
|
dnl d_DoEnd
|
|
dnl
|
|
dnl $1 is NoStencil or Stencil
|
|
dnl
|
|
define(`d_DoEnd', `ifelse($1, `NoStencil', `
|
|
; pCtx->pfnAlphaTestPassEnd(pCtx, pP, pS);
|
|
jmp dword ptr XpCtx(pfnAlphaTestPassEnd)
|
|
', `
|
|
; if (pCtx->SI.bStencilPass)
|
|
; {
|
|
; pCtx->pfnAlphaTestPassEnd(pCtx, pP, pS);
|
|
; }
|
|
; else
|
|
; {
|
|
; // in the C code this does a return, since this is the
|
|
; // last bead before write
|
|
; // pCtx->pfnAlphaTestFailEnd(pCtx, pP, pS);
|
|
; }
|
|
cmp word ptr XpCtxSI(bStencilPass), 0
|
|
je NoWrite ; All cases can jump to same label since all just routine to span loop.
|
|
jmp dword ptr XpCtx(pfnAlphaTestPassEnd)
|
|
')')dnl
|
|
dnl
|
|
dnl Inserts conditional AlphaDither Test code
|
|
dnl $1 the function type
|
|
dnl $2 is the ZWrite type
|
|
dnl $3 is the format of the Z buffer
|
|
dnl $4 is whether this function do a conditional return based on stencil
|
|
dnl
|
|
define(`d_DoAlphaDitherTest', `ifelse(`$1', `NoAlphaDither', `', `
|
|
|
|
define(`d_LabelCounter', eval(d_LabelCounter+1))dnl
|
|
|
|
;INT32 Alpha;
|
|
xor eax, eax ; Prevent partial register stall. Since alpha will be one byte.
|
|
|
|
;UINT16 uDither = g_uDitherTable[pCtx->SI.uDitherOffset];
|
|
mov edx, DWORD PTR g_uDitherValue ; Only need one byte for comparison.
|
|
shr edx, 3 ; The dither values are shifted to make color dithering easier.
|
|
; Just shift them back down.
|
|
|
|
;if (pCtx->cActTex != 0)
|
|
;{
|
|
cmp dword ptr XpCtx(cActTex), 0
|
|
je NoTexture`'d_LabelCounter`'
|
|
|
|
;Alpha = RGBA_GETALPHA(pCtx->SI.TexCol[0]);
|
|
mov al, byte ptr XpCtxSI(TexCol+3)
|
|
jmp DoneTexture`'d_LabelCounter`'
|
|
;}
|
|
;else
|
|
;{
|
|
NoTexture`'d_LabelCounter`':
|
|
;Alpha = pS->uA >> COLOR_SHIFT;
|
|
mov al, byte ptr XpS(uA+1)
|
|
;}
|
|
DoneTexture`'d_LabelCounter`':
|
|
|
|
;if ((Alpha & 0xff) > uDither)
|
|
;{
|
|
cmp al, dl
|
|
jbe DitherAlpha`'d_LabelCounter`'
|
|
|
|
d_DoZWrite($2, $3)
|
|
d_DoEnd($4)
|
|
;}
|
|
DitherAlpha`'d_LabelCounter`':
|
|
')')dnl
|
|
|
|
define(`d_AlphaHdr', `
|
|
;void MMX_AlphaTest_$1_$2_$3_$4_$5(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS)
|
|
;{
|
|
PUBLIC _MMX_AlphaTest_$1_$2_$3_$4_$5
|
|
_MMX_AlphaTest_$1_$2_$3_$4_$5:
|
|
|
|
ifelse(`$1', `NoAlpha',
|
|
`d_DoAlphaDitherTest(`$2', `$3', `$4', `$5')', `
|
|
;if (ACMP(pCtx, pCtx->SI.uBA, pCtx->iARef))
|
|
;{
|
|
movzx edx, word ptr XpCtxSI(uBA)
|
|
sub edx, dword ptr XpCtx(iARef)
|
|
and edx, XpCtx(iAAndMask)
|
|
sub edx, XpCtx(iANeg)
|
|
sar edx, 31
|
|
xor edx, XpCtx(iAXorMask)
|
|
test edx, edx
|
|
jz NoWrite ; All cases can jump to same label since all just routine to span loop.
|
|
|
|
ifelse($2, `NoAlphaDither', `
|
|
d_DoZWrite(`$3', `$4')
|
|
d_DoEnd($5)
|
|
', `
|
|
d_DoAlphaDitherTest(`$2', `$3', `$4', `$5')
|
|
')
|
|
;}
|
|
;else
|
|
;{
|
|
;// in the C code this does a return, since this is the
|
|
;// last bead before write
|
|
;// pCtx->pfnAlphaTestFailEnd(pCtx, pP, pS);
|
|
; ASM code has everything jump to same label since it all goes to the same place.
|
|
;}')
|
|
dnl
|
|
; If Alpha Test passes, but alpha dither fails, we still need to call
|
|
; AlphaTestFailEnd or code continues to run into next routine.
|
|
jmp dword ptr XpCtx(pfnAlphaTestFailEnd)
|
|
;}')
|
|
dnl
|
|
|
|
NoWrite:
|
|
jmp dword ptr XpCtx(pfnAlphaTestFailEnd)
|
|
|
|
|
|
d_RepStr(`d_RepStr(`d_RepStr(`d_RepStr(`d_RepStr(`d_AlphaHdr(AA, BB, CC, DD, EE)',
|
|
`AA', `NoAlpha', `Alpha')',
|
|
`BB', `NoAlphaDither', `AlphaDither')',
|
|
`CC', `NoZWrite', `ZWrite')',
|
|
`DD', `16', `32')',
|
|
`EE', `NoStencil', `Stencil')
|
|
|
|
END
|