1 /**************************************************************************
3 * Copyright 2008 Red Hat Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 #include "main/imports.h"
30 #include "main/macros.h"
31 #include "main/mfeatures.h"
32 #include "main/mtypes.h"
33 #include "main/enums.h"
34 #include "main/fbobject.h"
35 #include "main/framebuffer.h"
36 #include "main/renderbuffer.h"
37 #include "main/context.h"
38 #include "swrast/swrast.h"
39 #include "drivers/common/meta.h"
41 #include "radeon_common.h"
42 #include "radeon_mipmap_tree.h"
44 #define FILE_DEBUG_FLAG RADEON_TEXTURE
45 #define DBG(...) do { \
46 if (RADEON_DEBUG & FILE_DEBUG_FLAG) \
47 printf(__VA_ARGS__); \
50 static struct gl_framebuffer
*
51 radeon_new_framebuffer(struct gl_context
*ctx
, GLuint name
)
53 return _mesa_new_framebuffer(ctx
, name
);
57 radeon_delete_renderbuffer(struct gl_renderbuffer
*rb
)
59 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
61 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
62 "%s(rb %p, rrb %p) \n",
68 radeon_bo_unref(rrb
->bo
);
70 _mesa_delete_renderbuffer(rb
);
73 #if defined(RADEON_R100)
74 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
77 GLuint ba
, address
= 0;
79 ba
= (y
>> 4) * (rrb
->pitch
>> 6) + (x
>> 4);
81 address
|= (x
& 0x7) << 2;
82 address
|= (y
& 0x3) << 5;
83 address
|= (((x
& 0x10) >> 2) ^ (y
& 0x4)) << 5;
84 address
|= (ba
& 3) << 8;
85 address
|= (y
& 0x8) << 7;
86 address
|= (((x
& 0x8) << 1) ^ (y
& 0x10)) << 7;
87 address
|= (ba
& ~0x3) << 10;
91 static GLuint
get_depth_z16(const struct radeon_renderbuffer
* rrb
,
94 GLuint ba
, address
= 0; /* a[0] = 0 */
96 ba
= (y
/ 16) * (rrb
->pitch
>> 6) + (x
/ 32);
98 address
|= (x
& 0x7) << 1; /* a[1..3] = x[0..2] */
99 address
|= (y
& 0x7) << 4; /* a[4..6] = y[0..2] */
100 address
|= (x
& 0x8) << 4; /* a[7] = x[3] */
101 address
|= (ba
& 0x3) << 8; /* a[8..9] = ba[0..1] */
102 address
|= (y
& 0x8) << 7; /* a[10] = y[3] */
103 address
|= ((x
& 0x10) ^ (y
& 0x10)) << 7;/* a[11] = x[4] ^ y[4] */
104 address
|= (ba
& ~0x3) << 10; /* a[12..] = ba[2..] */
109 #if defined(RADEON_R200)
110 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
116 b
= (((y
& 0x7ff) >> 4) * (rrb
->pitch
>> 7) + (x
>> 5));
117 offset
+= (b
>> 1) << 12;
118 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
119 offset
+= ((y
>> 2) & 0x3) << 9;
120 offset
+= ((x
>> 2) & 0x1) << 8;
121 offset
+= ((x
>> 3) & 0x3) << 6;
122 offset
+= ((y
>> 1) & 0x1) << 5;
123 offset
+= ((x
>> 1) & 0x1) << 4;
124 offset
+= (y
& 0x1) << 3;
125 offset
+= (x
& 0x1) << 2;
130 static GLuint
get_depth_z16(const struct radeon_renderbuffer
*rrb
,
137 b
= (((y
>> 4) * (rrb
->pitch
>> 7) + (x
>> 6)));
138 offset
+= (b
>> 1) << 12;
139 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
140 offset
+= ((y
>> 2) & 0x3) << 9;
141 offset
+= ((x
>> 3) & 0x1) << 8;
142 offset
+= ((x
>> 4) & 0x3) << 6;
143 offset
+= ((x
>> 2) & 0x1) << 5;
144 offset
+= ((y
>> 1) & 0x1) << 4;
145 offset
+= ((x
>> 1) & 0x1) << 3;
146 offset
+= (y
& 0x1) << 2;
147 offset
+= (x
& 0x1) << 1;
154 radeon_map_renderbuffer_s8z24(struct gl_context
*ctx
,
155 struct gl_renderbuffer
*rb
,
156 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
161 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
162 uint32_t *untiled_s8z24_map
, *tiled_s8z24_map
;
164 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
165 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
166 uint32_t pitch
= w
* rrb
->cpp
;
168 rrb
->map_pitch
= pitch
;
170 rrb
->map_buffer
= malloc(w
* h
* 4);
171 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
173 untiled_s8z24_map
= rrb
->map_buffer
;
174 tiled_s8z24_map
= rrb
->bo
->ptr
;
176 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
177 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
178 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
179 uint32_t src_offset
= get_depth_z32(rrb
, x
+ pix_x
, flipped_y
);
180 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
181 untiled_s8z24_map
[dst_offset
/4] = tiled_s8z24_map
[src_offset
/4];
185 radeon_bo_unmap(rrb
->bo
);
187 *out_map
= rrb
->map_buffer
;
188 *out_stride
= rrb
->map_pitch
;
192 radeon_map_renderbuffer_z16(struct gl_context
*ctx
,
193 struct gl_renderbuffer
*rb
,
194 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
199 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
200 uint16_t *untiled_z16_map
, *tiled_z16_map
;
202 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
203 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
204 uint32_t pitch
= w
* rrb
->cpp
;
206 rrb
->map_pitch
= pitch
;
208 rrb
->map_buffer
= malloc(w
* h
* 2);
209 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
212 untiled_z16_map
= rrb
->map_buffer
;
213 tiled_z16_map
= rrb
->bo
->ptr
;
215 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
216 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
217 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
218 uint32_t src_offset
= get_depth_z16(rrb
, x
+ pix_x
, flipped_y
);
219 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
220 untiled_z16_map
[dst_offset
/2] = tiled_z16_map
[src_offset
/2];
224 radeon_bo_unmap(rrb
->bo
);
226 *out_map
= rrb
->map_buffer
;
227 *out_stride
= rrb
->map_pitch
;
231 radeon_map_renderbuffer(struct gl_context
*ctx
,
232 struct gl_renderbuffer
*rb
,
233 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
238 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
239 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
242 int stride
, flip_stride
;
246 if (!rrb
|| !rrb
->bo
) {
252 rrb
->map_mode
= mode
;
257 rrb
->map_pitch
= rrb
->pitch
;
259 ok
= rmesa
->vtbl
.check_blit(rb
->Format
, rrb
->pitch
/ rrb
->cpp
);
266 src_y
= rrb
->base
.Base
.Height
- y
- h
;
269 /* Make a temporary buffer and blit the current contents of the renderbuffer
270 * out to it. This gives us linear access to the buffer, instead of having
271 * to do detiling in software.
274 rrb
->map_pitch
= rrb
->pitch
;
276 assert(!rrb
->map_bo
);
277 rrb
->map_bo
= radeon_bo_open(rmesa
->radeonScreen
->bom
, 0,
278 rrb
->map_pitch
* h
, 4,
279 RADEON_GEM_DOMAIN_GTT
, 0);
281 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->bo
, rrb
->draw_offset
,
282 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
283 rb
->Width
, rb
->Height
,
286 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
293 ret
= radeon_bo_map(rrb
->map_bo
, !!(mode
& GL_MAP_WRITE_BIT
));
296 map
= rrb
->map_bo
->ptr
;
300 *out_stride
= rrb
->map_pitch
;
302 *out_map
= map
+ (h
- 1) * rrb
->map_pitch
;
303 *out_stride
= -rrb
->map_pitch
;
308 /* sw fallback flush stuff */
309 if (radeon_bo_is_referenced_by_cs(rrb
->bo
, rmesa
->cmdbuf
.cs
)) {
310 radeon_firevertices(rmesa
);
313 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
314 if (rb
->Format
== MESA_FORMAT_S8_Z24
|| rb
->Format
== MESA_FORMAT_X8_Z24
) {
315 radeon_map_renderbuffer_s8z24(ctx
, rb
, x
, y
, w
, h
,
316 mode
, out_map
, out_stride
);
319 if (rb
->Format
== MESA_FORMAT_Z16
) {
320 radeon_map_renderbuffer_z16(ctx
, rb
, x
, y
, w
, h
,
321 mode
, out_map
, out_stride
);
326 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
330 stride
= rrb
->map_pitch
;
333 y
= rb
->Height
- 1 - y
;
334 flip_stride
= -stride
;
336 flip_stride
= stride
;
337 map
+= rrb
->draw_offset
;
341 map
+= (int)y
* stride
;
344 *out_stride
= flip_stride
;
348 radeon_unmap_renderbuffer_s8z24(struct gl_context
*ctx
,
349 struct gl_renderbuffer
*rb
)
351 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
353 if (!rrb
->map_buffer
)
356 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
357 uint32_t *untiled_s8z24_map
= rrb
->map_buffer
;
358 uint32_t *tiled_s8z24_map
;
359 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
360 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
362 radeon_bo_map(rrb
->bo
, 1);
364 tiled_s8z24_map
= rrb
->bo
->ptr
;
366 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
367 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
368 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
369 uint32_t dst_offset
= get_depth_z32(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
370 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
371 tiled_s8z24_map
[dst_offset
/4] = untiled_s8z24_map
[src_offset
/4];
374 radeon_bo_unmap(rrb
->bo
);
376 free(rrb
->map_buffer
);
377 rrb
->map_buffer
= NULL
;
381 radeon_unmap_renderbuffer_z16(struct gl_context
*ctx
,
382 struct gl_renderbuffer
*rb
)
384 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
386 if (!rrb
->map_buffer
)
389 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
390 uint16_t *untiled_z16_map
= rrb
->map_buffer
;
391 uint16_t *tiled_z16_map
;
392 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
393 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
395 radeon_bo_map(rrb
->bo
, 1);
397 tiled_z16_map
= rrb
->bo
->ptr
;
399 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
400 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
401 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
402 uint32_t dst_offset
= get_depth_z16(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
403 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
404 tiled_z16_map
[dst_offset
/2] = untiled_z16_map
[src_offset
/2];
407 radeon_bo_unmap(rrb
->bo
);
409 free(rrb
->map_buffer
);
410 rrb
->map_buffer
= NULL
;
415 radeon_unmap_renderbuffer(struct gl_context
*ctx
,
416 struct gl_renderbuffer
*rb
)
418 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
419 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
422 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
423 if (rb
->Format
== MESA_FORMAT_S8_Z24
|| rb
->Format
== MESA_FORMAT_X8_Z24
) {
424 radeon_unmap_renderbuffer_s8z24(ctx
, rb
);
427 if (rb
->Format
== MESA_FORMAT_Z16
) {
428 radeon_unmap_renderbuffer_z16(ctx
, rb
);
435 radeon_bo_unmap(rrb
->bo
);
439 radeon_bo_unmap(rrb
->map_bo
);
441 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
442 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->map_bo
, 0,
443 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
444 rrb
->map_w
, rrb
->map_h
,
446 rrb
->bo
, rrb
->draw_offset
,
447 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
448 rb
->Width
, rb
->Height
,
449 rrb
->map_x
, rrb
->map_y
,
450 rrb
->map_w
, rrb
->map_h
,
455 radeon_bo_unref(rrb
->map_bo
);
461 * Called via glRenderbufferStorageEXT() to set the format and allocate
462 * storage for a user-created renderbuffer.
465 radeon_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
466 GLenum internalFormat
,
467 GLuint width
, GLuint height
)
469 struct radeon_context
*radeon
= RADEON_CONTEXT(ctx
);
470 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
471 uint32_t size
, pitch
;
474 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
478 ASSERT(rb
->Name
!= 0);
479 switch (internalFormat
) {
483 rb
->Format
= _radeon_texformat_rgb565
;
491 rb
->Format
= _radeon_texformat_argb8888
;
502 rb
->Format
= _radeon_texformat_argb8888
;
505 case GL_STENCIL_INDEX
:
506 case GL_STENCIL_INDEX1_EXT
:
507 case GL_STENCIL_INDEX4_EXT
:
508 case GL_STENCIL_INDEX8_EXT
:
509 case GL_STENCIL_INDEX16_EXT
:
510 /* alloc a depth+stencil buffer */
511 rb
->Format
= MESA_FORMAT_S8_Z24
;
514 case GL_DEPTH_COMPONENT16
:
515 rb
->Format
= MESA_FORMAT_Z16
;
518 case GL_DEPTH_COMPONENT
:
519 case GL_DEPTH_COMPONENT24
:
520 case GL_DEPTH_COMPONENT32
:
521 rb
->Format
= MESA_FORMAT_X8_Z24
;
524 case GL_DEPTH_STENCIL_EXT
:
525 case GL_DEPTH24_STENCIL8_EXT
:
526 rb
->Format
= MESA_FORMAT_S8_Z24
;
531 "Unexpected format in radeon_alloc_renderbuffer_storage");
535 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
537 if (ctx
->Driver
.Flush
)
538 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
541 radeon_bo_unref(rrb
->bo
);
543 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
;
545 if (RADEON_DEBUG
& RADEON_MEMORY
)
546 fprintf(stderr
,"Allocating %d x %d radeon RBO (pitch %d)\n", width
,
549 size
= pitch
* height
* cpp
;
550 rrb
->pitch
= pitch
* cpp
;
552 rrb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
556 RADEON_GEM_DOMAIN_VRAM
,
563 #if FEATURE_OES_EGL_image
565 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
566 struct gl_renderbuffer
*rb
,
569 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
570 struct radeon_renderbuffer
*rrb
;
574 screen
= radeon
->radeonScreen
->driScreen
;
575 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
576 screen
->loaderPrivate
);
580 rrb
= radeon_renderbuffer(rb
);
582 if (ctx
->Driver
.Flush
)
583 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
586 radeon_bo_unref(rrb
->bo
);
588 radeon_bo_ref(rrb
->bo
);
589 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
590 image
->width
, image
->pitch
);
592 rrb
->cpp
= image
->cpp
;
593 rrb
->pitch
= image
->pitch
* image
->cpp
;
595 rb
->Format
= image
->format
;
596 rb
->InternalFormat
= image
->internal_format
;
597 rb
->Width
= image
->width
;
598 rb
->Height
= image
->height
;
599 rb
->Format
= image
->format
;
600 rb
->_BaseFormat
= _mesa_base_fbo_format(radeon
->glCtx
,
601 image
->internal_format
);
606 * Called for each hardware renderbuffer when a _window_ is resized.
607 * Just update fields.
608 * Not used for user-created renderbuffers!
611 radeon_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
612 GLenum internalFormat
, GLuint width
, GLuint height
)
614 ASSERT(rb
->Name
== 0);
617 rb
->InternalFormat
= internalFormat
;
618 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
628 radeon_resize_buffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
629 GLuint width
, GLuint height
)
631 struct radeon_framebuffer
*radeon_fb
= (struct radeon_framebuffer
*)fb
;
634 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
638 _mesa_resize_framebuffer(ctx
, fb
, width
, height
);
640 fb
->Initialized
= GL_TRUE
; /* XXX remove someday */
646 /* Make sure all window system renderbuffers are up to date */
647 for (i
= 0; i
< 2; i
++) {
648 struct gl_renderbuffer
*rb
= &radeon_fb
->color_rb
[i
]->base
.Base
;
650 /* only resize if size is changing */
651 if (rb
&& (rb
->Width
!= width
|| rb
->Height
!= height
)) {
652 rb
->AllocStorage(ctx
, rb
, rb
->InternalFormat
, width
, height
);
658 /** Dummy function for gl_renderbuffer::AllocStorage() */
660 radeon_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
661 GLenum internalFormat
, GLuint width
, GLuint height
)
663 _mesa_problem(ctx
, "radeon_op_alloc_storage should never be called.");
669 * Create a renderbuffer for a window's color, depth and/or stencil buffer.
670 * Not used for user-created renderbuffers.
672 struct radeon_renderbuffer
*
673 radeon_create_renderbuffer(gl_format format
, __DRIdrawable
*driDrawPriv
)
675 struct radeon_renderbuffer
*rrb
;
676 struct gl_renderbuffer
*rb
;
678 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
680 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
687 rb
= &rrb
->base
.Base
;
689 _mesa_init_renderbuffer(rb
, 0);
690 rb
->ClassID
= RADEON_RB_CLASS
;
692 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
693 rb
->InternalFormat
= _mesa_get_format_base_format(format
);
695 rrb
->dPriv
= driDrawPriv
;
697 rb
->Delete
= radeon_delete_renderbuffer
;
698 rb
->AllocStorage
= radeon_alloc_window_storage
;
704 static struct gl_renderbuffer
*
705 radeon_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
707 struct radeon_renderbuffer
*rrb
;
708 struct gl_renderbuffer
*rb
;
711 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
713 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
720 rb
= &rrb
->base
.Base
;
722 _mesa_init_renderbuffer(rb
, name
);
723 rb
->ClassID
= RADEON_RB_CLASS
;
724 rb
->Delete
= radeon_delete_renderbuffer
;
725 rb
->AllocStorage
= radeon_alloc_renderbuffer_storage
;
731 radeon_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
732 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
734 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
735 "%s(%p, fb %p, target %s) \n",
737 _mesa_lookup_enum_by_nr(target
));
739 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
740 radeon_draw_buffer(ctx
, fb
);
743 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
748 radeon_framebuffer_renderbuffer(struct gl_context
* ctx
,
749 struct gl_framebuffer
*fb
,
750 GLenum attachment
, struct gl_renderbuffer
*rb
)
753 if (ctx
->Driver
.Flush
)
754 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
756 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
757 "%s(%p, fb %p, rb %p) \n",
758 __func__
, ctx
, fb
, rb
);
760 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
761 radeon_draw_buffer(ctx
, fb
);
765 radeon_update_wrapper(struct gl_context
*ctx
, struct radeon_renderbuffer
*rrb
,
766 struct gl_texture_image
*texImage
)
768 struct gl_renderbuffer
*rb
= &rrb
->base
.Base
;
770 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
771 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
772 __func__
, ctx
, rrb
, texImage
, _mesa_get_format_name(texImage
->TexFormat
));
774 rrb
->cpp
= _mesa_get_format_bytes(texImage
->TexFormat
);
775 rrb
->pitch
= texImage
->Width
* rrb
->cpp
;
776 rb
->Format
= texImage
->TexFormat
;
777 rb
->InternalFormat
= texImage
->InternalFormat
;
778 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, rb
->InternalFormat
);
779 rb
->Width
= texImage
->Width
;
780 rb
->Height
= texImage
->Height
;
781 rb
->Delete
= radeon_delete_renderbuffer
;
782 rb
->AllocStorage
= radeon_nop_alloc_storage
;
788 static struct radeon_renderbuffer
*
789 radeon_wrap_texture(struct gl_context
* ctx
, struct gl_texture_image
*texImage
)
791 const GLuint name
= ~0; /* not significant, but distinct for debugging */
792 struct radeon_renderbuffer
*rrb
;
794 /* make an radeon_renderbuffer to wrap the texture image */
795 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
797 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
798 "%s(%p, rrb %p, texImage %p) \n",
799 __func__
, ctx
, rrb
, texImage
);
802 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glFramebufferTexture");
806 _mesa_init_renderbuffer(&rrb
->base
.Base
, name
);
807 rrb
->base
.Base
.ClassID
= RADEON_RB_CLASS
;
809 if (!radeon_update_wrapper(ctx
, rrb
, texImage
)) {
818 radeon_render_texture(struct gl_context
* ctx
,
819 struct gl_framebuffer
*fb
,
820 struct gl_renderbuffer_attachment
*att
)
822 struct gl_texture_image
*newImage
823 = att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
824 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(att
->Renderbuffer
);
825 radeon_texture_image
*radeon_image
;
828 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
829 "%s(%p, fb %p, rrb %p, att %p)\n",
830 __func__
, ctx
, fb
, rrb
, att
);
836 radeon_image
= (radeon_texture_image
*)newImage
;
838 if (!radeon_image
->mt
) {
839 /* Fallback on drawing to a texture without a miptree.
841 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
842 _swrast_render_texture(ctx
, fb
, att
);
846 rrb
= radeon_wrap_texture(ctx
, newImage
);
848 /* bind the wrapper to the attachment point */
849 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &rrb
->base
.Base
);
852 /* fallback to software rendering */
853 _swrast_render_texture(ctx
, fb
, att
);
858 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
859 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
860 _swrast_render_texture(ctx
, fb
, att
);
864 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
866 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
867 rrb
->base
.Base
.RefCount
);
869 /* point the renderbufer's region to the texture image region */
870 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
872 radeon_bo_unref(rrb
->bo
);
873 rrb
->bo
= radeon_image
->mt
->bo
;
874 radeon_bo_ref(rrb
->bo
);
877 /* compute offset of the particular 2D image within the texture region */
878 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
882 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
883 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
884 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
888 /* store that offset in the region, along with the correct pitch for
889 * the image we are rendering to */
890 rrb
->draw_offset
= imageOffset
;
891 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
892 radeon_image
->used_as_render_target
= GL_TRUE
;
894 /* update drawing region, etc */
895 radeon_draw_buffer(ctx
, fb
);
899 radeon_finish_render_texture(struct gl_context
* ctx
,
900 struct gl_renderbuffer_attachment
*att
)
902 struct gl_texture_object
*tex_obj
= att
->Texture
;
903 struct gl_texture_image
*image
=
904 tex_obj
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
905 radeon_texture_image
*radeon_image
= (radeon_texture_image
*)image
;
908 radeon_image
->used_as_render_target
= GL_FALSE
;
910 if (ctx
->Driver
.Flush
)
911 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
914 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
916 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
917 gl_format mesa_format
;
920 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
921 struct gl_renderbuffer_attachment
*att
;
923 att
= &fb
->Attachment
[BUFFER_DEPTH
];
924 } else if (i
== -1) {
925 att
= &fb
->Attachment
[BUFFER_STENCIL
];
927 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
930 if (att
->Type
== GL_TEXTURE
) {
931 mesa_format
= att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
]->TexFormat
;
933 /* All renderbuffer formats are renderable, but not sampable */
937 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
938 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
939 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
940 "%s: HW doesn't support format %s as output format of attachment %d\n",
941 __FUNCTION__
, _mesa_get_format_name(mesa_format
), i
);
947 void radeon_fbo_init(struct radeon_context
*radeon
)
949 radeon
->glCtx
->Driver
.NewFramebuffer
= radeon_new_framebuffer
;
950 radeon
->glCtx
->Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
951 radeon
->glCtx
->Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
952 radeon
->glCtx
->Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
953 radeon
->glCtx
->Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
954 radeon
->glCtx
->Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
955 radeon
->glCtx
->Driver
.RenderTexture
= radeon_render_texture
;
956 radeon
->glCtx
->Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
957 radeon
->glCtx
->Driver
.ResizeBuffers
= radeon_resize_buffers
;
958 radeon
->glCtx
->Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
959 #if FEATURE_EXT_framebuffer_blit
960 radeon
->glCtx
->Driver
.BlitFramebuffer
= _mesa_meta_BlitFramebuffer
;
962 #if FEATURE_OES_EGL_image
963 radeon
->glCtx
->Driver
.EGLImageTargetRenderbufferStorage
=
964 radeon_image_target_renderbuffer_storage
;
969 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
970 struct radeon_bo
*bo
)
972 struct radeon_bo
*old
;
977 radeon_bo_unref(old
);