Subversion Repositories Kolibri OS

Rev

Rev 5153 | Rev 6172 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5153 IgorA 1
;
2
;
3
; Z buffer: 16 bits Z / 16 bits color
4
;
5
;
6
;include 'zbuffer.inc'
7
 
8
;output:
9
; eax - указатель на ZBuffer (0 если не удача)
10
align 4
11
proc ZB_open uses ecx edi, xsize:dword, ysize:dword, mode:dword,\
12
		nb_colors:dword, color_indexes:dword, color_table:dword, frame_buffer:dword
13
 
14
	stdcall gl_malloc, sizeof.ZBuffer
15
	cmp eax,0
16
	jne @f
17
		stdcall dbg_print,f_zb_opn,err_1
18
		jmp .end_f
19
	@@:
20
	mov edi,eax
21
 
22
	mov eax,[ysize]
23
	mov [edi+offs_zbuf_ysize],eax
24
	mov eax,[xsize]
25
	mov [edi+offs_zbuf_xsize],eax
26
	imul eax,PSZB
27
	add eax,3
28
	and eax,not 3
29
	mov [edi+offs_zbuf_linesize],eax
30
	mov eax,[mode]
31
	mov [edi+offs_zbuf_mode],eax
32
 
33
if TGL_FEATURE_8_BITS eq 1
34
	cmp eax,ZB_MODE_INDEX
35
	jne @f
36
;ZB_initDither(edi, nb_colors, color_indexes, color_table);
37
		jmp .end_s
38
	@@:
39
end if
40
if TGL_FEATURE_32_BITS eq 1
41
	cmp eax,ZB_MODE_RGBA
42
	je .correct
43
end if
44
if TGL_FEATURE_24_BITS eq 1
45
	cmp eax,ZB_MODE_RGB24
46
	je .correct
47
end if
48
	cmp eax,ZB_MODE_5R6G5B
49
	jne @f
50
	.correct:
51
		mov dword[edi+offs_zbuf_nb_colors],0
52
		jmp .end_s
53
	@@: ;default:
54
		stdcall dbg_print,f_zb_opn,err_3
55
		jmp .error
56
	.end_s:
57
 
58
	mov ecx,[edi+offs_zbuf_xsize]
59
	imul ecx,[edi+offs_zbuf_ysize]
5159 IgorA 60
	shl ecx,1 ;*= sizeof(unsigned short)
5153 IgorA 61
 
62
	stdcall gl_malloc, ecx
63
	mov [edi+offs_zbuf_zbuf],eax
64
	cmp eax,0
65
	jne @f
66
		stdcall dbg_print,f_zb_opn,err_2
67
		jmp .error
68
	@@:
69
 
70
	mov dword[edi+offs_zbuf_frame_buffer_allocated],0
71
	mov dword[edi+offs_zbuf_pbuf],0 ;NULL
72
 
73
	mov dword[edi+offs_zbuf_current_texture],0 ;NULL
74
 
75
	mov eax,edi
76
	jmp .end_f
77
	.error:
78
		stdcall gl_free,edi
79
		xor eax,eax
80
	.end_f:
81
	ret
82
endp
83
 
84
;void ZB_close(ZBuffer * zb)
85
;{
86
if TGL_FEATURE_8_BITS eq 1
87
;    if (zb->mode == ZB_MODE_INDEX)
88
;	ZB_closeDither(zb);
89
end if
90
;
91
;    if (zb->frame_buffer_allocated)
92
;	gl_free(zb->pbuf);
93
;
94
;    gl_free(zb->zbuf);
95
;    gl_free(zb);
96
;}
97
 
98
align 4
99
proc ZB_resize uses eax ebx ecx edi esi, zb:dword, frame_buffer:dword, xsize:dword, ysize:dword
100
	mov ebx,[zb]
101
 
102
	; xsize must be a multiple of 4
103
	mov edi,[xsize]
104
	and edi,not 3
105
	mov esi,[ysize]
106
 
107
	mov [ebx+offs_zbuf_xsize], edi
108
	mov [ebx+offs_zbuf_ysize], esi
109
 
110
	mov eax,edi
111
	imul eax,PSZB
112
	add eax,3
113
	and eax,not 3
114
	mov [ebx+offs_zbuf_linesize],eax ;zb.linesize = (xsize * PSZB + 3) & ~3
115
 
116
	mov ecx,edi
117
	imul ecx,esi
5159 IgorA 118
	shl ecx,1 ;*= sizeof(unsigned short)
5153 IgorA 119
 
120
	stdcall gl_free,dword[ebx+offs_zbuf_zbuf]
121
	stdcall gl_malloc,ecx
122
	mov [ebx+offs_zbuf_zbuf],eax
123
 
124
	cmp dword[ebx+offs_zbuf_frame_buffer_allocated],0
125
	je @f
126
		stdcall gl_free,dword[ebx+offs_zbuf_pbuf]
127
	@@:
128
 
129
	cmp dword[frame_buffer],0
130
	jne .els_0
131
		inc esi
132
		imul esi,dword[ebx+offs_zbuf_linesize]
133
		stdcall gl_malloc,esi
134
		mov dword[ebx+offs_zbuf_pbuf],eax
135
		mov dword[ebx+offs_zbuf_frame_buffer_allocated],1
136
		jmp @f
137
	.els_0:
138
		mov eax,[frame_buffer]
139
		mov dword[ebx+offs_zbuf_pbuf],eax
140
		mov dword[ebx+offs_zbuf_frame_buffer_allocated],0
141
	@@:
142
	ret
143
endp
144
 
145
;static void ZB_copyBuffer(ZBuffer * zb,
146
;                          void *buf,
147
;                          int linesize)
148
;{
149
;    unsigned char *p1;
150
;    PIXEL *q;
151
;    int y, n;
152
;
153
;    q = zb->pbuf;
154
;    p1 = buf;
155
;    n = zb->xsize * PSZB;
156
;    for (y = 0; y < zb->ysize; y++) {
157
;	memcpy(p1, q, n);
158
;	p1 += linesize;
159
;	q = (PIXEL *) ((char *) q + zb->linesize);
160
;    }
161
;}
162
;
163
;#if TGL_FEATURE_RENDER_BITS == 16
164
 
165
;/* 32 bpp copy */
166
 
167
;#ifdef TGL_FEATURE_32_BITS
168
 
169
;#define RGB16_TO_RGB32(p0,p1,v)\
170
;{\
171
;    unsigned int g,b,gb;\
172
;    g = (v & 0x07E007E0) << 5;\
173
;    b = (v & 0x001F001F) << 3;\
174
;    gb = g | b;\
175
;    p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\
176
;    p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\
177
;}
178
 
179
;static void ZB_copyFrameBufferRGB32(ZBuffer * zb,
180
;                                    void *buf,
181
;                                    int linesize)
182
;{
183
;    unsigned short *q;
184
;    unsigned int *p, *p1, v, w0, w1;
185
;    int y, n;
186
;
187
;    q = zb->pbuf;
188
;    p1 = (unsigned int *) buf;
189
;
190
;    for (y = 0; y < zb->ysize; y++) {
191
;	p = p1;
192
;	n = zb->xsize >> 2;
193
;	do {
194
;	    v = *(unsigned int *) q;
195
;#if BYTE_ORDER == BIG_ENDIAN
196
;	    RGB16_TO_RGB32(w1, w0, v);
197
;#else
198
;	    RGB16_TO_RGB32(w0, w1, v);
199
;#endif
200
;	    p[0] = w0;
201
;	    p[1] = w1;
202
;
203
;	    v = *(unsigned int *) (q + 2);
204
;#if BYTE_ORDER == BIG_ENDIAN
205
;	    RGB16_TO_RGB32(w1, w0, v);
206
;#else
207
;	    RGB16_TO_RGB32(w0, w1, v);
208
;#endif
209
;	    p[2] = w0;
210
;	    p[3] = w1;
211
;
212
;	    q += 4;
213
;	    p += 4;
214
;	} while (--n > 0);
215
;
216
;	p1 += linesize;
217
;    }
218
;}
219
 
220
;#endif
221
 
222
;/* 24 bit packed pixel handling */
223
 
224
;#ifdef TGL_FEATURE_24_BITS
225
 
226
;/* order: RGBR GBRG BRGB */
227
 
228
;/* XXX: packed pixel 24 bit support not tested */
229
;/* XXX: big endian case not optimised */
230
 
231
;#if BYTE_ORDER == BIG_ENDIAN
232
 
233
;#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
234
;{\
235
;    unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
236
;    v1 = (v1 << 16) | (v1 >> 16);\
237
;    v2 = (v2 << 16) | (v2 >> 16);\
238
;    r1 = (v1 & 0xF800F800);\
239
;    g1 = (v1 & 0x07E007E0) << 5;\
240
;    b1 = (v1 & 0x001F001F) << 3;\
241
;    gb1 = g1 | b1;\
242
;    p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
243
;    g2 = (v2 & 0x07E007E0) << 5;\
244
;    b2 = (v2 & 0x001F001F) << 3;\
245
;    gb2 = g2 | b2;\
246
;    p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
247
;    p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
248
;}
249
 
250
;#else
251
 
252
;#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
253
;{\
254
;    unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
255
;    r1 = (v1 & 0xF800F800);\
256
;    g1 = (v1 & 0x07E007E0) << 5;\
257
;    b1 = (v1 & 0x001F001F) << 3;\
258
;    gb1 = g1 | b1;\
259
;    p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
260
;    g2 = (v2 & 0x07E007E0) << 5;\
261
;    b2 = (v2 & 0x001F001F) << 3;\
262
;    gb2 = g2 | b2;\
263
;    p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
264
;    p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
265
;}
266
 
267
;#endif
268
 
269
;static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
270
;                                    void *buf, int linesize)
271
;{
272
;    unsigned short *q;
273
;    unsigned int *p, *p1, w0, w1, w2, v0, v1;
274
;    int y, n;
275
;
276
;    q = zb->pbuf;
277
;    p1 = (unsigned int *) buf;
278
;    linesize = linesize * 3;
279
;
280
;    for (y = 0; y < zb->ysize; y++) {
281
;	p = p1;
282
;	n = zb->xsize >> 2;
283
;	do {
284
;	    v0 = *(unsigned int *) q;
285
;	    v1 = *(unsigned int *) (q + 2);
286
;	    RGB16_TO_RGB24(w0, w1, w2, v0, v1);
287
;	    p[0] = w0;
288
;	    p[1] = w1;
289
;	    p[2] = w2;
290
 
291
;	    q += 4;
292
;	    p += 3;
293
;	} while (--n > 0);
294
;
295
;	(char *) p1 += linesize;
296
;    }
297
;}
298
 
299
;#endif
300
 
301
;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
302
;			int linesize)
303
;{
304
;    switch (zb->mode) {
305
;#ifdef TGL_FEATURE_8_BITS
306
;    case ZB_MODE_INDEX:
307
;	ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
308
;	break;
309
;#endif
310
;#ifdef TGL_FEATURE_16_BITS
311
;    case ZB_MODE_5R6G5B:
312
;	ZB_copyBuffer(zb, buf, linesize);
313
;	break;
314
;#endif
315
;#ifdef TGL_FEATURE_32_BITS
316
;    case ZB_MODE_RGBA:
317
;	ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
318
;	break;
319
;#endif
320
;#ifdef TGL_FEATURE_24_BITS
321
;    case ZB_MODE_RGB24:
322
;	ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
323
;	break;
324
;#endif
325
;    default:
326
;	assert(0);
327
;    }
328
;}
329
 
330
;#endif /* TGL_FEATURE_RENDER_BITS == 16 */
331
 
332
;#if TGL_FEATURE_RENDER_BITS == 24
333
 
334
;#define RGB24_TO_RGB16(r, g, b) \
335
;  ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
336
 
337
;/* XXX: not optimized */
338
;static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
339
;                                     void *buf, int linesize)
340
;{
341
;    PIXEL *q;
342
;    unsigned short *p, *p1;
343
;    int y, n;
344
;
345
;    q = zb->pbuf;
346
;    p1 = (unsigned short *) buf;
347
;
348
;    for (y = 0; y < zb->ysize; y++) {
349
;	p = p1;
350
;	n = zb->xsize >> 2;
351
;	do {
352
;            p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
353
;            p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
354
;            p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
355
;            p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
356
;	    q = (PIXEL *)((char *)q + 4 * PSZB);
357
;	    p += 4;
358
;	} while (--n > 0);
359
;	p1 = (unsigned short *)((char *)p1 + linesize);
360
;    }
361
;}
362
 
363
;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
364
;			int linesize)
365
;{
366
;    switch (zb->mode) {
367
;#ifdef TGL_FEATURE_16_BITS
368
;    case ZB_MODE_5R6G5B:
369
;	ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
370
;	break;
371
;#endif
372
;#ifdef TGL_FEATURE_24_BITS
373
;    case ZB_MODE_RGB24:
374
;	ZB_copyBuffer(zb, buf, linesize);
375
;	break;
376
;#endif
377
;    default:
378
;	assert(0);
379
;    }
380
;}
381
 
382
;#endif /* TGL_FEATURE_RENDER_BITS == 24 */
383
 
384
;#if TGL_FEATURE_RENDER_BITS == 32
385
 
386
;#define RGB32_TO_RGB16(v) \
387
;  (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
388
 
389
;/* XXX: not optimized */
390
;static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
391
;                                     void *buf, int linesize)
392
;{
393
;    PIXEL *q;
394
;    unsigned short *p, *p1;
395
;    int y, n;
396
;
397
;    q = zb->pbuf;
398
;    p1 = (unsigned short *) buf;
399
;
400
;    for (y = 0; y < zb->ysize; y++) {
401
;	p = p1;
402
;	n = zb->xsize >> 2;
403
;	do {
404
;            p[0] = RGB32_TO_RGB16(q[0]);
405
;            p[1] = RGB32_TO_RGB16(q[1]);
406
;            p[2] = RGB32_TO_RGB16(q[2]);
407
;            p[3] = RGB32_TO_RGB16(q[3]);
408
;	    q += 4;
409
;	    p += 4;
410
;	} while (--n > 0);
411
;	p1 = (unsigned short *)((char *)p1 + linesize);
412
;    }
413
;}
414
;
415
;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
416
;			int linesize)
417
;{
418
;    switch (zb->mode) {
419
;#ifdef TGL_FEATURE_16_BITS
420
;    case ZB_MODE_5R6G5B:
421
;	ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
422
;	break;
423
;#endif
424
;#ifdef TGL_FEATURE_32_BITS
425
;    case ZB_MODE_RGBA:
426
;	ZB_copyBuffer(zb, buf, linesize);
427
;	break;
428
;#endif
429
;    default:
430
;	assert(0);
431
;    }
432
;}
433
;
434
;#endif /* TGL_FEATURE_RENDER_BITS == 32 */
5159 IgorA 435
 
436
 
5153 IgorA 437
;
5159 IgorA 438
; adr must be aligned on an 'int'
5153 IgorA 439
;
5159 IgorA 440
align 4
441
proc memset_s uses eax ecx edi, adr:dword, val:dword, count:dword
442
	mov eax,[val]
443
	mov di,ax
444
	ror eax,16
445
	mov ax,di
446
	mov ecx,[count]
447
	shr ecx,1
448
	mov edi,[adr]
449
	rep stosd
450
 
451
	bt dword[count],0
452
	jnc @f
453
		stosw
454
	@@:
455
	ret
456
endp
457
 
458
align 4
459
proc memset_l uses eax ecx edi, adr:dword, val:dword, count:dword
460
	mov eax,[val]
461
	mov ecx,[count]
462
	mov edi,[adr]
463
	rep stosd
464
	ret
465
endp
466
 
467
; count must be a multiple of 4 and >= 4
468
align 4
469
proc memset_RGB24 uses eax ecx edi esi, adr:dword, r:dword, g:dword, b:dword, count:dword
470
	mov esi,[adr]
471
	mov eax,[r] ;копируем в буфер первые 12 байт (минимальное число кратное 3 и 4)
472
	mov byte[esi],al
473
	mov byte[esi+3],al
474
	mov byte[esi+6],al
475
	mov byte[esi+9],al
476
	mov eax,[g]
477
	mov byte[esi+1],al
478
	mov byte[esi+4],al
479
	mov byte[esi+7],al
480
	mov byte[esi+10],al
481
	mov eax,[b]
482
	mov byte[esi+2],al
483
	mov byte[esi+5],al
484
	mov byte[esi+8],al
485
	mov byte[esi+11],al
486
 
487
	mov ecx,[count]
488
	shr ecx,2
489
	cmp ecx,1
490
	jle .end_f ;если ширина буфера меньше 12 байт, то выходим
491
	dec ecx
492
	mov edi,esi
493
	add edi,12
494
 
495
	mov eax,[esi]
496
	cmp eax,[esi+4]
497
	jne @f
498
		;если r=g и g=b и b=r
499
		mov esi,ecx
500
		shl ecx,2
501
		sub ecx,esi ;ecx*=3
502
		rep stosd
503
		jmp .end_f
504
	@@:
505
 
506
	;если r!=g или g!=b или b!=r
507
	@@:
508
		movsd
509
		movsd
510
		movsd
511
		sub esi,12
512
	loop @b
513
	.end_f:
514
	ret
515
endp
516
 
517
align 4
518
proc ZB_clear uses eax ebx ecx, zb:dword, clear_z:dword, z:dword, clear_color:dword,\
519
	r:dword, g:dword, b:dword
520
;if TGL_FEATURE_RENDER_BITS != 24
521
;	color dd ?
522
;end if
523
 
524
	mov eax,[zb]
525
	cmp dword[clear_z],0
526
	je @f
527
		mov ebx,[eax+offs_zbuf_xsize]
528
		imul ebx,[eax+offs_zbuf_ysize]
529
		stdcall memset_s, [eax+offs_zbuf_zbuf],[z],ebx
530
	@@:
531
	cmp dword[clear_color],0
532
	je @f
533
if TGL_FEATURE_RENDER_BITS eq 24
534
		mov ebx,[eax+offs_zbuf_xsize]
535
		push ebx
536
		mov ebx,[b]
537
		shr ebx,8
538
		push ebx
539
		mov ebx,[g]
540
		shr ebx,8
541
		push ebx
542
		mov ebx,[r]
543
		shr ebx,8
544
		push ebx
545
		add esp,16
546
end if
547
		mov ebx,[eax+offs_zbuf_pbuf]
548
		mov ecx,[eax+offs_zbuf_ysize]
549
		.cycle_0:
550
if (TGL_FEATURE_RENDER_BITS eq 15) ;or (TGL_FEATURE_RENDER_BITS eq 16)
551
			;color = RGB_TO_PIXEL(r, g, b);
552
			;memset_s(ebx, color, zb->xsize);
553
end if
554
if TGL_FEATURE_RENDER_BITS eq 32
555
			;color = RGB_TO_PIXEL(r, g, b);
556
			;memset_l(ebx, color, zb->xsize);
557
end if
558
if TGL_FEATURE_RENDER_BITS eq 24
559
			sub esp,16
560
			stdcall memset_RGB24,ebx
561
end if
562
			add ebx,[eax+offs_zbuf_linesize]
563
		loop .cycle_0
564
	@@:
565
	ret
566
endp