; ========================================================================================
; FillColor(x,y,w,h,c)
; p1: r8d = x
; p2: r9d = y
; p3: r10d = width
; p4: r11d = height
; p5: r12d = rgb color
;
; Dispatches to AVX2 or SSE based on cpuSupport.
; ========================================================================================
MEMORY$ equ 20000000h ; base of emulator RAM
VIDEO$ equ 24000000h ; 2048x1080x4 = $87:0000 bytes
SPRITE$ equ VIDEO$+880000h ; 2048x64x4 = 80000h (512k)
REU$ equ 25000000h ; 16 mb reu
global FillColor
export FillColor
align 16
FillColor:
sub rsp, 28h
mov [rsp+00h], rsi
mov [rsp+08h], rdi
mov [rsp+10h], rbx
mov [rsp+18h], rbp
mov [rsp+20h], r15
; ----- Enter -----
; Compute starting dst: base + y*pitch + x*4
mov edi, VIDEO$ ;base
shl r8d, 2 ; x * 4
shl r9d, 13 ; y * 2000h
add edi, r8d
add edi, r9d ; dst ptr
mov ebp, edi ; 1st row ptr = dst ptr
; --------------------------------------
; CPU feature detection (AVX yes/no)
; --------------------------------------
xor r15d, r15d ; default = 0 (no avx)
mov eax, 1
cpuid
shr ecx, 28 ; shift AVX feature bit into bit 0
and ecx, 1 ; isolate the bit (will be 0 or 1)
add r15d, ecx ; add 0 (no AVX) or 1 (AVX)
test r15d, r15d
jz .use_sse
; --------
; AVX path
; --------
call FillColorAVX
jmp .Exit
; --------
; SSE path
; --------
.use_sse:
call FillColorSSE
; ----- Exit -----
.Exit:
mov rsi, [rsp+00h]
mov rdi, [rsp+08h]
mov rbx, [rsp+10h]
mov rbp, [rsp+18h]
mov r15, [rsp+20h]
add rsp, 28h
ret
; ========================================================================================
; ========================================================================================
; FillColorAVX2: (x,w) must be multiples of 8 pixels
; ========================================================================================
; r8d = x, r9d = y, r10d = w, r11d = h, r12d = color
; ========================================================================================
global FillColorAVX
;export FillColorAVX
align 16
FillColorAVX:
; Broadcast color to ymm0
movd xmm1, r12d ; color
vbroadcastss ymm0, xmm1
shr r10d, 3 ; 8 pixels per ymm0
; ----- The Loop -----
mov edx, r11d ; height
.fc0:
mov ecx, r10d ; width
; shr ecx, 3 ; 8 pixels per ymm0
.fc1:
vmovdqa [edi], ymm0
add edi, 32 ; 8 * 4 bytes
dec ecx
jnz .fc1
; next row
add ebp, 2000h ; next row ptr
mov edi, ebp ; next dst ptr
dec edx
jnz .fc0
ret
; ========================================================================================
; ========================================================================================
; FillColorSSE: (x,w) must be multiples of 4 pixels
; ========================================================================================
; r8d = x, r9d = y, r10d = w, r11d = h, r12d = color
; ========================================================================================
global FillColorSSE
;export FillColorSSE
align 16
FillColorSSE:
movd xmm0, r12d
pshufd xmm0, xmm0, 0 ; replicate color to 4 dwords
shr r10d, 2 ; 4 pixels per xmm0
; ----- The Loop -----
mov edx, r11d ; height
.fc0:
mov ecx, r10d ; width
; shr ecx, 2 ; 4 pixels per xmm0
.fc1:
movdqa [edi], xmm0
add edi, 16
dec ecx
jnz .fc1
add ebp, 2000h
mov edi, ebp
dec edx
jnz .fc0
ret
; ========================================================================================