643952875841bbfa6c3d53b3379c1d4a0f143523
[mesa.git] / src / mesa / swrast / s_texrender.c
1
2 #include "main/context.h"
3 #include "main/colormac.h"
4 #include "main/fbobject.h"
5 #include "main/macros.h"
6 #include "main/teximage.h"
7 #include "main/renderbuffer.h"
8 #include "swrast/swrast.h"
9 #include "swrast/s_context.h"
10 #include "swrast/s_texfetch.h"
11
12
13 /*
14 * Render-to-texture code for GL_EXT_framebuffer_object
15 */
16
17
18 /**
19 * Derived from gl_renderbuffer class
20 */
21 struct texture_renderbuffer
22 {
23 struct gl_renderbuffer Base; /**< Base class object */
24 struct swrast_texture_image *TexImage;
25 StoreTexelFunc Store;
26 FetchTexelFuncF Fetchf;
27 GLint Yoffset; /**< Layer for 1D array textures. */
28 GLint Zoffset; /**< Layer for 2D array textures, or slice
29 * for 3D textures
30 */
31 };
32
33
34 /**
35 * Get row of values from the renderbuffer that wraps a texture image.
36 */
37 static void
38 texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
39 GLint x, GLint y, void *values)
40 {
41 const struct texture_renderbuffer *trb
42 = (const struct texture_renderbuffer *) rb;
43 const GLint z = trb->Zoffset;
44 GLuint i;
45
46 ASSERT(trb->TexImage->Base.Width == rb->Width);
47 ASSERT(trb->TexImage->Base.Height == rb->Height);
48
49 y += trb->Yoffset;
50
51 if (rb->DataType == CHAN_TYPE) {
52 GLchan *rgbaOut = (GLchan *) values;
53 for (i = 0; i < count; i++) {
54 GLfloat rgba[4];
55 trb->Fetchf(trb->TexImage, x + i, y, z, rgba);
56 UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
57 }
58 }
59 else if (rb->DataType == GL_UNSIGNED_SHORT) {
60 GLushort *zValues = (GLushort *) values;
61 for (i = 0; i < count; i++) {
62 GLfloat flt;
63 trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
64 zValues[i] = (GLushort) (flt * 0xffff);
65 }
66 }
67 else if (rb->DataType == GL_UNSIGNED_INT) {
68 GLuint *zValues = (GLuint *) values;
69 /*
70 const GLdouble scale = (GLdouble) 0xffffffff;
71 */
72 for (i = 0; i < count; i++) {
73 GLfloat flt;
74 trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
75 #if 0
76 /* this should work, but doesn't (overflow due to low precision) */
77 zValues[i] = (GLuint) (flt * scale);
78 #else
79 /* temporary hack */
80 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
81 #endif
82 }
83 }
84 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
85 GLuint *zValues = (GLuint *) values;
86 for (i = 0; i < count; i++) {
87 GLfloat flt;
88 trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
89 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
90 }
91 }
92 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
93 GLuint *zValues = (GLuint *) values;
94 for (i = 0; i < count; i++) {
95 GLfloat flt;
96 trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
97 zValues[i] = (GLuint) (flt * 0xffffff);
98 }
99 }
100 else {
101 _mesa_problem(ctx, "invalid rb->DataType in texture_get_row");
102 }
103 }
104
105
106 static void
107 texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
108 const GLint x[], const GLint y[], void *values)
109 {
110 const struct texture_renderbuffer *trb
111 = (const struct texture_renderbuffer *) rb;
112 const GLint z = trb->Zoffset;
113 GLuint i;
114
115 if (rb->DataType == CHAN_TYPE) {
116 GLchan *rgbaOut = (GLchan *) values;
117 for (i = 0; i < count; i++) {
118 GLfloat rgba[4];
119 trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
120 z, rgba);
121 UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
122 }
123 }
124 else if (rb->DataType == GL_UNSIGNED_SHORT) {
125 GLushort *zValues = (GLushort *) values;
126 for (i = 0; i < count; i++) {
127 GLfloat flt;
128 trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
129 z, &flt);
130 zValues[i] = (GLushort) (flt * 0xffff);
131 }
132 }
133 else if (rb->DataType == GL_UNSIGNED_INT) {
134 GLuint *zValues = (GLuint *) values;
135 for (i = 0; i < count; i++) {
136 GLfloat flt;
137 trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
138 z, &flt);
139 #if 0
140 zValues[i] = (GLuint) (flt * 0xffffffff);
141 #else
142 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
143 #endif
144 }
145 }
146 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
147 GLuint *zValues = (GLuint *) values;
148 for (i = 0; i < count; i++) {
149 GLfloat flt;
150 trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
151 z, &flt);
152 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
153 }
154 }
155 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
156 GLuint *zValues = (GLuint *) values;
157 for (i = 0; i < count; i++) {
158 GLfloat flt;
159 trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
160 z, &flt);
161 zValues[i] = (GLuint) (flt * 0xffffff);
162 }
163 }
164 else {
165 _mesa_problem(ctx, "invalid rb->DataType in texture_get_values");
166 }
167 }
168
169
170 /**
171 * Put row of values into a renderbuffer that wraps a texture image.
172 */
173 static void
174 texture_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
175 GLint x, GLint y, const void *values, const GLubyte *mask)
176 {
177 const struct texture_renderbuffer *trb
178 = (const struct texture_renderbuffer *) rb;
179 const GLint z = trb->Zoffset;
180 GLuint i;
181
182 y += trb->Yoffset;
183
184 if (rb->DataType == CHAN_TYPE) {
185 const GLchan *rgba = (const GLchan *) values;
186 for (i = 0; i < count; i++) {
187 if (!mask || mask[i]) {
188 trb->Store(trb->TexImage, x + i, y, z, rgba);
189 }
190 rgba += 4;
191 }
192 }
193 else if (rb->DataType == GL_UNSIGNED_SHORT) {
194 const GLushort *zValues = (const GLushort *) values;
195 for (i = 0; i < count; i++) {
196 if (!mask || mask[i]) {
197 trb->Store(trb->TexImage, x + i, y, z, zValues + i);
198 }
199 }
200 }
201 else if (rb->DataType == GL_UNSIGNED_INT) {
202 const GLuint *zValues = (const GLuint *) values;
203 for (i = 0; i < count; i++) {
204 if (!mask || mask[i]) {
205 trb->Store(trb->TexImage, x + i, y, z, zValues + i);
206 }
207 }
208 }
209 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
210 const GLuint *zValues = (const GLuint *) values;
211 for (i = 0; i < count; i++) {
212 if (!mask || mask[i]) {
213 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
214 trb->Store(trb->TexImage, x + i, y, z, &flt);
215 }
216 }
217 }
218 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
219 const GLuint *zValues = (const GLuint *) values;
220 for (i = 0; i < count; i++) {
221 if (!mask || mask[i]) {
222 GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
223 trb->Store(trb->TexImage, x + i, y, z, &flt);
224 }
225 }
226 }
227 else {
228 _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
229 }
230 }
231
232 /**
233 * Put row of RGB values into a renderbuffer that wraps a texture image.
234 */
235 static void
236 texture_put_row_rgb(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
237 GLint x, GLint y, const void *values, const GLubyte *mask)
238 {
239 const struct texture_renderbuffer *trb
240 = (const struct texture_renderbuffer *) rb;
241 const GLint z = trb->Zoffset;
242 GLuint i;
243
244 y += trb->Yoffset;
245
246 if (rb->DataType == CHAN_TYPE) {
247 const GLchan *rgb = (const GLchan *) values;
248 for (i = 0; i < count; i++) {
249 if (!mask || mask[i]) {
250 trb->Store(trb->TexImage, x + i, y, z, rgb);
251 }
252 rgb += 3;
253 }
254 }
255 else if (rb->DataType == GL_UNSIGNED_SHORT) {
256 const GLushort *zValues = (const GLushort *) values;
257 for (i = 0; i < count; i++) {
258 if (!mask || mask[i]) {
259 trb->Store(trb->TexImage, x + i, y, z, zValues + i);
260 }
261 }
262 }
263 else if (rb->DataType == GL_UNSIGNED_INT) {
264 const GLuint *zValues = (const GLuint *) values;
265 for (i = 0; i < count; i++) {
266 if (!mask || mask[i]) {
267 trb->Store(trb->TexImage, x + i, y, z, zValues + i);
268 }
269 }
270 }
271 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
272 const GLuint *zValues = (const GLuint *) values;
273 for (i = 0; i < count; i++) {
274 if (!mask || mask[i]) {
275 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
276 trb->Store(trb->TexImage, x + i, y, z, &flt);
277 }
278 }
279 }
280 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
281 const GLuint *zValues = (const GLuint *) values;
282 for (i = 0; i < count; i++) {
283 if (!mask || mask[i]) {
284 GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
285 trb->Store(trb->TexImage, x + i, y, z, &flt);
286 }
287 }
288 }
289 else {
290 _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
291 }
292 }
293
294
295 static void
296 texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
297 GLint x, GLint y, const void *value, const GLubyte *mask)
298 {
299 const struct texture_renderbuffer *trb
300 = (const struct texture_renderbuffer *) rb;
301 const GLint z = trb->Zoffset;
302 GLuint i;
303
304 y += trb->Yoffset;
305
306 if (rb->DataType == CHAN_TYPE) {
307 const GLchan *rgba = (const GLchan *) value;
308 for (i = 0; i < count; i++) {
309 if (!mask || mask[i]) {
310 trb->Store(trb->TexImage, x + i, y, z, rgba);
311 }
312 }
313 }
314 else if (rb->DataType == GL_UNSIGNED_SHORT) {
315 const GLushort zValue = *((const GLushort *) value);
316 for (i = 0; i < count; i++) {
317 if (!mask || mask[i]) {
318 trb->Store(trb->TexImage, x + i, y, z, &zValue);
319 }
320 }
321 }
322 else if (rb->DataType == GL_UNSIGNED_INT) {
323 const GLuint zValue = *((const GLuint *) value);
324 for (i = 0; i < count; i++) {
325 if (!mask || mask[i]) {
326 trb->Store(trb->TexImage, x + i, y, z, &zValue);
327 }
328 }
329 }
330 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
331 const GLuint zValue = *((const GLuint *) value);
332 const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff));
333 for (i = 0; i < count; i++) {
334 if (!mask || mask[i]) {
335 trb->Store(trb->TexImage, x + i, y, z, &flt);
336 }
337 }
338 }
339 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
340 const GLuint zValue = *((const GLuint *) value);
341 const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (1.0 / 0xffffff));
342 for (i = 0; i < count; i++) {
343 if (!mask || mask[i]) {
344 trb->Store(trb->TexImage, x + i, y, z, &flt);
345 }
346 }
347 }
348 else {
349 _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row");
350 }
351 }
352
353
354 static void
355 texture_put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
356 const GLint x[], const GLint y[], const void *values,
357 const GLubyte *mask)
358 {
359 const struct texture_renderbuffer *trb
360 = (const struct texture_renderbuffer *) rb;
361 const GLint z = trb->Zoffset;
362 GLuint i;
363
364 if (rb->DataType == CHAN_TYPE) {
365 const GLchan *rgba = (const GLchan *) values;
366 for (i = 0; i < count; i++) {
367 if (!mask || mask[i]) {
368 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
369 }
370 rgba += 4;
371 }
372 }
373 else if (rb->DataType == GL_UNSIGNED_SHORT) {
374 const GLushort *zValues = (const GLushort *) values;
375 for (i = 0; i < count; i++) {
376 if (!mask || mask[i]) {
377 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
378 }
379 }
380 }
381 else if (rb->DataType == GL_UNSIGNED_INT) {
382 const GLuint *zValues = (const GLuint *) values;
383 for (i = 0; i < count; i++) {
384 if (!mask || mask[i]) {
385 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
386 }
387 }
388 }
389 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
390 const GLuint *zValues = (const GLuint *) values;
391 for (i = 0; i < count; i++) {
392 if (!mask || mask[i]) {
393 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
394 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
395 }
396 }
397 }
398 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
399 const GLuint *zValues = (const GLuint *) values;
400 for (i = 0; i < count; i++) {
401 if (!mask || mask[i]) {
402 GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
403 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
404 }
405 }
406 }
407 else {
408 _mesa_problem(ctx, "invalid rb->DataType in texture_put_values");
409 }
410 }
411
412
413 static void
414 texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
415 GLuint count, const GLint x[], const GLint y[],
416 const void *value, const GLubyte *mask)
417 {
418 const struct texture_renderbuffer *trb
419 = (const struct texture_renderbuffer *) rb;
420 const GLint z = trb->Zoffset;
421 GLuint i;
422
423 if (rb->DataType == CHAN_TYPE) {
424 const GLchan *rgba = (const GLchan *) value;
425 for (i = 0; i < count; i++) {
426 if (!mask || mask[i]) {
427 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
428 }
429 }
430 }
431 else if (rb->DataType == GL_UNSIGNED_INT) {
432 const GLuint zValue = *((const GLuint *) value);
433 for (i = 0; i < count; i++) {
434 if (!mask || mask[i]) {
435 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
436 }
437 }
438 }
439 else if (rb->DataType == GL_UNSIGNED_SHORT) {
440 const GLushort zValue = *((const GLushort *) value);
441 for (i = 0; i < count; i++) {
442 if (!mask || mask[i]) {
443 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
444 }
445 }
446 }
447 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
448 const GLuint zValue = *((const GLuint *) value);
449 const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff));
450 for (i = 0; i < count; i++) {
451 if (!mask || mask[i]) {
452 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
453 }
454 }
455 }
456 else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
457 const GLuint zValue = *((const GLuint *) value);
458 const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (1.0 / 0xffffff));
459 for (i = 0; i < count; i++) {
460 if (!mask || mask[i]) {
461 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
462 }
463 }
464 }
465 else {
466 _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values");
467 }
468 }
469
470
471 static void
472 store_nop(struct swrast_texture_image *texImage,
473 GLint col, GLint row, GLint img,
474 const void *texel)
475 {
476 }
477
478
479 static void
480 delete_texture_wrapper(struct gl_renderbuffer *rb)
481 {
482 ASSERT(rb->RefCount == 0);
483 free(rb);
484 }
485
486
487 /**
488 * This function creates a renderbuffer object which wraps a texture image.
489 * The new renderbuffer is plugged into the given attachment point.
490 * This allows rendering into the texture as if it were a renderbuffer.
491 */
492 static void
493 wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
494 {
495 struct texture_renderbuffer *trb;
496 const GLuint name = 0;
497
498 ASSERT(att->Type == GL_TEXTURE);
499 ASSERT(att->Renderbuffer == NULL);
500
501 trb = CALLOC_STRUCT(texture_renderbuffer);
502 if (!trb) {
503 _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
504 return;
505 }
506
507 /* init base gl_renderbuffer fields */
508 _mesa_init_renderbuffer(&trb->Base, name);
509 /* plug in our texture_renderbuffer-specific functions */
510 trb->Base.Delete = delete_texture_wrapper;
511 trb->Base.AllocStorage = NULL; /* illegal! */
512 trb->Base.GetRow = texture_get_row;
513 trb->Base.GetValues = texture_get_values;
514 trb->Base.PutRow = texture_put_row;
515 trb->Base.PutRowRGB = texture_put_row_rgb;
516 trb->Base.PutMonoRow = texture_put_mono_row;
517 trb->Base.PutValues = texture_put_values;
518 trb->Base.PutMonoValues = texture_put_mono_values;
519
520 /* update attachment point */
521 _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
522 }
523
524 /**
525 * Update the renderbuffer wrapper for rendering to a texture.
526 * For example, update the width, height of the RB based on the texture size,
527 * update the internal format info, etc.
528 */
529 static void
530 update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
531 {
532 struct texture_renderbuffer *trb
533 = (struct texture_renderbuffer *) att->Renderbuffer;
534
535 (void) ctx;
536 ASSERT(trb);
537
538 trb->TexImage = swrast_texture_image(_mesa_get_attachment_teximage(att));
539 ASSERT(trb->TexImage);
540
541 trb->Store = _mesa_get_texel_store_func(trb->TexImage->Base.TexFormat);
542 if (!trb->Store) {
543 /* we'll never draw into some textures (compressed formats) */
544 trb->Store = store_nop;
545 }
546
547 if (!trb->TexImage->FetchTexelf) {
548 _mesa_update_fetch_functions(trb->TexImage->Base.TexObject);
549 }
550 trb->Fetchf = trb->TexImage->FetchTexelf;
551 assert(trb->Fetchf);
552
553 if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
554 trb->Yoffset = att->Zoffset;
555 trb->Zoffset = 0;
556 }
557 else {
558 trb->Yoffset = 0;
559 trb->Zoffset = att->Zoffset;
560 }
561
562 trb->Base.Width = trb->TexImage->Base.Width;
563 trb->Base.Height = trb->TexImage->Base.Height;
564 trb->Base.InternalFormat = trb->TexImage->Base.InternalFormat;
565 trb->Base.Format = trb->TexImage->Base.TexFormat;
566
567 /* XXX may need more special cases here */
568 switch (trb->TexImage->Base.TexFormat) {
569 case MESA_FORMAT_Z24_S8:
570 trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
571 trb->Base._BaseFormat = GL_DEPTH_STENCIL;
572 break;
573 case MESA_FORMAT_S8_Z24:
574 trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA;
575 trb->Base._BaseFormat = GL_DEPTH_STENCIL;
576 break;
577 case MESA_FORMAT_Z24_X8:
578 trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
579 trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
580 break;
581 case MESA_FORMAT_X8_Z24:
582 trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA;
583 trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
584 break;
585 case MESA_FORMAT_Z16:
586 trb->Base.DataType = GL_UNSIGNED_SHORT;
587 trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
588 break;
589 case MESA_FORMAT_Z32:
590 trb->Base.DataType = GL_UNSIGNED_INT;
591 trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
592 break;
593 /* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */
594 case MESA_FORMAT_SRGB8:
595 trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888, _mesa_get_texture_dimensions(att->Texture->Target));
596 trb->Base.DataType = CHAN_TYPE;
597 trb->Base._BaseFormat = GL_RGBA;
598 break;
599 case MESA_FORMAT_SRGBA8:
600 trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888, _mesa_get_texture_dimensions(att->Texture->Target));
601 trb->Base.DataType = CHAN_TYPE;
602 trb->Base._BaseFormat = GL_RGBA;
603 break;
604 case MESA_FORMAT_SARGB8:
605 trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_ARGB8888, _mesa_get_texture_dimensions(att->Texture->Target));
606 trb->Base.DataType = CHAN_TYPE;
607 trb->Base._BaseFormat = GL_RGBA;
608 break;
609 default:
610 trb->Base.DataType = CHAN_TYPE;
611 trb->Base._BaseFormat = GL_RGBA;
612 }
613 trb->Base.Data = trb->TexImage->Base.Data;
614 }
615
616
617
618 /**
619 * Called when rendering to a texture image begins, or when changing
620 * the dest mipmap level, cube face, etc.
621 * This is a fallback routine for software render-to-texture.
622 *
623 * Called via the glRenderbufferTexture1D/2D/3D() functions
624 * and elsewhere (such as glTexImage2D).
625 *
626 * The image we're rendering into is
627 * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
628 * It'll never be NULL.
629 *
630 * \param fb the framebuffer object the texture is being bound to
631 * \param att the fb attachment point of the texture
632 *
633 * \sa _mesa_framebuffer_renderbuffer
634 */
635 void
636 _swrast_render_texture(struct gl_context *ctx,
637 struct gl_framebuffer *fb,
638 struct gl_renderbuffer_attachment *att)
639 {
640 (void) fb;
641
642 if (!att->Renderbuffer) {
643 wrap_texture(ctx, att);
644 }
645 update_wrapper(ctx, att);
646 }
647
648
649 void
650 _swrast_finish_render_texture(struct gl_context *ctx,
651 struct gl_renderbuffer_attachment *att)
652 {
653 /* do nothing */
654 /* The renderbuffer texture wrapper will get deleted by the
655 * normal mechanism for deleting renderbuffers.
656 */
657 (void) ctx;
658 (void) att;
659 }