881f3e6337b41dabbeef36220eefe7ecb9c77b55
[mesa.git] / src / mesa / swrast / s_renderbuffer.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * Functions for allocating/managing software-based renderbuffers.
28 * Also, routines for reading/writing software-based renderbuffer data as
29 * ubytes, ushorts, uints, etc.
30 */
31
32
33 #include "main/glheader.h"
34 #include "main/imports.h"
35 #include "main/context.h"
36 #include "main/fbobject.h"
37 #include "main/formats.h"
38 #include "main/mtypes.h"
39 #include "main/renderbuffer.h"
40 #include "swrast/s_renderbuffer.h"
41
42
43 /*
44 * Routines for get/put values in common buffer formats follow.
45 */
46
47 /* Returns a bytes per pixel of the DataType in the get/put span
48 * functions for at least a subset of the available combinations a
49 * renderbuffer can have.
50 *
51 * It would be nice to see gl_renderbuffer start talking about a
52 * gl_format instead of a GLenum DataType.
53 */
54 static int
55 get_datatype_bytes(struct gl_renderbuffer *rb)
56 {
57 int component_size;
58
59 switch (rb->DataType) {
60 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
61 component_size = 8;
62 break;
63 case GL_FLOAT:
64 case GL_UNSIGNED_INT:
65 case GL_UNSIGNED_INT_24_8_EXT:
66 component_size = 4;
67 break;
68 case GL_UNSIGNED_SHORT:
69 component_size = 2;
70 break;
71 case GL_UNSIGNED_BYTE:
72 component_size = 1;
73 break;
74 default:
75 component_size = 1;
76 assert(0);
77 }
78
79 switch (rb->_BaseFormat) {
80 case GL_DEPTH_COMPONENT:
81 case GL_DEPTH_STENCIL:
82 return component_size;
83 default:
84 return 4 * component_size;
85 }
86 }
87
88 /* This is commonly used by most of the accessors. */
89 static void *
90 get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
91 GLint x, GLint y)
92 {
93 if (!rb->Data)
94 return NULL;
95
96 return ((char *) rb->Data +
97 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format));
98 }
99
100 /* GetRow() implementation for formats where DataType matches the rb->Format.
101 */
102 static void
103 get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
104 GLuint count, GLint x, GLint y, void *values)
105 {
106 void *src = rb->GetPointer(ctx, rb, x, y);
107 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format));
108 }
109
110 /* Only used for float textures currently, but might also be used for
111 * RGBA8888, RGBA16, etc.
112 */
113 static void
114 get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
115 GLuint count, const GLint x[], const GLint y[], void *values)
116 {
117 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
118 GLuint i;
119
120 for (i = 0; i < count; i++) {
121 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]);
122 char *dst = (char *) values + i * format_bytes;
123 memcpy(dst, src, format_bytes);
124 }
125 }
126
127 /* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and
128 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of
129 * storing those initial components of the value per pixel into the
130 * destination.
131 */
132 static void
133 put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
134 GLuint count, GLint x, GLint y,
135 const void *values, const GLubyte *mask)
136 {
137 void *row = rb->GetPointer(ctx, rb, x, y);
138 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
139 int datatype_bytes = get_datatype_bytes(rb);
140 unsigned int i;
141
142 if (mask) {
143 for (i = 0; i < count; i++) {
144 char *dst = (char *) row + i * format_bytes;
145 const char *src = (const char *) values + i * datatype_bytes;
146
147 if (mask[i]) {
148 memcpy(dst, src, format_bytes);
149 }
150 }
151 }
152 else {
153 for (i = 0; i < count; i++) {
154 char *dst = (char *) row + i * format_bytes;
155 const char *src = (const char *) values + i * datatype_bytes;
156 memcpy(dst, src, format_bytes);
157 }
158 }
159 }
160
161
162 static void
163 put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb,
164 GLuint count, const GLint x[], const GLint y[],
165 const void *values, const GLubyte *mask)
166 {
167 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat);
168 int datatype_bytes = get_datatype_bytes(rb);
169 unsigned int i;
170
171 for (i = 0; i < count; i++) {
172 if (!mask || mask[i]) {
173 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
174 const char *src = (const char *) values + i * datatype_bytes;
175 memcpy(dst, src, format_bytes);
176 }
177 }
178 }
179
180
181
182 /**********************************************************************
183 * Functions for buffers of 1 X GLubyte values.
184 * Typically stencil.
185 */
186
187 static void
188 get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
189 const GLint x[], const GLint y[], void *values)
190 {
191 GLubyte *dst = (GLubyte *) values;
192 GLuint i;
193 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
194 for (i = 0; i < count; i++) {
195 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
196 dst[i] = *src;
197 }
198 }
199
200
201 static void
202 put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
203 GLint x, GLint y, const void *values, const GLubyte *mask)
204 {
205 const GLubyte *src = (const GLubyte *) values;
206 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x;
207 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
208 if (mask) {
209 GLuint i;
210 for (i = 0; i < count; i++) {
211 if (mask[i]) {
212 dst[i] = src[i];
213 }
214 }
215 }
216 else {
217 memcpy(dst, values, count * sizeof(GLubyte));
218 }
219 }
220
221
222 static void
223 put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
224 const GLint x[], const GLint y[],
225 const void *values, const GLubyte *mask)
226 {
227 const GLubyte *src = (const GLubyte *) values;
228 GLuint i;
229 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
230 for (i = 0; i < count; i++) {
231 if (!mask || mask[i]) {
232 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i];
233 *dst = src[i];
234 }
235 }
236 }
237
238
239 /**********************************************************************
240 * Functions for buffers of 1 X GLushort values.
241 * Typically depth/Z.
242 */
243
244 static void
245 get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
246 const GLint x[], const GLint y[], void *values)
247 {
248 GLushort *dst = (GLushort *) values;
249 GLuint i;
250 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
251 for (i = 0; i < count; i++) {
252 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
253 dst[i] = *src;
254 }
255 }
256
257
258 static void
259 put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
260 GLint x, GLint y, const void *values, const GLubyte *mask)
261 {
262 const GLushort *src = (const GLushort *) values;
263 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x;
264 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
265 if (mask) {
266 GLuint i;
267 for (i = 0; i < count; i++) {
268 if (mask[i]) {
269 dst[i] = src[i];
270 }
271 }
272 }
273 else {
274 memcpy(dst, src, count * sizeof(GLushort));
275 }
276 }
277
278
279 static void
280 put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
281 const GLint x[], const GLint y[], const void *values,
282 const GLubyte *mask)
283 {
284 const GLushort *src = (const GLushort *) values;
285 GLuint i;
286 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
287 for (i = 0; i < count; i++) {
288 if (!mask || mask[i]) {
289 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i];
290 *dst = src[i];
291 }
292 }
293 }
294
295
296 /**********************************************************************
297 * Functions for buffers of 1 X GLuint values.
298 * Typically depth/Z or color index.
299 */
300
301 static void
302 get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
303 const GLint x[], const GLint y[], void *values)
304 {
305 GLuint *dst = (GLuint *) values;
306 GLuint i;
307 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
308 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
309 for (i = 0; i < count; i++) {
310 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
311 dst[i] = *src;
312 }
313 }
314
315
316 static void
317 put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
318 GLint x, GLint y, const void *values, const GLubyte *mask)
319 {
320 const GLuint *src = (const GLuint *) values;
321 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x;
322 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
323 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
324 if (mask) {
325 GLuint i;
326 for (i = 0; i < count; i++) {
327 if (mask[i]) {
328 dst[i] = src[i];
329 }
330 }
331 }
332 else {
333 memcpy(dst, src, count * sizeof(GLuint));
334 }
335 }
336
337
338 static void
339 put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
340 const GLint x[], const GLint y[], const void *values,
341 const GLubyte *mask)
342 {
343 const GLuint *src = (const GLuint *) values;
344 GLuint i;
345 ASSERT(rb->DataType == GL_UNSIGNED_INT ||
346 rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
347 for (i = 0; i < count; i++) {
348 if (!mask || mask[i]) {
349 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i];
350 *dst = src[i];
351 }
352 }
353 }
354
355
356 /**********************************************************************
357 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
358 * Typically color buffers.
359 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
360 * alpha values and return 255 for outgoing alpha values.
361 */
362
363 static void *
364 get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb,
365 GLint x, GLint y)
366 {
367 ASSERT(rb->Format == MESA_FORMAT_RGB888);
368 /* No direct access since this buffer is RGB but caller will be
369 * treating it as if it were RGBA.
370 */
371 return NULL;
372 }
373
374
375 static void
376 get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
377 GLint x, GLint y, void *values)
378 {
379 const GLubyte *src = ((const GLubyte *) rb->Data) +
380 3 * (y * rb->RowStride + x);
381 GLubyte *dst = (GLubyte *) values;
382 GLuint i;
383 ASSERT(rb->Format == MESA_FORMAT_RGB888);
384 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
385 for (i = 0; i < count; i++) {
386 dst[i * 4 + 0] = src[i * 3 + 0];
387 dst[i * 4 + 1] = src[i * 3 + 1];
388 dst[i * 4 + 2] = src[i * 3 + 2];
389 dst[i * 4 + 3] = 255;
390 }
391 }
392
393
394 static void
395 get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
396 const GLint x[], const GLint y[], void *values)
397 {
398 GLubyte *dst = (GLubyte *) values;
399 GLuint i;
400 ASSERT(rb->Format == MESA_FORMAT_RGB888);
401 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
402 for (i = 0; i < count; i++) {
403 const GLubyte *src
404 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
405 dst[i * 4 + 0] = src[0];
406 dst[i * 4 + 1] = src[1];
407 dst[i * 4 + 2] = src[2];
408 dst[i * 4 + 3] = 255;
409 }
410 }
411
412
413 static void
414 put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
415 GLint x, GLint y, const void *values, const GLubyte *mask)
416 {
417 /* note: incoming values are RGB+A! */
418 const GLubyte *src = (const GLubyte *) values;
419 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
420 GLuint i;
421 ASSERT(rb->Format == MESA_FORMAT_RGB888);
422 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
423 for (i = 0; i < count; i++) {
424 if (!mask || mask[i]) {
425 dst[i * 3 + 0] = src[i * 4 + 0];
426 dst[i * 3 + 1] = src[i * 4 + 1];
427 dst[i * 3 + 2] = src[i * 4 + 2];
428 }
429 }
430 }
431
432
433 static void
434 put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
435 GLint x, GLint y, const void *values, const GLubyte *mask)
436 {
437 /* note: incoming values are RGB+A! */
438 const GLubyte *src = (const GLubyte *) values;
439 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x);
440 GLuint i;
441 ASSERT(rb->Format == MESA_FORMAT_RGB888);
442 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
443 for (i = 0; i < count; i++) {
444 if (!mask || mask[i]) {
445 dst[i * 3 + 0] = src[i * 3 + 0];
446 dst[i * 3 + 1] = src[i * 3 + 1];
447 dst[i * 3 + 2] = src[i * 3 + 2];
448 }
449 }
450 }
451
452
453 static void
454 put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
455 const GLint x[], const GLint y[], const void *values,
456 const GLubyte *mask)
457 {
458 /* note: incoming values are RGB+A! */
459 const GLubyte *src = (const GLubyte *) values;
460 GLuint i;
461 ASSERT(rb->Format == MESA_FORMAT_RGB888);
462 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
463 for (i = 0; i < count; i++) {
464 if (!mask || mask[i]) {
465 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]);
466 dst[0] = src[i * 4 + 0];
467 dst[1] = src[i * 4 + 1];
468 dst[2] = src[i * 4 + 2];
469 }
470 }
471 }
472
473
474 /**********************************************************************
475 * Functions for buffers of 4 X GLubyte (or GLbyte) values.
476 * Typically color buffers.
477 */
478
479 static void
480 get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
481 const GLint x[], const GLint y[], void *values)
482 {
483 /* treat 4*GLubyte as 1*GLuint */
484 GLuint *dst = (GLuint *) values;
485 GLuint i;
486 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
487 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
488 rb->Format == MESA_FORMAT_RGBA8888_REV);
489 for (i = 0; i < count; i++) {
490 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
491 dst[i] = *src;
492 }
493 }
494
495
496 static void
497 put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
498 GLint x, GLint y, const void *values, const GLubyte *mask)
499 {
500 /* treat 4*GLubyte as 1*GLuint */
501 const GLuint *src = (const GLuint *) values;
502 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x);
503 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
504 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
505 rb->Format == MESA_FORMAT_RGBA8888_REV);
506 if (mask) {
507 GLuint i;
508 for (i = 0; i < count; i++) {
509 if (mask[i]) {
510 dst[i] = src[i];
511 }
512 }
513 }
514 else {
515 memcpy(dst, src, 4 * count * sizeof(GLubyte));
516 }
517 }
518
519
520 static void
521 put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
522 GLint x, GLint y, const void *values, const GLubyte *mask)
523 {
524 /* Store RGB values in RGBA buffer */
525 const GLubyte *src = (const GLubyte *) values;
526 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x);
527 GLuint i;
528 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
529 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
530 rb->Format == MESA_FORMAT_RGBA8888_REV);
531 for (i = 0; i < count; i++) {
532 if (!mask || mask[i]) {
533 dst[i * 4 + 0] = src[i * 3 + 0];
534 dst[i * 4 + 1] = src[i * 3 + 1];
535 dst[i * 4 + 2] = src[i * 3 + 2];
536 dst[i * 4 + 3] = 0xff;
537 }
538 }
539 }
540
541
542 static void
543 put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
544 const GLint x[], const GLint y[], const void *values,
545 const GLubyte *mask)
546 {
547 /* treat 4*GLubyte as 1*GLuint */
548 const GLuint *src = (const GLuint *) values;
549 GLuint i;
550 ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
551 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 ||
552 rb->Format == MESA_FORMAT_RGBA8888_REV);
553 for (i = 0; i < count; i++) {
554 if (!mask || mask[i]) {
555 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]);
556 *dst = src[i];
557 }
558 }
559 }
560
561
562 /**********************************************************************
563 * Functions for buffers of 4 X GLushort (or GLshort) values.
564 * Typically accum buffer.
565 */
566
567 static void
568 get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
569 const GLint x[], const GLint y[], void *values)
570 {
571 GLushort *dst = (GLushort *) values;
572 GLuint i;
573 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
574 for (i = 0; i < count; i++) {
575 const GLushort *src
576 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]);
577 dst[i] = *src;
578 }
579 }
580
581
582 static void
583 put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
584 GLint x, GLint y, const void *values, const GLubyte *mask)
585 {
586 const GLushort *src = (const GLushort *) values;
587 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
588 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
589 if (mask) {
590 GLuint i;
591 for (i = 0; i < count; i++) {
592 if (mask[i]) {
593 dst[i * 4 + 0] = src[i * 4 + 0];
594 dst[i * 4 + 1] = src[i * 4 + 1];
595 dst[i * 4 + 2] = src[i * 4 + 2];
596 dst[i * 4 + 3] = src[i * 4 + 3];
597 }
598 }
599 }
600 else {
601 memcpy(dst, src, 4 * count * sizeof(GLushort));
602 }
603 }
604
605
606 static void
607 put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
608 GLint x, GLint y, const void *values, const GLubyte *mask)
609 {
610 /* Put RGB values in RGBA buffer */
611 const GLushort *src = (const GLushort *) values;
612 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x);
613 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
614 if (mask) {
615 GLuint i;
616 for (i = 0; i < count; i++) {
617 if (mask[i]) {
618 dst[i * 4 + 0] = src[i * 3 + 0];
619 dst[i * 4 + 1] = src[i * 3 + 1];
620 dst[i * 4 + 2] = src[i * 3 + 2];
621 dst[i * 4 + 3] = 0xffff;
622 }
623 }
624 }
625 else {
626 memcpy(dst, src, 4 * count * sizeof(GLushort));
627 }
628 }
629
630
631 static void
632 put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
633 const GLint x[], const GLint y[], const void *values,
634 const GLubyte *mask)
635 {
636 const GLushort *src = (const GLushort *) values;
637 GLuint i;
638 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
639 for (i = 0; i < count; i++) {
640 if (!mask || mask[i]) {
641 GLushort *dst =
642 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]);
643 dst[0] = src[i * 4 + 0];
644 dst[1] = src[i * 4 + 1];
645 dst[2] = src[i * 4 + 2];
646 dst[3] = src[i * 4 + 3];
647 }
648 }
649 }
650
651
652 /**********************************************************************
653 * Functions for MESA_FORMAT_R8.
654 */
655 static void
656 get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
657 GLint x, GLint y, void *values)
658 {
659 const GLubyte *src = rb->GetPointer(ctx, rb, x, y);
660 GLuint *dst = values;
661 GLuint i;
662
663 for (i = 0; i < count; i++) {
664 dst[i] = 0xff000000 | src[i];
665 }
666 }
667
668 static void
669 get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
670 const GLint x[], const GLint y[], void *values)
671 {
672 GLuint *dst = (GLuint *) values;
673 GLuint i;
674
675 for (i = 0; i < count; i++) {
676 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]);
677 dst[i] = 0xff000000 | *src;
678 }
679 }
680
681 /**********************************************************************
682 * Functions for MESA_FORMAT_GR88.
683 */
684 static void
685 get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
686 GLint x, GLint y, void *values)
687 {
688 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
689 GLuint *dst = values;
690 GLuint i;
691
692 for (i = 0; i < count; i++) {
693 dst[i] = 0xff000000 | src[i];
694 }
695 }
696
697 static void
698 get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb,
699 GLuint count, const GLint x[], const GLint y[], void *values)
700 {
701 GLuint *dst = (GLuint *) values;
702 GLuint i;
703
704 for (i = 0; i < count; i++) {
705 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
706 dst[i] = 0xff000000 | *src;
707 }
708 }
709
710 /**********************************************************************
711 * Functions for MESA_FORMAT_R16.
712 */
713 static void
714 get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
715 GLint x, GLint y, void *values)
716 {
717 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
718 GLushort *dst = values;
719 GLuint i;
720
721 for (i = 0; i < count; i++) {
722 dst[i * 4 + RCOMP] = src[i];
723 dst[i * 4 + GCOMP] = 0;
724 dst[i * 4 + BCOMP] = 0;
725 dst[i * 4 + ACOMP] = 0xffff;
726 }
727 }
728
729 static void
730 get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
731 const GLint x[], const GLint y[], void *values)
732 {
733 GLushort *dst = values;
734 GLuint i;
735
736 for (i = 0; i < count; i++) {
737 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
738 dst[i * 4 + RCOMP] = *src;
739 dst[i * 4 + GCOMP] = 0;
740 dst[i * 4 + BCOMP] = 0;
741 dst[i * 4 + ACOMP] = 0xffff;
742 }
743 }
744
745 /**********************************************************************
746 * Functions for MESA_FORMAT_RG1616.
747 */
748 static void
749 get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
750 GLint x, GLint y, void *values)
751 {
752 const GLushort *src = rb->GetPointer(ctx, rb, x, y);
753 GLushort *dst = values;
754 GLuint i;
755
756 for (i = 0; i < count; i++) {
757 dst[i * 4 + RCOMP] = src[i * 2];
758 dst[i * 4 + GCOMP] = src[i * 2 + 1];
759 dst[i * 4 + BCOMP] = 0;
760 dst[i * 4 + ACOMP] = 0xffff;
761 }
762 }
763
764 static void
765 get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb,
766 GLuint count, const GLint x[], const GLint y[], void *values)
767 {
768 GLushort *dst = values;
769 GLuint i;
770
771 for (i = 0; i < count; i++) {
772 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]);
773 dst[i * 4 + RCOMP] = src[0];
774 dst[i * 4 + GCOMP] = src[1];
775 dst[i * 4 + BCOMP] = 0;
776 dst[i * 4 + ACOMP] = 0xffff;
777 }
778 }
779
780 /**********************************************************************
781 * Functions for MESA_FORMAT_INTENSITY_FLOAT32.
782 */
783 static void
784 get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
785 GLuint count, GLint x, GLint y, void *values)
786 {
787 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
788 GLfloat *dst = values;
789 GLuint i;
790
791 for (i = 0; i < count; i++) {
792 dst[i * 4 + RCOMP] =
793 dst[i * 4 + GCOMP] =
794 dst[i * 4 + BCOMP] =
795 dst[i * 4 + ACOMP] = src[i];
796 }
797 }
798
799 static void
800 get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
801 GLuint count, const GLint x[], const GLint y[],
802 void *values)
803 {
804 GLfloat *dst = values;
805 GLuint i;
806
807 for (i = 0; i < count; i++) {
808 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
809 dst[i * 4 + RCOMP] =
810 dst[i * 4 + GCOMP] =
811 dst[i * 4 + BCOMP] =
812 dst[i * 4 + ACOMP] = src[0];
813 }
814 }
815
816 /**********************************************************************
817 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32.
818 */
819 static void
820 get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
821 GLuint count, GLint x, GLint y, void *values)
822 {
823 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
824 GLfloat *dst = values;
825 GLuint i;
826
827 for (i = 0; i < count; i++) {
828 dst[i * 4 + RCOMP] =
829 dst[i * 4 + GCOMP] =
830 dst[i * 4 + BCOMP] = src[i];
831 dst[i * 4 + ACOMP] = 1.0;
832 }
833 }
834
835 static void
836 get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
837 GLuint count, const GLint x[], const GLint y[],
838 void *values)
839 {
840 GLfloat *dst = values;
841 GLuint i;
842
843 for (i = 0; i < count; i++) {
844 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
845 dst[i * 4 + RCOMP] =
846 dst[i * 4 + GCOMP] =
847 dst[i * 4 + BCOMP] = src[0];
848 dst[i * 4 + ACOMP] = 1.0;
849 }
850 }
851
852 /**********************************************************************
853 * Functions for MESA_FORMAT_ALPHA_FLOAT32.
854 */
855 static void
856 get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
857 GLuint count, GLint x, GLint y, void *values)
858 {
859 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
860 GLfloat *dst = values;
861 GLuint i;
862
863 for (i = 0; i < count; i++) {
864 dst[i * 4 + RCOMP] = 0.0;
865 dst[i * 4 + GCOMP] = 0.0;
866 dst[i * 4 + BCOMP] = 0.0;
867 dst[i * 4 + ACOMP] = src[i];
868 }
869 }
870
871 static void
872 get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
873 GLuint count, const GLint x[], const GLint y[],
874 void *values)
875 {
876 GLfloat *dst = values;
877 GLuint i;
878
879 for (i = 0; i < count; i++) {
880 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
881 dst[i * 4 + RCOMP] = 0.0;
882 dst[i * 4 + GCOMP] = 0.0;
883 dst[i * 4 + BCOMP] = 0.0;
884 dst[i * 4 + ACOMP] = src[0];
885 }
886 }
887
888 static void
889 put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
890 GLuint count, GLint x, GLint y,
891 const void *values, const GLubyte *mask)
892 {
893 float *dst = rb->GetPointer(ctx, rb, x, y);
894 const float *src = values;
895 unsigned int i;
896
897 if (mask) {
898 for (i = 0; i < count; i++) {
899 if (mask[i]) {
900 dst[i] = src[i * 4 + ACOMP];
901 }
902 }
903 }
904 else {
905 for (i = 0; i < count; i++) {
906 dst[i] = src[i * 4 + ACOMP];
907 }
908 }
909 }
910
911 static void
912 put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
913 GLuint count, const GLint x[], const GLint y[],
914 const void *values, const GLubyte *mask)
915 {
916 const float *src = values;
917 unsigned int i;
918
919 for (i = 0; i < count; i++) {
920 if (!mask || mask[i]) {
921 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]);
922
923 *dst = src[i * 4 + ACOMP];
924 }
925 }
926 }
927
928 /**********************************************************************
929 * Functions for MESA_FORMAT_R_FLOAT32.
930 */
931 static void
932 get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
933 GLuint count, GLint x, GLint y, void *values)
934 {
935 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
936 GLfloat *dst = values;
937 GLuint i;
938
939 for (i = 0; i < count; i++) {
940 dst[i * 4 + RCOMP] = src[i];
941 dst[i * 4 + GCOMP] = 0.0;
942 dst[i * 4 + BCOMP] = 0.0;
943 dst[i * 4 + ACOMP] = 1.0;
944 }
945 }
946
947 static void
948 get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
949 GLuint count, const GLint x[], const GLint y[],
950 void *values)
951 {
952 GLfloat *dst = values;
953 GLuint i;
954
955 for (i = 0; i < count; i++) {
956 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
957 dst[i * 4 + RCOMP] = src[0];
958 dst[i * 4 + GCOMP] = 0.0;
959 dst[i * 4 + BCOMP] = 0.0;
960 dst[i * 4 + ACOMP] = 1.0;
961 }
962 }
963
964 /**********************************************************************
965 * Functions for MESA_FORMAT_RG_FLOAT32.
966 */
967 static void
968 get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
969 GLuint count, GLint x, GLint y, void *values)
970 {
971 const GLfloat *src = rb->GetPointer(ctx, rb, x, y);
972 GLfloat *dst = values;
973 GLuint i;
974
975 for (i = 0; i < count; i++) {
976 dst[i * 4 + RCOMP] = src[i * 2 + 0];
977 dst[i * 4 + GCOMP] = src[i * 2 + 1];
978 dst[i * 4 + BCOMP] = 0.0;
979 dst[i * 4 + ACOMP] = 1.0;
980 }
981 }
982
983 static void
984 get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb,
985 GLuint count, const GLint x[], const GLint y[],
986 void *values)
987 {
988 GLfloat *dst = values;
989 GLuint i;
990
991 for (i = 0; i < count; i++) {
992 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]);
993 dst[i * 4 + RCOMP] = src[0];
994 dst[i * 4 + GCOMP] = src[1];
995 dst[i * 4 + BCOMP] = 0.0;
996 dst[i * 4 + ACOMP] = 1.0;
997 }
998 }
999
1000 /**
1001 * This is the default software fallback for gl_renderbuffer's span
1002 * access functions.
1003 *
1004 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels
1005 * are packed in the type of rb->Format, and that subsequent rows appear
1006 * rb->RowStride pixels later.
1007 */
1008 void
1009 _swrast_set_renderbuffer_accessors(struct gl_renderbuffer *rb)
1010 {
1011 rb->GetPointer = get_pointer_generic;
1012 rb->GetRow = get_row_generic;
1013
1014 switch (rb->Format) {
1015 case MESA_FORMAT_RGB888:
1016 rb->DataType = GL_UNSIGNED_BYTE;
1017 rb->GetPointer = get_pointer_ubyte3;
1018 rb->GetRow = get_row_ubyte3;
1019 rb->GetValues = get_values_ubyte3;
1020 rb->PutRow = put_row_ubyte3;
1021 rb->PutRowRGB = put_row_rgb_ubyte3;
1022 rb->PutValues = put_values_ubyte3;
1023 break;
1024
1025 case MESA_FORMAT_RGBA8888:
1026 case MESA_FORMAT_RGBA8888_REV:
1027 rb->DataType = GL_UNSIGNED_BYTE;
1028 rb->GetValues = get_values_ubyte4;
1029 rb->PutRow = put_row_ubyte4;
1030 rb->PutRowRGB = put_row_rgb_ubyte4;
1031 rb->PutValues = put_values_ubyte4;
1032 break;
1033
1034 case MESA_FORMAT_R8:
1035 rb->DataType = GL_UNSIGNED_BYTE;
1036 rb->GetValues = get_values_r8;
1037 rb->GetRow = get_row_r8;
1038 rb->PutRow = put_row_generic;
1039 rb->PutRowRGB = put_row_generic;
1040 rb->PutValues = put_values_generic;
1041 break;
1042
1043 case MESA_FORMAT_GR88:
1044 rb->DataType = GL_UNSIGNED_BYTE;
1045 rb->GetValues = get_values_rg88;
1046 rb->GetRow = get_row_rg88;
1047 rb->PutRow = put_row_generic;
1048 rb->PutRowRGB = put_row_generic;
1049 rb->PutValues = put_values_generic;
1050 break;
1051
1052 case MESA_FORMAT_R16:
1053 rb->DataType = GL_UNSIGNED_SHORT;
1054 rb->GetValues = get_values_r16;
1055 rb->GetRow = get_row_r16;
1056 rb->PutRow = put_row_generic;
1057 rb->PutRowRGB = put_row_generic;
1058 rb->PutValues = put_values_generic;
1059 break;
1060
1061 case MESA_FORMAT_RG1616:
1062 rb->DataType = GL_UNSIGNED_SHORT;
1063 rb->GetValues = get_values_rg1616;
1064 rb->GetRow = get_row_rg1616;
1065 rb->PutRow = put_row_generic;
1066 rb->PutRowRGB = put_row_generic;
1067 rb->PutValues = put_values_generic;
1068 break;
1069
1070 case MESA_FORMAT_SIGNED_RGBA_16:
1071 rb->DataType = GL_SHORT;
1072 rb->GetValues = get_values_ushort4;
1073 rb->PutRow = put_row_ushort4;
1074 rb->PutRowRGB = put_row_rgb_ushort4;
1075 rb->PutValues = put_values_ushort4;
1076 break;
1077
1078 case MESA_FORMAT_S8:
1079 rb->DataType = GL_UNSIGNED_BYTE;
1080 rb->GetValues = get_values_ubyte;
1081 rb->PutRow = put_row_ubyte;
1082 rb->PutRowRGB = NULL;
1083 rb->PutValues = put_values_ubyte;
1084 break;
1085
1086 case MESA_FORMAT_Z16:
1087 rb->DataType = GL_UNSIGNED_SHORT;
1088 rb->GetValues = get_values_ushort;
1089 rb->PutRow = put_row_ushort;
1090 rb->PutRowRGB = NULL;
1091 rb->PutValues = put_values_ushort;
1092 break;
1093
1094 case MESA_FORMAT_Z32:
1095 case MESA_FORMAT_X8_Z24:
1096 case MESA_FORMAT_Z24_X8:
1097 rb->DataType = GL_UNSIGNED_INT;
1098 rb->GetValues = get_values_uint;
1099 rb->PutRow = put_row_uint;
1100 rb->PutRowRGB = NULL;
1101 rb->PutValues = put_values_uint;
1102 break;
1103
1104 case MESA_FORMAT_Z24_S8:
1105 case MESA_FORMAT_S8_Z24:
1106 rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
1107 rb->GetValues = get_values_uint;
1108 rb->PutRow = put_row_uint;
1109 rb->PutRowRGB = NULL;
1110 rb->PutValues = put_values_uint;
1111 break;
1112
1113 case MESA_FORMAT_RGBA_FLOAT32:
1114 rb->GetRow = get_row_generic;
1115 rb->GetValues = get_values_generic;
1116 rb->PutRow = put_row_generic;
1117 rb->PutRowRGB = NULL;
1118 rb->PutValues = put_values_generic;
1119 break;
1120
1121 case MESA_FORMAT_INTENSITY_FLOAT32:
1122 rb->GetRow = get_row_i_float32;
1123 rb->GetValues = get_values_i_float32;
1124 rb->PutRow = put_row_generic;
1125 rb->PutRowRGB = NULL;
1126 rb->PutValues = put_values_generic;
1127 break;
1128
1129 case MESA_FORMAT_LUMINANCE_FLOAT32:
1130 rb->GetRow = get_row_l_float32;
1131 rb->GetValues = get_values_l_float32;
1132 rb->PutRow = put_row_generic;
1133 rb->PutRowRGB = NULL;
1134 rb->PutValues = put_values_generic;
1135 break;
1136
1137 case MESA_FORMAT_ALPHA_FLOAT32:
1138 rb->GetRow = get_row_a_float32;
1139 rb->GetValues = get_values_a_float32;
1140 rb->PutRow = put_row_a_float32;
1141 rb->PutRowRGB = NULL;
1142 rb->PutValues = put_values_a_float32;
1143 break;
1144
1145 case MESA_FORMAT_RG_FLOAT32:
1146 rb->GetRow = get_row_rg_float32;
1147 rb->GetValues = get_values_rg_float32;
1148 rb->PutRow = put_row_generic;
1149 rb->PutRowRGB = NULL;
1150 rb->PutValues = put_values_generic;
1151 break;
1152
1153 case MESA_FORMAT_R_FLOAT32:
1154 rb->GetRow = get_row_r_float32;
1155 rb->GetValues = get_values_r_float32;
1156 rb->PutRow = put_row_generic;
1157 rb->PutRowRGB = NULL;
1158 rb->PutValues = put_values_generic;
1159 break;
1160
1161 default:
1162 break;
1163 }
1164 }
1165
1166 /**
1167 * This is a software fallback for the gl_renderbuffer->AllocStorage
1168 * function.
1169 * Device drivers will typically override this function for the buffers
1170 * which it manages (typically color buffers, Z and stencil).
1171 * Other buffers (like software accumulation and aux buffers) which the driver
1172 * doesn't manage can be handled with this function.
1173 *
1174 * This one multi-purpose function can allocate stencil, depth, accum, color
1175 * or color-index buffers!
1176 *
1177 * This function also plugs in the appropriate GetPointer, Get/PutRow and
1178 * Get/PutValues functions.
1179 */
1180 static GLboolean
1181 soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
1182 GLenum internalFormat,
1183 GLuint width, GLuint height)
1184 {
1185 switch (internalFormat) {
1186 case GL_RGB:
1187 case GL_R3_G3_B2:
1188 case GL_RGB4:
1189 case GL_RGB5:
1190 case GL_RGB8:
1191 case GL_RGB10:
1192 case GL_RGB12:
1193 case GL_RGB16:
1194 rb->Format = MESA_FORMAT_RGB888;
1195 break;
1196 case GL_RGBA:
1197 case GL_RGBA2:
1198 case GL_RGBA4:
1199 case GL_RGB5_A1:
1200 case GL_RGBA8:
1201 #if 1
1202 case GL_RGB10_A2:
1203 case GL_RGBA12:
1204 #endif
1205 if (_mesa_little_endian())
1206 rb->Format = MESA_FORMAT_RGBA8888_REV;
1207 else
1208 rb->Format = MESA_FORMAT_RGBA8888;
1209 break;
1210 case GL_RGBA16:
1211 case GL_RGBA16_SNORM:
1212 /* for accum buffer */
1213 rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
1214 break;
1215 case GL_STENCIL_INDEX:
1216 case GL_STENCIL_INDEX1_EXT:
1217 case GL_STENCIL_INDEX4_EXT:
1218 case GL_STENCIL_INDEX8_EXT:
1219 case GL_STENCIL_INDEX16_EXT:
1220 rb->Format = MESA_FORMAT_S8;
1221 break;
1222 case GL_DEPTH_COMPONENT:
1223 case GL_DEPTH_COMPONENT16:
1224 rb->Format = MESA_FORMAT_Z16;
1225 break;
1226 case GL_DEPTH_COMPONENT24:
1227 rb->Format = MESA_FORMAT_X8_Z24;
1228 break;
1229 case GL_DEPTH_COMPONENT32:
1230 rb->Format = MESA_FORMAT_Z32;
1231 break;
1232 case GL_DEPTH_STENCIL_EXT:
1233 case GL_DEPTH24_STENCIL8_EXT:
1234 rb->Format = MESA_FORMAT_Z24_S8;
1235 break;
1236 default:
1237 /* unsupported format */
1238 return GL_FALSE;
1239 }
1240
1241 _swrast_set_renderbuffer_accessors(rb);
1242
1243 ASSERT(rb->DataType);
1244 ASSERT(rb->GetPointer);
1245 ASSERT(rb->GetRow);
1246 ASSERT(rb->GetValues);
1247 ASSERT(rb->PutRow);
1248 ASSERT(rb->PutValues);
1249
1250 /* free old buffer storage */
1251 if (rb->Data) {
1252 free(rb->Data);
1253 rb->Data = NULL;
1254 }
1255
1256 rb->RowStride = width;
1257
1258 if (width > 0 && height > 0) {
1259 /* allocate new buffer storage */
1260 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format));
1261
1262 if (rb->Data == NULL) {
1263 rb->Width = 0;
1264 rb->Height = 0;
1265 rb->RowStride = 0;
1266 _mesa_error(ctx, GL_OUT_OF_MEMORY,
1267 "software renderbuffer allocation (%d x %d x %d)",
1268 width, height, _mesa_get_format_bytes(rb->Format));
1269 return GL_FALSE;
1270 }
1271 }
1272
1273 rb->Width = width;
1274 rb->Height = height;
1275 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
1276
1277 if (rb->Name == 0 &&
1278 internalFormat == GL_RGBA16_SNORM &&
1279 rb->_BaseFormat == 0) {
1280 /* NOTE: This is a special case just for accumulation buffers.
1281 * This is a very limited use case- there's no snorm texturing or
1282 * rendering going on.
1283 */
1284 rb->_BaseFormat = GL_RGBA;
1285 }
1286 else {
1287 /* the internalFormat should have been error checked long ago */
1288 ASSERT(rb->_BaseFormat);
1289 }
1290
1291 return GL_TRUE;
1292 }
1293
1294
1295 void
1296 _swrast_map_soft_renderbuffer(struct gl_context *ctx,
1297 struct gl_renderbuffer *rb,
1298 GLuint x, GLuint y, GLuint w, GLuint h,
1299 GLbitfield mode,
1300 GLubyte **out_map,
1301 GLint *out_stride)
1302 {
1303 GLubyte *map = rb->Data;
1304 int cpp = _mesa_get_format_bytes(rb->Format);
1305 int stride = rb->RowStride * cpp;
1306
1307 ASSERT(rb->Data);
1308
1309 map += y * stride;
1310 map += x * cpp;
1311
1312 *out_map = map;
1313 *out_stride = stride;
1314 }
1315
1316
1317 void
1318 _swrast_unmap_soft_renderbuffer(struct gl_context *ctx,
1319 struct gl_renderbuffer *rb)
1320 {
1321 }
1322
1323
1324
1325 /**
1326 * Allocate a software-based renderbuffer. This is called via the
1327 * ctx->Driver.NewRenderbuffer() function when the user creates a new
1328 * renderbuffer.
1329 * This would not be used for hardware-based renderbuffers.
1330 */
1331 struct gl_renderbuffer *
1332 _swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
1333 {
1334 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
1335 if (rb) {
1336 rb->AllocStorage = soft_renderbuffer_storage;
1337 /* Normally, one would setup the PutRow, GetRow, etc functions here.
1338 * But we're doing that in the soft_renderbuffer_storage() function
1339 * instead.
1340 */
1341 }
1342 return rb;
1343 }
1344
1345
1346 /**
1347 * Add software-based color renderbuffers to the given framebuffer.
1348 * This is a helper routine for device drivers when creating a
1349 * window system framebuffer (not a user-created render/framebuffer).
1350 * Once this function is called, you can basically forget about this
1351 * renderbuffer; core Mesa will handle all the buffer management and
1352 * rendering!
1353 */
1354 static GLboolean
1355 add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
1356 GLuint rgbBits, GLuint alphaBits,
1357 GLboolean frontLeft, GLboolean backLeft,
1358 GLboolean frontRight, GLboolean backRight)
1359 {
1360 gl_buffer_index b;
1361
1362 if (rgbBits > 16 || alphaBits > 16) {
1363 _mesa_problem(ctx,
1364 "Unsupported bit depth in add_color_renderbuffers");
1365 return GL_FALSE;
1366 }
1367
1368 assert(MAX_COLOR_ATTACHMENTS >= 4);
1369
1370 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
1371 struct gl_renderbuffer *rb;
1372
1373 if (b == BUFFER_FRONT_LEFT && !frontLeft)
1374 continue;
1375 else if (b == BUFFER_BACK_LEFT && !backLeft)
1376 continue;
1377 else if (b == BUFFER_FRONT_RIGHT && !frontRight)
1378 continue;
1379 else if (b == BUFFER_BACK_RIGHT && !backRight)
1380 continue;
1381
1382 assert(fb->Attachment[b].Renderbuffer == NULL);
1383
1384 rb = _mesa_new_renderbuffer(ctx, 0);
1385 if (!rb) {
1386 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
1387 return GL_FALSE;
1388 }
1389
1390 rb->InternalFormat = GL_RGBA;
1391
1392 rb->AllocStorage = soft_renderbuffer_storage;
1393 _mesa_add_renderbuffer(fb, b, rb);
1394 }
1395
1396 return GL_TRUE;
1397 }
1398
1399
1400 /**
1401 * Add a software-based depth renderbuffer to the given framebuffer.
1402 * This is a helper routine for device drivers when creating a
1403 * window system framebuffer (not a user-created render/framebuffer).
1404 * Once this function is called, you can basically forget about this
1405 * renderbuffer; core Mesa will handle all the buffer management and
1406 * rendering!
1407 */
1408 static GLboolean
1409 add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1410 GLuint depthBits)
1411 {
1412 struct gl_renderbuffer *rb;
1413
1414 if (depthBits > 32) {
1415 _mesa_problem(ctx,
1416 "Unsupported depthBits in add_depth_renderbuffer");
1417 return GL_FALSE;
1418 }
1419
1420 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1421
1422 rb = _mesa_new_renderbuffer(ctx, 0);
1423 if (!rb) {
1424 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
1425 return GL_FALSE;
1426 }
1427
1428 if (depthBits <= 16) {
1429 rb->InternalFormat = GL_DEPTH_COMPONENT16;
1430 }
1431 else if (depthBits <= 24) {
1432 rb->InternalFormat = GL_DEPTH_COMPONENT24;
1433 }
1434 else {
1435 rb->InternalFormat = GL_DEPTH_COMPONENT32;
1436 }
1437
1438 rb->AllocStorage = soft_renderbuffer_storage;
1439 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1440
1441 return GL_TRUE;
1442 }
1443
1444
1445 /**
1446 * Add a software-based stencil renderbuffer to the given framebuffer.
1447 * This is a helper routine for device drivers when creating a
1448 * window system framebuffer (not a user-created render/framebuffer).
1449 * Once this function is called, you can basically forget about this
1450 * renderbuffer; core Mesa will handle all the buffer management and
1451 * rendering!
1452 */
1453 static GLboolean
1454 add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1455 GLuint stencilBits)
1456 {
1457 struct gl_renderbuffer *rb;
1458
1459 if (stencilBits > 16) {
1460 _mesa_problem(ctx,
1461 "Unsupported stencilBits in add_stencil_renderbuffer");
1462 return GL_FALSE;
1463 }
1464
1465 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1466
1467 rb = _mesa_new_renderbuffer(ctx, 0);
1468 if (!rb) {
1469 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
1470 return GL_FALSE;
1471 }
1472
1473 assert(stencilBits <= 8);
1474 rb->InternalFormat = GL_STENCIL_INDEX8;
1475
1476 rb->AllocStorage = soft_renderbuffer_storage;
1477 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1478
1479 return GL_TRUE;
1480 }
1481
1482
1483 static GLboolean
1484 add_depth_stencil_renderbuffer(struct gl_context *ctx,
1485 struct gl_framebuffer *fb)
1486 {
1487 struct gl_renderbuffer *rb;
1488
1489 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
1490 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
1491
1492 rb = _mesa_new_renderbuffer(ctx, 0);
1493 if (!rb) {
1494 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer");
1495 return GL_FALSE;
1496 }
1497
1498 rb->InternalFormat = GL_DEPTH_STENCIL;
1499
1500 rb->AllocStorage = soft_renderbuffer_storage;
1501 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
1502 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
1503
1504 return GL_TRUE;
1505 }
1506
1507
1508 /**
1509 * Add a software-based accumulation renderbuffer to the given framebuffer.
1510 * This is a helper routine for device drivers when creating a
1511 * window system framebuffer (not a user-created render/framebuffer).
1512 * Once this function is called, you can basically forget about this
1513 * renderbuffer; core Mesa will handle all the buffer management and
1514 * rendering!
1515 */
1516 static GLboolean
1517 add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1518 GLuint redBits, GLuint greenBits,
1519 GLuint blueBits, GLuint alphaBits)
1520 {
1521 struct gl_renderbuffer *rb;
1522
1523 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
1524 _mesa_problem(ctx,
1525 "Unsupported accumBits in add_accum_renderbuffer");
1526 return GL_FALSE;
1527 }
1528
1529 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
1530
1531 rb = _mesa_new_renderbuffer(ctx, 0);
1532 if (!rb) {
1533 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
1534 return GL_FALSE;
1535 }
1536
1537 rb->InternalFormat = GL_RGBA16_SNORM;
1538 rb->AllocStorage = soft_renderbuffer_storage;
1539 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
1540
1541 return GL_TRUE;
1542 }
1543
1544
1545
1546 /**
1547 * Add a software-based aux renderbuffer to the given framebuffer.
1548 * This is a helper routine for device drivers when creating a
1549 * window system framebuffer (not a user-created render/framebuffer).
1550 * Once this function is called, you can basically forget about this
1551 * renderbuffer; core Mesa will handle all the buffer management and
1552 * rendering!
1553 *
1554 * NOTE: color-index aux buffers not supported.
1555 */
1556 static GLboolean
1557 add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
1558 GLuint colorBits, GLuint numBuffers)
1559 {
1560 GLuint i;
1561
1562 if (colorBits > 16) {
1563 _mesa_problem(ctx,
1564 "Unsupported colorBits in add_aux_renderbuffers");
1565 return GL_FALSE;
1566 }
1567
1568 assert(numBuffers <= MAX_AUX_BUFFERS);
1569
1570 for (i = 0; i < numBuffers; i++) {
1571 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
1572
1573 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
1574
1575 if (!rb) {
1576 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
1577 return GL_FALSE;
1578 }
1579
1580 assert (colorBits <= 8);
1581 rb->InternalFormat = GL_RGBA;
1582
1583 rb->AllocStorage = soft_renderbuffer_storage;
1584 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
1585 }
1586 return GL_TRUE;
1587 }
1588
1589
1590 /**
1591 * Create/attach software-based renderbuffers to the given framebuffer.
1592 * This is a helper routine for device drivers. Drivers can just as well
1593 * call the individual _mesa_add_*_renderbuffer() routines directly.
1594 */
1595 void
1596 _swrast_add_soft_renderbuffers(struct gl_framebuffer *fb,
1597 GLboolean color,
1598 GLboolean depth,
1599 GLboolean stencil,
1600 GLboolean accum,
1601 GLboolean alpha,
1602 GLboolean aux)
1603 {
1604 GLboolean frontLeft = GL_TRUE;
1605 GLboolean backLeft = fb->Visual.doubleBufferMode;
1606 GLboolean frontRight = fb->Visual.stereoMode;
1607 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
1608
1609 if (color) {
1610 assert(fb->Visual.redBits == fb->Visual.greenBits);
1611 assert(fb->Visual.redBits == fb->Visual.blueBits);
1612 add_color_renderbuffers(NULL, fb,
1613 fb->Visual.redBits,
1614 fb->Visual.alphaBits,
1615 frontLeft, backLeft,
1616 frontRight, backRight);
1617 }
1618
1619 #if 0
1620 /* This is pretty much for debugging purposes only since there's a perf
1621 * hit for using combined depth/stencil in swrast.
1622 */
1623 if (depth && fb->Visual.depthBits == 24 &&
1624 stencil && fb->Visual.stencilBits == 8) {
1625 /* use combined depth/stencil buffer */
1626 add_depth_stencil_renderbuffer(NULL, fb);
1627 }
1628 else
1629 #else
1630 (void) add_depth_stencil_renderbuffer;
1631 #endif
1632 {
1633 if (depth) {
1634 assert(fb->Visual.depthBits > 0);
1635 add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
1636 }
1637
1638 if (stencil) {
1639 assert(fb->Visual.stencilBits > 0);
1640 add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
1641 }
1642 }
1643
1644 if (accum) {
1645 assert(fb->Visual.accumRedBits > 0);
1646 assert(fb->Visual.accumGreenBits > 0);
1647 assert(fb->Visual.accumBlueBits > 0);
1648 add_accum_renderbuffer(NULL, fb,
1649 fb->Visual.accumRedBits,
1650 fb->Visual.accumGreenBits,
1651 fb->Visual.accumBlueBits,
1652 fb->Visual.accumAlphaBits);
1653 }
1654
1655 if (aux) {
1656 assert(fb->Visual.numAuxBuffers > 0);
1657 add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
1658 fb->Visual.numAuxBuffers);
1659 }
1660
1661 #if 0
1662 if (multisample) {
1663 /* maybe someday */
1664 }
1665 #endif
1666 }