Subversion Repositories Kolibri OS

Rev

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