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
);
73 #if defined(RADEON_R200)
74 static GLuint
r200_depth_4byte(const struct radeon_renderbuffer
* rrb
,
80 b
= (((y
& 0x7ff) >> 4) * (rrb
->pitch
>> 7) + (x
>> 5));
81 offset
+= (b
>> 1) << 12;
82 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
83 offset
+= ((y
>> 2) & 0x3) << 9;
84 offset
+= ((x
>> 2) & 0x1) << 8;
85 offset
+= ((x
>> 3) & 0x3) << 6;
86 offset
+= ((y
>> 1) & 0x1) << 5;
87 offset
+= ((x
>> 1) & 0x1) << 4;
88 offset
+= (y
& 0x1) << 3;
89 offset
+= (x
& 0x1) << 2;
95 radeon_map_renderbuffer_s8z24(struct gl_context
*ctx
,
96 struct gl_renderbuffer
*rb
,
97 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
102 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
103 uint32_t *untiled_s8z24_map
, *tiled_s8z24_map
;
105 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
106 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
107 uint32_t pitch
= w
* rrb
->cpp
;
109 rrb
->map_pitch
= pitch
;
111 rrb
->map_buffer
= malloc(w
* h
* 4);
112 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
114 untiled_s8z24_map
= rrb
->map_buffer
;
115 tiled_s8z24_map
= rrb
->bo
->ptr
;
117 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
118 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
119 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
120 uint32_t src_offset
= r200_depth_4byte(rrb
, x
+ pix_x
, flipped_y
);
121 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
122 untiled_s8z24_map
[dst_offset
/4] = tiled_s8z24_map
[src_offset
/4];
126 radeon_bo_unmap(rrb
->bo
);
128 *out_map
= rrb
->map_buffer
;
129 *out_stride
= rrb
->map_pitch
;
134 radeon_map_renderbuffer(struct gl_context
*ctx
,
135 struct gl_renderbuffer
*rb
,
136 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
141 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
142 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
145 int stride
, flip_stride
;
149 if (!rrb
|| !rrb
->bo
) {
155 rrb
->map_mode
= mode
;
160 rrb
->map_pitch
= rrb
->pitch
;
162 ok
= rmesa
->vtbl
.check_blit(rb
->Format
, rrb
->pitch
/ rrb
->cpp
);
169 src_y
= rrb
->base
.Height
- y
- h
;
172 /* Make a temporary buffer and blit the current contents of the renderbuffer
173 * out to it. This gives us linear access to the buffer, instead of having
174 * to do detiling in software.
177 rrb
->map_pitch
= rrb
->pitch
;
179 assert(!rrb
->map_bo
);
180 rrb
->map_bo
= radeon_bo_open(rmesa
->radeonScreen
->bom
, 0,
181 rrb
->map_pitch
* h
, 4,
182 RADEON_GEM_DOMAIN_GTT
, 0);
184 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->bo
, rrb
->draw_offset
,
185 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
186 rb
->Width
, rb
->Height
,
189 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
196 ret
= radeon_bo_map(rrb
->map_bo
, !!(mode
& GL_MAP_WRITE_BIT
));
199 map
= rrb
->map_bo
->ptr
;
203 *out_stride
= rrb
->map_pitch
;
205 *out_map
= map
+ (h
- 1) * rrb
->map_pitch
;
206 *out_stride
= -rrb
->map_pitch
;
211 /* sw fallback flush stuff */
212 if (radeon_bo_is_referenced_by_cs(rrb
->bo
, rmesa
->cmdbuf
.cs
)) {
213 radeon_firevertices(rmesa
);
216 #if defined(RADEON_R200)
217 if (rb
->Format
== MESA_FORMAT_S8_Z24
&& !rrb
->has_surface
) {
218 radeon_map_renderbuffer_s8z24(ctx
, rb
, x
, y
, w
, h
,
219 mode
, out_map
, out_stride
);
223 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
227 stride
= rrb
->map_pitch
;
230 y
= rb
->Height
- 1 - y
;
231 flip_stride
= -stride
;
233 flip_stride
= stride
;
234 map
+= rrb
->draw_offset
;
238 map
+= (int)y
* stride
;
241 *out_stride
= flip_stride
;
244 #if defined(RADEON_R200)
246 radeon_unmap_renderbuffer_s8z24(struct gl_context
*ctx
,
247 struct gl_renderbuffer
*rb
)
249 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
250 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
252 if (!rrb
->map_buffer
)
255 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
256 uint32_t *untiled_s8z24_map
= rrb
->map_buffer
;
257 uint32_t *tiled_s8z24_map
;
258 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
259 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
261 radeon_bo_map(rrb
->bo
, 1);
263 tiled_s8z24_map
= rrb
->bo
->ptr
;
265 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
266 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
267 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
268 uint32_t dst_offset
= r200_depth_4byte(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
269 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
270 tiled_s8z24_map
[dst_offset
/4] = untiled_s8z24_map
[src_offset
/4];
273 radeon_bo_unmap(rrb
->bo
);
275 free(rrb
->map_buffer
);
276 rrb
->map_buffer
= NULL
;
281 radeon_unmap_renderbuffer(struct gl_context
*ctx
,
282 struct gl_renderbuffer
*rb
)
284 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
285 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
289 if (rb
->Format
== MESA_FORMAT_S8_Z24
&& !rrb
->has_surface
) {
290 radeon_unmap_renderbuffer_s8z24(ctx
, rb
);
297 radeon_bo_unmap(rrb
->bo
);
301 radeon_bo_unmap(rrb
->map_bo
);
303 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
304 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->map_bo
, 0,
305 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
306 rrb
->map_w
, rrb
->map_h
,
308 rrb
->bo
, rrb
->draw_offset
,
309 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
310 rb
->Width
, rb
->Height
,
311 rrb
->map_x
, rrb
->map_y
,
312 rrb
->map_w
, rrb
->map_h
,
317 radeon_bo_unref(rrb
->map_bo
);
322 radeon_get_pointer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
325 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
333 * Called via glRenderbufferStorageEXT() to set the format and allocate
334 * storage for a user-created renderbuffer.
337 radeon_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
338 GLenum internalFormat
,
339 GLuint width
, GLuint height
)
341 struct radeon_context
*radeon
= RADEON_CONTEXT(ctx
);
342 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
343 uint32_t size
, pitch
;
346 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
350 ASSERT(rb
->Name
!= 0);
351 switch (internalFormat
) {
355 rb
->Format
= _radeon_texformat_rgb565
;
356 rb
->DataType
= GL_UNSIGNED_BYTE
;
364 rb
->Format
= _radeon_texformat_argb8888
;
365 rb
->DataType
= GL_UNSIGNED_BYTE
;
376 rb
->Format
= _radeon_texformat_argb8888
;
377 rb
->DataType
= GL_UNSIGNED_BYTE
;
380 case GL_STENCIL_INDEX
:
381 case GL_STENCIL_INDEX1_EXT
:
382 case GL_STENCIL_INDEX4_EXT
:
383 case GL_STENCIL_INDEX8_EXT
:
384 case GL_STENCIL_INDEX16_EXT
:
385 /* alloc a depth+stencil buffer */
386 rb
->Format
= MESA_FORMAT_S8_Z24
;
387 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
390 case GL_DEPTH_COMPONENT16
:
391 rb
->Format
= MESA_FORMAT_Z16
;
392 rb
->DataType
= GL_UNSIGNED_SHORT
;
395 case GL_DEPTH_COMPONENT
:
396 case GL_DEPTH_COMPONENT24
:
397 case GL_DEPTH_COMPONENT32
:
398 rb
->Format
= MESA_FORMAT_X8_Z24
;
399 rb
->DataType
= GL_UNSIGNED_INT
;
402 case GL_DEPTH_STENCIL_EXT
:
403 case GL_DEPTH24_STENCIL8_EXT
:
404 rb
->Format
= MESA_FORMAT_S8_Z24
;
405 rb
->DataType
= GL_UNSIGNED_INT_24_8_EXT
;
410 "Unexpected format in radeon_alloc_renderbuffer_storage");
414 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
416 if (ctx
->Driver
.Flush
)
417 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
420 radeon_bo_unref(rrb
->bo
);
422 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
;
424 if (RADEON_DEBUG
& RADEON_MEMORY
)
425 fprintf(stderr
,"Allocating %d x %d radeon RBO (pitch %d)\n", width
,
428 size
= pitch
* height
* cpp
;
429 rrb
->pitch
= pitch
* cpp
;
431 rrb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
435 RADEON_GEM_DOMAIN_VRAM
,
442 #if FEATURE_OES_EGL_image
444 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
445 struct gl_renderbuffer
*rb
,
448 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
449 struct radeon_renderbuffer
*rrb
;
453 screen
= radeon
->radeonScreen
->driScreen
;
454 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
455 screen
->loaderPrivate
);
459 rrb
= radeon_renderbuffer(rb
);
461 if (ctx
->Driver
.Flush
)
462 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
465 radeon_bo_unref(rrb
->bo
);
467 radeon_bo_ref(rrb
->bo
);
468 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
469 image
->width
, image
->pitch
);
471 rrb
->cpp
= image
->cpp
;
472 rrb
->pitch
= image
->pitch
* image
->cpp
;
474 rb
->Format
= image
->format
;
475 rb
->InternalFormat
= image
->internal_format
;
476 rb
->Width
= image
->width
;
477 rb
->Height
= image
->height
;
478 rb
->Format
= image
->format
;
479 rb
->DataType
= image
->data_type
;
480 rb
->_BaseFormat
= _mesa_base_fbo_format(radeon
->glCtx
,
481 image
->internal_format
);
486 * Called for each hardware renderbuffer when a _window_ is resized.
487 * Just update fields.
488 * Not used for user-created renderbuffers!
491 radeon_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
492 GLenum internalFormat
, GLuint width
, GLuint height
)
494 ASSERT(rb
->Name
== 0);
497 rb
->InternalFormat
= internalFormat
;
498 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
508 radeon_resize_buffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
509 GLuint width
, GLuint height
)
511 struct radeon_framebuffer
*radeon_fb
= (struct radeon_framebuffer
*)fb
;
514 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
518 _mesa_resize_framebuffer(ctx
, fb
, width
, height
);
520 fb
->Initialized
= GL_TRUE
; /* XXX remove someday */
526 /* Make sure all window system renderbuffers are up to date */
527 for (i
= 0; i
< 2; i
++) {
528 struct gl_renderbuffer
*rb
= &radeon_fb
->color_rb
[i
]->base
;
530 /* only resize if size is changing */
531 if (rb
&& (rb
->Width
!= width
|| rb
->Height
!= height
)) {
532 rb
->AllocStorage(ctx
, rb
, rb
->InternalFormat
, width
, height
);
538 /** Dummy function for gl_renderbuffer::AllocStorage() */
540 radeon_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
541 GLenum internalFormat
, GLuint width
, GLuint height
)
543 _mesa_problem(ctx
, "radeon_op_alloc_storage should never be called.");
549 * Create a renderbuffer for a window's color, depth and/or stencil buffer.
550 * Not used for user-created renderbuffers.
552 struct radeon_renderbuffer
*
553 radeon_create_renderbuffer(gl_format format
, __DRIdrawable
*driDrawPriv
)
555 struct radeon_renderbuffer
*rrb
;
557 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
559 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
566 _mesa_init_renderbuffer(&rrb
->base
, 0);
567 rrb
->base
.ClassID
= RADEON_RB_CLASS
;
569 rrb
->base
.Format
= format
;
572 case MESA_FORMAT_RGB565
:
573 assert(_mesa_little_endian());
574 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
576 case MESA_FORMAT_RGB565_REV
:
577 assert(!_mesa_little_endian());
578 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
580 case MESA_FORMAT_XRGB8888
:
581 assert(_mesa_little_endian());
582 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
584 case MESA_FORMAT_XRGB8888_REV
:
585 assert(!_mesa_little_endian());
586 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
588 case MESA_FORMAT_ARGB8888
:
589 assert(_mesa_little_endian());
590 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
592 case MESA_FORMAT_ARGB8888_REV
:
593 assert(!_mesa_little_endian());
594 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
597 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
599 case MESA_FORMAT_Z16
:
600 rrb
->base
.DataType
= GL_UNSIGNED_SHORT
;
602 case MESA_FORMAT_X8_Z24
:
603 rrb
->base
.DataType
= GL_UNSIGNED_INT
;
605 case MESA_FORMAT_S8_Z24
:
606 rrb
->base
.DataType
= GL_UNSIGNED_INT_24_8_EXT
;
609 fprintf(stderr
, "%s: Unknown format %s\n",
610 __FUNCTION__
, _mesa_get_format_name(format
));
611 _mesa_delete_renderbuffer(&rrb
->base
);
614 rrb
->base
._BaseFormat
= _mesa_get_format_base_format(format
);
616 rrb
->dPriv
= driDrawPriv
;
617 rrb
->base
.InternalFormat
= _mesa_get_format_base_format(format
);
619 rrb
->base
.Delete
= radeon_delete_renderbuffer
;
620 rrb
->base
.AllocStorage
= radeon_alloc_window_storage
;
621 rrb
->base
.GetPointer
= radeon_get_pointer
;
627 static struct gl_renderbuffer
*
628 radeon_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
630 struct radeon_renderbuffer
*rrb
;
632 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
634 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
641 _mesa_init_renderbuffer(&rrb
->base
, name
);
642 rrb
->base
.ClassID
= RADEON_RB_CLASS
;
644 rrb
->base
.Delete
= radeon_delete_renderbuffer
;
645 rrb
->base
.AllocStorage
= radeon_alloc_renderbuffer_storage
;
646 rrb
->base
.GetPointer
= radeon_get_pointer
;
652 radeon_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
653 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
655 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
656 "%s(%p, fb %p, target %s) \n",
658 _mesa_lookup_enum_by_nr(target
));
660 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
661 radeon_draw_buffer(ctx
, fb
);
664 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
669 radeon_framebuffer_renderbuffer(struct gl_context
* ctx
,
670 struct gl_framebuffer
*fb
,
671 GLenum attachment
, struct gl_renderbuffer
*rb
)
674 if (ctx
->Driver
.Flush
)
675 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
677 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
678 "%s(%p, fb %p, rb %p) \n",
679 __func__
, ctx
, fb
, rb
);
681 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
682 radeon_draw_buffer(ctx
, fb
);
686 radeon_update_wrapper(struct gl_context
*ctx
, struct radeon_renderbuffer
*rrb
,
687 struct gl_texture_image
*texImage
)
689 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
690 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
691 __func__
, ctx
, rrb
, texImage
, _mesa_get_format_name(texImage
->TexFormat
));
693 switch (texImage
->TexFormat
) {
694 case MESA_FORMAT_RGBA8888
:
695 case MESA_FORMAT_RGBA8888_REV
:
696 case MESA_FORMAT_ARGB8888
:
697 case MESA_FORMAT_ARGB8888_REV
:
698 case MESA_FORMAT_XRGB8888
:
699 case MESA_FORMAT_XRGB8888_REV
:
700 case MESA_FORMAT_RGB565
:
701 case MESA_FORMAT_RGB565_REV
:
702 case MESA_FORMAT_RGBA5551
:
703 case MESA_FORMAT_ARGB1555
:
704 case MESA_FORMAT_ARGB1555_REV
:
705 case MESA_FORMAT_ARGB4444
:
706 case MESA_FORMAT_ARGB4444_REV
:
707 rrb
->base
.DataType
= GL_UNSIGNED_BYTE
;
709 case MESA_FORMAT_Z16
:
710 rrb
->base
.DataType
= GL_UNSIGNED_SHORT
;
712 case MESA_FORMAT_X8_Z24
:
713 rrb
->base
.DataType
= GL_UNSIGNED_INT
;
715 case MESA_FORMAT_S8_Z24
:
716 rrb
->base
.DataType
= GL_UNSIGNED_INT_24_8_EXT
;
719 _mesa_problem(ctx
, "Unexpected texture format in radeon_update_wrapper()");
722 rrb
->cpp
= _mesa_get_format_bytes(texImage
->TexFormat
);
723 rrb
->pitch
= texImage
->Width
* rrb
->cpp
;
724 rrb
->base
.Format
= texImage
->TexFormat
;
725 rrb
->base
.InternalFormat
= texImage
->InternalFormat
;
726 rrb
->base
._BaseFormat
= _mesa_base_fbo_format(ctx
, rrb
->base
.InternalFormat
);
727 rrb
->base
.Width
= texImage
->Width
;
728 rrb
->base
.Height
= texImage
->Height
;
729 rrb
->base
.Delete
= radeon_delete_renderbuffer
;
730 rrb
->base
.AllocStorage
= radeon_nop_alloc_storage
;
736 static struct radeon_renderbuffer
*
737 radeon_wrap_texture(struct gl_context
* ctx
, struct gl_texture_image
*texImage
)
739 const GLuint name
= ~0; /* not significant, but distinct for debugging */
740 struct radeon_renderbuffer
*rrb
;
742 /* make an radeon_renderbuffer to wrap the texture image */
743 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
745 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
746 "%s(%p, rrb %p, texImage %p) \n",
747 __func__
, ctx
, rrb
, texImage
);
750 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glFramebufferTexture");
754 _mesa_init_renderbuffer(&rrb
->base
, name
);
755 rrb
->base
.ClassID
= RADEON_RB_CLASS
;
757 if (!radeon_update_wrapper(ctx
, rrb
, texImage
)) {
766 radeon_render_texture(struct gl_context
* ctx
,
767 struct gl_framebuffer
*fb
,
768 struct gl_renderbuffer_attachment
*att
)
770 struct gl_texture_image
*newImage
771 = att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
772 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(att
->Renderbuffer
);
773 radeon_texture_image
*radeon_image
;
776 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
777 "%s(%p, fb %p, rrb %p, att %p)\n",
778 __func__
, ctx
, fb
, rrb
, att
);
784 radeon_image
= (radeon_texture_image
*)newImage
;
786 if (!radeon_image
->mt
) {
787 /* Fallback on drawing to a texture without a miptree.
789 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
790 _swrast_render_texture(ctx
, fb
, att
);
794 rrb
= radeon_wrap_texture(ctx
, newImage
);
796 /* bind the wrapper to the attachment point */
797 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &rrb
->base
);
800 /* fallback to software rendering */
801 _swrast_render_texture(ctx
, fb
, att
);
806 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
807 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
808 _swrast_render_texture(ctx
, fb
, att
);
812 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
814 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
817 /* point the renderbufer's region to the texture image region */
818 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
820 radeon_bo_unref(rrb
->bo
);
821 rrb
->bo
= radeon_image
->mt
->bo
;
822 radeon_bo_ref(rrb
->bo
);
825 /* compute offset of the particular 2D image within the texture region */
826 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
830 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
831 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
832 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
836 /* store that offset in the region, along with the correct pitch for
837 * the image we are rendering to */
838 rrb
->draw_offset
= imageOffset
;
839 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
840 radeon_image
->used_as_render_target
= GL_TRUE
;
842 /* update drawing region, etc */
843 radeon_draw_buffer(ctx
, fb
);
847 radeon_finish_render_texture(struct gl_context
* ctx
,
848 struct gl_renderbuffer_attachment
*att
)
850 struct gl_texture_object
*tex_obj
= att
->Texture
;
851 struct gl_texture_image
*image
=
852 tex_obj
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
853 radeon_texture_image
*radeon_image
= (radeon_texture_image
*)image
;
856 radeon_image
->used_as_render_target
= GL_FALSE
;
858 if (ctx
->Driver
.Flush
)
859 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
862 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
864 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
865 gl_format mesa_format
;
868 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
869 struct gl_renderbuffer_attachment
*att
;
871 att
= &fb
->Attachment
[BUFFER_DEPTH
];
872 } else if (i
== -1) {
873 att
= &fb
->Attachment
[BUFFER_STENCIL
];
875 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
878 if (att
->Type
== GL_TEXTURE
) {
879 mesa_format
= att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
]->TexFormat
;
881 /* All renderbuffer formats are renderable, but not sampable */
885 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
886 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
887 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
888 "%s: HW doesn't support format %s as output format of attachment %d\n",
889 __FUNCTION__
, _mesa_get_format_name(mesa_format
), i
);
895 void radeon_fbo_init(struct radeon_context
*radeon
)
897 #if FEATURE_EXT_framebuffer_object
898 radeon
->glCtx
->Driver
.NewFramebuffer
= radeon_new_framebuffer
;
899 radeon
->glCtx
->Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
900 radeon
->glCtx
->Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
901 radeon
->glCtx
->Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
902 radeon
->glCtx
->Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
903 radeon
->glCtx
->Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
904 radeon
->glCtx
->Driver
.RenderTexture
= radeon_render_texture
;
905 radeon
->glCtx
->Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
906 radeon
->glCtx
->Driver
.ResizeBuffers
= radeon_resize_buffers
;
907 radeon
->glCtx
->Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
909 #if FEATURE_EXT_framebuffer_blit
910 radeon
->glCtx
->Driver
.BlitFramebuffer
= _mesa_meta_BlitFramebuffer
;
912 #if FEATURE_OES_EGL_image
913 radeon
->glCtx
->Driver
.EGLImageTargetRenderbufferStorage
=
914 radeon_image_target_renderbuffer_storage
;
919 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
920 struct radeon_bo
*bo
)
922 struct radeon_bo
*old
;
927 radeon_bo_unref(old
);