kolibrios/programs/develop/libraries/TinyGL/asm_fork/specbuf.asm
IgorA 40df1da8cf some fixes
git-svn-id: svn://kolibrios.org@5256 a494cfbc-eb01-0410-851d-a64ba20cac60
2014-12-22 09:21:22 +00:00

112 lines
3.0 KiB
NASM

align 4
proc calc_buf uses ebx ecx, buf:dword, shininess:dword
locals
val dd ? ;float
f_inc dd ? ;float
endl
mov dword[val],0.0f
mov dword[f_inc],SPECULAR_BUFFER_SIZE
fld1
fidiv dword[f_inc]
fstp dword[f_inc] ;f_inc = 1.0f/SPECULAR_BUFFER_SIZE
xor ecx,ecx
align 4
.cycle_0: ;for (i = 0; i <= SPECULAR_BUFFER_SIZE; i++)
cmp ecx,SPECULAR_BUFFER_SIZE
jg @f
;Вычисляем x^y
fld dword[shininess]
fld dword[val]
fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
;Теперь считаем 2**z:
fld st0 ;Создаем еще одну копию z
frndint ;Округляем
fsubr st0,st1 ;st1=z, st0=z-trunc(z)
f2xm1 ;st1=z, st0=2**(z-trunc(z))-1
fld1
faddp ;st1=z, st0=2**(z-trunc(z))
fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
fxch st1
fstp st ;Результат остается на вершине стека st0
mov ebx,ecx
shl ebx,2
add ebx,offs_spec_buf
add ebx,[buf]
fstp dword[ebx] ;buf.buf[i] = pow(val, shininess)
fld dword[val]
fadd dword[f_inc]
fstp dword[val] ;val += f_inc
inc ecx
jmp .cycle_0
@@:
ret
endp
align 4
proc specbuf_get_buffer uses ebx ecx edx, context:dword, shininess_i:dword, shininess:dword
locals
found dd ? ;GLSpecBuf *
oldest dd ? ;GLSpecBuf *
endl
mov edx,[context]
mov eax,[edx+offs_cont_specbuf_first]
mov [found],eax
mov [oldest],eax
mov ebx,[shininess_i]
.cycle_0:
or eax,eax ;while (found)
jz @f
cmp [eax+offs_spec_shininess_i],ebx ;while (found.shininess_i != shininess_i)
je @f
mov ecx,[oldest]
mov ecx,[ecx+offs_spec_last_used]
cmp [eax+offs_spec_last_used],ecx ;if (found.last_used < oldest.last_used)
jge .end_0
mov [oldest],eax ;oldest = found
.end_0:
mov eax,[eax+offs_spec_next] ;found = found.next
jmp .cycle_0
@@:
cmp dword[found],0 ;if (found) /* hey, found one! */
je @f
mov eax,[found]
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx ;found.last_used = context.specbuf_used_counter
inc dword[edx+offs_cont_specbuf_used_counter]
jmp .end_f ;return found
@@:
cmp dword[oldest],0 ;if (oldest == NULL || context.specbuf_num_buffers < MAX_SPECULAR_BUFFERS)
je @f
cmp dword[edx+offs_cont_specbuf_num_buffers],MAX_SPECULAR_BUFFERS
jl @f
jmp .end_1
@@:
; create new buffer
stdcall gl_malloc, sizeof.GLSpecBuf
;if (!eax) gl_fatal_error("could not allocate specular buffer")
inc dword[edx+offs_cont_specbuf_num_buffers]
mov ecx,[edx+offs_cont_specbuf_first]
mov [eax+offs_spec_next],ecx
mov [edx+offs_cont_specbuf_first],eax
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx
inc dword[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_shininess_i],ebx
stdcall calc_buf, eax,dword[shininess]
jmp .end_f
.end_1:
; overwrite the lru buffer
;tgl_trace("overwriting spec buffer :(\n");
mov eax,[oldest]
mov [eax+offs_spec_shininess_i],ebx
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx
inc dword[edx+offs_cont_specbuf_used_counter]
stdcall calc_buf, eax,dword[shininess]
.end_f:
ret
endp