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
,
564 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
565 struct gl_renderbuffer
*rb
,
568 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
569 struct radeon_renderbuffer
*rrb
;
573 screen
= radeon
->radeonScreen
->driScreen
;
574 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
575 screen
->loaderPrivate
);
579 rrb
= radeon_renderbuffer(rb
);
581 if (ctx
->Driver
.Flush
)
582 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
585 radeon_bo_unref(rrb
->bo
);
587 radeon_bo_ref(rrb
->bo
);
588 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
589 image
->width
, image
->pitch
);
591 rrb
->cpp
= image
->cpp
;
592 rrb
->pitch
= image
->pitch
* image
->cpp
;
594 rb
->Format
= image
->format
;
595 rb
->InternalFormat
= image
->internal_format
;
596 rb
->Width
= image
->width
;
597 rb
->Height
= image
->height
;
598 rb
->Format
= image
->format
;
599 rb
->_BaseFormat
= _mesa_base_fbo_format(radeon
->glCtx
,
600 image
->internal_format
);
604 * Called for each hardware renderbuffer when a _window_ is resized.
605 * Just update fields.
606 * Not used for user-created renderbuffers!
609 radeon_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
610 GLenum internalFormat
, GLuint width
, GLuint height
)
612 ASSERT(rb
->Name
== 0);
615 rb
->InternalFormat
= internalFormat
;
616 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
626 radeon_resize_buffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
627 GLuint width
, GLuint height
)
629 struct radeon_framebuffer
*radeon_fb
= (struct radeon_framebuffer
*)fb
;
632 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
636 _mesa_resize_framebuffer(ctx
, fb
, width
, height
);
638 fb
->Initialized
= GL_TRUE
; /* XXX remove someday */
644 /* Make sure all window system renderbuffers are up to date */
645 for (i
= 0; i
< 2; i
++) {
646 struct gl_renderbuffer
*rb
= &radeon_fb
->color_rb
[i
]->base
.Base
;
648 /* only resize if size is changing */
649 if (rb
&& (rb
->Width
!= width
|| rb
->Height
!= height
)) {
650 rb
->AllocStorage(ctx
, rb
, rb
->InternalFormat
, width
, height
);
656 /** Dummy function for gl_renderbuffer::AllocStorage() */
658 radeon_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
659 GLenum internalFormat
, GLuint width
, GLuint height
)
661 _mesa_problem(ctx
, "radeon_op_alloc_storage should never be called.");
667 * Create a renderbuffer for a window's color, depth and/or stencil buffer.
668 * Not used for user-created renderbuffers.
670 struct radeon_renderbuffer
*
671 radeon_create_renderbuffer(gl_format format
, __DRIdrawable
*driDrawPriv
)
673 struct radeon_renderbuffer
*rrb
;
674 struct gl_renderbuffer
*rb
;
676 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
678 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
685 rb
= &rrb
->base
.Base
;
687 _mesa_init_renderbuffer(rb
, 0);
688 rb
->ClassID
= RADEON_RB_CLASS
;
690 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
691 rb
->InternalFormat
= _mesa_get_format_base_format(format
);
693 rrb
->dPriv
= driDrawPriv
;
695 rb
->Delete
= radeon_delete_renderbuffer
;
696 rb
->AllocStorage
= radeon_alloc_window_storage
;
702 static struct gl_renderbuffer
*
703 radeon_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
705 struct radeon_renderbuffer
*rrb
;
706 struct gl_renderbuffer
*rb
;
709 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
711 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
718 rb
= &rrb
->base
.Base
;
720 _mesa_init_renderbuffer(rb
, name
);
721 rb
->ClassID
= RADEON_RB_CLASS
;
722 rb
->Delete
= radeon_delete_renderbuffer
;
723 rb
->AllocStorage
= radeon_alloc_renderbuffer_storage
;
729 radeon_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
730 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
732 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
733 "%s(%p, fb %p, target %s) \n",
735 _mesa_lookup_enum_by_nr(target
));
737 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
738 radeon_draw_buffer(ctx
, fb
);
741 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
746 radeon_framebuffer_renderbuffer(struct gl_context
* ctx
,
747 struct gl_framebuffer
*fb
,
748 GLenum attachment
, struct gl_renderbuffer
*rb
)
751 if (ctx
->Driver
.Flush
)
752 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
754 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
755 "%s(%p, fb %p, rb %p) \n",
756 __func__
, ctx
, fb
, rb
);
758 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
759 radeon_draw_buffer(ctx
, fb
);
763 radeon_update_wrapper(struct gl_context
*ctx
, struct radeon_renderbuffer
*rrb
,
764 struct gl_texture_image
*texImage
)
766 struct gl_renderbuffer
*rb
= &rrb
->base
.Base
;
768 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
769 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
770 __func__
, ctx
, rrb
, texImage
, _mesa_get_format_name(texImage
->TexFormat
));
772 rrb
->cpp
= _mesa_get_format_bytes(texImage
->TexFormat
);
773 rrb
->pitch
= texImage
->Width
* rrb
->cpp
;
774 rb
->Format
= texImage
->TexFormat
;
775 rb
->InternalFormat
= texImage
->InternalFormat
;
776 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, rb
->InternalFormat
);
777 rb
->Width
= texImage
->Width
;
778 rb
->Height
= texImage
->Height
;
779 rb
->Delete
= radeon_delete_renderbuffer
;
780 rb
->AllocStorage
= radeon_nop_alloc_storage
;
786 static struct radeon_renderbuffer
*
787 radeon_wrap_texture(struct gl_context
* ctx
, struct gl_texture_image
*texImage
)
789 const GLuint name
= ~0; /* not significant, but distinct for debugging */
790 struct radeon_renderbuffer
*rrb
;
792 /* make an radeon_renderbuffer to wrap the texture image */
793 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
795 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
796 "%s(%p, rrb %p, texImage %p) \n",
797 __func__
, ctx
, rrb
, texImage
);
800 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glFramebufferTexture");
804 _mesa_init_renderbuffer(&rrb
->base
.Base
, name
);
805 rrb
->base
.Base
.ClassID
= RADEON_RB_CLASS
;
807 if (!radeon_update_wrapper(ctx
, rrb
, texImage
)) {
816 radeon_render_texture(struct gl_context
* ctx
,
817 struct gl_framebuffer
*fb
,
818 struct gl_renderbuffer_attachment
*att
)
820 struct gl_texture_image
*newImage
821 = att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
822 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(att
->Renderbuffer
);
823 radeon_texture_image
*radeon_image
;
826 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
827 "%s(%p, fb %p, rrb %p, att %p)\n",
828 __func__
, ctx
, fb
, rrb
, att
);
834 radeon_image
= (radeon_texture_image
*)newImage
;
836 if (!radeon_image
->mt
) {
837 /* Fallback on drawing to a texture without a miptree.
839 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
840 _swrast_render_texture(ctx
, fb
, att
);
844 rrb
= radeon_wrap_texture(ctx
, newImage
);
846 /* bind the wrapper to the attachment point */
847 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &rrb
->base
.Base
);
850 /* fallback to software rendering */
851 _swrast_render_texture(ctx
, fb
, att
);
856 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
857 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
858 _swrast_render_texture(ctx
, fb
, att
);
862 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
864 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
865 rrb
->base
.Base
.RefCount
);
867 /* point the renderbufer's region to the texture image region */
868 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
870 radeon_bo_unref(rrb
->bo
);
871 rrb
->bo
= radeon_image
->mt
->bo
;
872 radeon_bo_ref(rrb
->bo
);
875 /* compute offset of the particular 2D image within the texture region */
876 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
880 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
881 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
882 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
886 /* store that offset in the region, along with the correct pitch for
887 * the image we are rendering to */
888 rrb
->draw_offset
= imageOffset
;
889 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
890 radeon_image
->used_as_render_target
= GL_TRUE
;
892 /* update drawing region, etc */
893 radeon_draw_buffer(ctx
, fb
);
897 radeon_finish_render_texture(struct gl_context
* ctx
,
898 struct gl_renderbuffer_attachment
*att
)
900 struct gl_texture_object
*tex_obj
= att
->Texture
;
901 struct gl_texture_image
*image
=
902 tex_obj
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
903 radeon_texture_image
*radeon_image
= (radeon_texture_image
*)image
;
906 radeon_image
->used_as_render_target
= GL_FALSE
;
908 if (ctx
->Driver
.Flush
)
909 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
912 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
914 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
915 gl_format mesa_format
;
918 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
919 struct gl_renderbuffer_attachment
*att
;
921 att
= &fb
->Attachment
[BUFFER_DEPTH
];
922 } else if (i
== -1) {
923 att
= &fb
->Attachment
[BUFFER_STENCIL
];
925 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
928 if (att
->Type
== GL_TEXTURE
) {
929 mesa_format
= att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
]->TexFormat
;
931 /* All renderbuffer formats are renderable, but not sampable */
935 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
936 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
937 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
938 "%s: HW doesn't support format %s as output format of attachment %d\n",
939 __FUNCTION__
, _mesa_get_format_name(mesa_format
), i
);
945 void radeon_fbo_init(struct radeon_context
*radeon
)
947 radeon
->glCtx
->Driver
.NewFramebuffer
= radeon_new_framebuffer
;
948 radeon
->glCtx
->Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
949 radeon
->glCtx
->Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
950 radeon
->glCtx
->Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
951 radeon
->glCtx
->Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
952 radeon
->glCtx
->Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
953 radeon
->glCtx
->Driver
.RenderTexture
= radeon_render_texture
;
954 radeon
->glCtx
->Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
955 radeon
->glCtx
->Driver
.ResizeBuffers
= radeon_resize_buffers
;
956 radeon
->glCtx
->Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
957 #if FEATURE_EXT_framebuffer_blit
958 radeon
->glCtx
->Driver
.BlitFramebuffer
= _mesa_meta_BlitFramebuffer
;
960 radeon
->glCtx
->Driver
.EGLImageTargetRenderbufferStorage
=
961 radeon_image_target_renderbuffer_storage
;
965 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
966 struct radeon_bo
*bo
)
968 struct radeon_bo
*old
;
973 radeon_bo_unref(old
);