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 VMWARE 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/mtypes.h"
32 #include "main/enums.h"
33 #include "main/fbobject.h"
34 #include "main/framebuffer.h"
35 #include "main/renderbuffer.h"
36 #include "main/context.h"
37 #include "swrast/swrast.h"
38 #include "drivers/common/meta.h"
40 #include "radeon_common.h"
41 #include "radeon_mipmap_tree.h"
43 #define FILE_DEBUG_FLAG RADEON_TEXTURE
44 #define DBG(...) do { \
45 if (RADEON_DEBUG & FILE_DEBUG_FLAG) \
46 printf(__VA_ARGS__); \
49 static struct gl_framebuffer
*
50 radeon_new_framebuffer(struct gl_context
*ctx
, GLuint name
)
52 return _mesa_new_framebuffer(ctx
, name
);
56 radeon_delete_renderbuffer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
58 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
60 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
61 "%s(rb %p, rrb %p) \n",
67 radeon_bo_unref(rrb
->bo
);
69 _mesa_delete_renderbuffer(ctx
, rb
);
72 #if defined(RADEON_R100)
73 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
76 GLuint ba
, address
= 0;
78 ba
= (y
>> 4) * (rrb
->pitch
>> 6) + (x
>> 4);
80 address
|= (x
& 0x7) << 2;
81 address
|= (y
& 0x3) << 5;
82 address
|= (((x
& 0x10) >> 2) ^ (y
& 0x4)) << 5;
83 address
|= (ba
& 3) << 8;
84 address
|= (y
& 0x8) << 7;
85 address
|= (((x
& 0x8) << 1) ^ (y
& 0x10)) << 7;
86 address
|= (ba
& ~0x3) << 10;
90 static GLuint
get_depth_z16(const struct radeon_renderbuffer
* rrb
,
93 GLuint ba
, address
= 0; /* a[0] = 0 */
95 ba
= (y
/ 16) * (rrb
->pitch
>> 6) + (x
/ 32);
97 address
|= (x
& 0x7) << 1; /* a[1..3] = x[0..2] */
98 address
|= (y
& 0x7) << 4; /* a[4..6] = y[0..2] */
99 address
|= (x
& 0x8) << 4; /* a[7] = x[3] */
100 address
|= (ba
& 0x3) << 8; /* a[8..9] = ba[0..1] */
101 address
|= (y
& 0x8) << 7; /* a[10] = y[3] */
102 address
|= ((x
& 0x10) ^ (y
& 0x10)) << 7;/* a[11] = x[4] ^ y[4] */
103 address
|= (ba
& ~0x3) << 10; /* a[12..] = ba[2..] */
108 #if defined(RADEON_R200)
109 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
115 b
= (((y
& 0x7ff) >> 4) * (rrb
->pitch
>> 7) + (x
>> 5));
116 offset
+= (b
>> 1) << 12;
117 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
118 offset
+= ((y
>> 2) & 0x3) << 9;
119 offset
+= ((x
>> 2) & 0x1) << 8;
120 offset
+= ((x
>> 3) & 0x3) << 6;
121 offset
+= ((y
>> 1) & 0x1) << 5;
122 offset
+= ((x
>> 1) & 0x1) << 4;
123 offset
+= (y
& 0x1) << 3;
124 offset
+= (x
& 0x1) << 2;
129 static GLuint
get_depth_z16(const struct radeon_renderbuffer
*rrb
,
136 b
= (((y
>> 4) * (rrb
->pitch
>> 7) + (x
>> 6)));
137 offset
+= (b
>> 1) << 12;
138 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
139 offset
+= ((y
>> 2) & 0x3) << 9;
140 offset
+= ((x
>> 3) & 0x1) << 8;
141 offset
+= ((x
>> 4) & 0x3) << 6;
142 offset
+= ((x
>> 2) & 0x1) << 5;
143 offset
+= ((y
>> 1) & 0x1) << 4;
144 offset
+= ((x
>> 1) & 0x1) << 3;
145 offset
+= (y
& 0x1) << 2;
146 offset
+= (x
& 0x1) << 1;
153 radeon_map_renderbuffer_s8z24(struct gl_context
*ctx
,
154 struct gl_renderbuffer
*rb
,
155 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
160 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
161 uint32_t *untiled_s8z24_map
, *tiled_s8z24_map
;
163 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
164 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
165 uint32_t pitch
= w
* rrb
->cpp
;
167 rrb
->map_pitch
= pitch
;
169 rrb
->map_buffer
= malloc(w
* h
* 4);
170 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
));
213 untiled_z16_map
= rrb
->map_buffer
;
214 tiled_z16_map
= rrb
->bo
->ptr
;
216 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
217 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
218 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
219 uint32_t src_offset
= get_depth_z16(rrb
, x
+ pix_x
, flipped_y
);
220 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
221 untiled_z16_map
[dst_offset
/2] = tiled_z16_map
[src_offset
/2];
225 radeon_bo_unmap(rrb
->bo
);
227 *out_map
= rrb
->map_buffer
;
228 *out_stride
= rrb
->map_pitch
;
232 radeon_map_renderbuffer(struct gl_context
*ctx
,
233 struct gl_renderbuffer
*rb
,
234 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
239 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
240 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
243 int stride
, flip_stride
;
247 if (!rrb
|| !rrb
->bo
) {
253 rrb
->map_mode
= mode
;
258 rrb
->map_pitch
= rrb
->pitch
;
260 ok
= rmesa
->vtbl
.check_blit(rb
->Format
, rrb
->pitch
/ rrb
->cpp
);
267 src_y
= rrb
->base
.Base
.Height
- y
- h
;
270 /* Make a temporary buffer and blit the current contents of the renderbuffer
271 * out to it. This gives us linear access to the buffer, instead of having
272 * to do detiling in software.
275 rrb
->map_pitch
= rrb
->pitch
;
277 assert(!rrb
->map_bo
);
278 rrb
->map_bo
= radeon_bo_open(rmesa
->radeonScreen
->bom
, 0,
279 rrb
->map_pitch
* h
, 4,
280 RADEON_GEM_DOMAIN_GTT
, 0);
282 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->bo
, rrb
->draw_offset
,
283 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
284 rb
->Width
, rb
->Height
,
287 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
294 ret
= radeon_bo_map(rrb
->map_bo
, !!(mode
& GL_MAP_WRITE_BIT
));
297 map
= rrb
->map_bo
->ptr
;
301 *out_stride
= rrb
->map_pitch
;
303 *out_map
= map
+ (h
- 1) * rrb
->map_pitch
;
304 *out_stride
= -rrb
->map_pitch
;
309 /* sw fallback flush stuff */
310 if (radeon_bo_is_referenced_by_cs(rrb
->bo
, rmesa
->cmdbuf
.cs
)) {
311 radeon_firevertices(rmesa
);
314 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
315 if (rb
->Format
== MESA_FORMAT_Z24_UNORM_S8_UINT
|| rb
->Format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) {
316 radeon_map_renderbuffer_s8z24(ctx
, rb
, x
, y
, w
, h
,
317 mode
, out_map
, out_stride
);
320 if (rb
->Format
== MESA_FORMAT_Z_UNORM16
) {
321 radeon_map_renderbuffer_z16(ctx
, rb
, x
, y
, w
, h
,
322 mode
, out_map
, out_stride
);
327 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
332 stride
= rrb
->map_pitch
;
335 y
= rb
->Height
- 1 - y
;
336 flip_stride
= -stride
;
338 flip_stride
= stride
;
339 map
+= rrb
->draw_offset
;
343 map
+= (int)y
* stride
;
346 *out_stride
= flip_stride
;
350 radeon_unmap_renderbuffer_s8z24(struct gl_context
*ctx
,
351 struct gl_renderbuffer
*rb
)
353 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
355 if (!rrb
->map_buffer
)
358 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
359 uint32_t *untiled_s8z24_map
= rrb
->map_buffer
;
360 uint32_t *tiled_s8z24_map
;
361 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
362 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
364 radeon_bo_map(rrb
->bo
, 1);
366 tiled_s8z24_map
= rrb
->bo
->ptr
;
368 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
369 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
370 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
371 uint32_t dst_offset
= get_depth_z32(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
372 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
373 tiled_s8z24_map
[dst_offset
/4] = untiled_s8z24_map
[src_offset
/4];
376 radeon_bo_unmap(rrb
->bo
);
378 free(rrb
->map_buffer
);
379 rrb
->map_buffer
= NULL
;
383 radeon_unmap_renderbuffer_z16(struct gl_context
*ctx
,
384 struct gl_renderbuffer
*rb
)
386 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
388 if (!rrb
->map_buffer
)
391 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
392 uint16_t *untiled_z16_map
= rrb
->map_buffer
;
393 uint16_t *tiled_z16_map
;
394 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
395 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
397 radeon_bo_map(rrb
->bo
, 1);
399 tiled_z16_map
= rrb
->bo
->ptr
;
401 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
402 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
403 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
404 uint32_t dst_offset
= get_depth_z16(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
405 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
406 tiled_z16_map
[dst_offset
/2] = untiled_z16_map
[src_offset
/2];
409 radeon_bo_unmap(rrb
->bo
);
411 free(rrb
->map_buffer
);
412 rrb
->map_buffer
= NULL
;
417 radeon_unmap_renderbuffer(struct gl_context
*ctx
,
418 struct gl_renderbuffer
*rb
)
420 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
421 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
423 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
424 if (rb
->Format
== MESA_FORMAT_Z24_UNORM_S8_UINT
|| rb
->Format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) {
425 radeon_unmap_renderbuffer_s8z24(ctx
, rb
);
428 if (rb
->Format
== MESA_FORMAT_Z_UNORM16
) {
429 radeon_unmap_renderbuffer_z16(ctx
, rb
);
436 radeon_bo_unmap(rrb
->bo
);
440 radeon_bo_unmap(rrb
->map_bo
);
442 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
444 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->map_bo
, 0,
445 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
446 rrb
->map_w
, rrb
->map_h
,
448 rrb
->bo
, rrb
->draw_offset
,
449 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
450 rb
->Width
, rb
->Height
,
451 rrb
->map_x
, rrb
->map_y
,
452 rrb
->map_w
, rrb
->map_h
,
458 radeon_bo_unref(rrb
->map_bo
);
464 * Called via glRenderbufferStorageEXT() to set the format and allocate
465 * storage for a user-created renderbuffer.
468 radeon_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
469 GLenum internalFormat
,
470 GLuint width
, GLuint height
)
472 struct radeon_context
*radeon
= RADEON_CONTEXT(ctx
);
473 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
474 uint32_t size
, pitch
;
477 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
481 assert(rb
->Name
!= 0);
482 switch (internalFormat
) {
486 rb
->Format
= _radeon_texformat_rgb565
;
494 rb
->Format
= _radeon_texformat_argb8888
;
505 rb
->Format
= _radeon_texformat_argb8888
;
508 case GL_STENCIL_INDEX
:
509 case GL_STENCIL_INDEX1_EXT
:
510 case GL_STENCIL_INDEX4_EXT
:
511 case GL_STENCIL_INDEX8_EXT
:
512 case GL_STENCIL_INDEX16_EXT
:
513 /* alloc a depth+stencil buffer */
514 rb
->Format
= MESA_FORMAT_Z24_UNORM_S8_UINT
;
517 case GL_DEPTH_COMPONENT16
:
518 rb
->Format
= MESA_FORMAT_Z_UNORM16
;
521 case GL_DEPTH_COMPONENT
:
522 case GL_DEPTH_COMPONENT24
:
523 case GL_DEPTH_COMPONENT32
:
524 rb
->Format
= MESA_FORMAT_Z24_UNORM_X8_UINT
;
527 case GL_DEPTH_STENCIL_EXT
:
528 case GL_DEPTH24_STENCIL8_EXT
:
529 rb
->Format
= MESA_FORMAT_Z24_UNORM_S8_UINT
;
534 "Unexpected format in radeon_alloc_renderbuffer_storage");
538 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
540 if (ctx
->Driver
.Flush
)
541 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
544 radeon_bo_unref(rrb
->bo
);
546 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
;
548 if (RADEON_DEBUG
& RADEON_MEMORY
)
549 fprintf(stderr
,"Allocating %d x %d radeon RBO (pitch %d)\n", width
,
552 size
= pitch
* height
* cpp
;
553 rrb
->pitch
= pitch
* cpp
;
555 rrb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
559 RADEON_GEM_DOMAIN_VRAM
,
567 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
568 struct gl_renderbuffer
*rb
,
571 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
572 struct radeon_renderbuffer
*rrb
;
576 screen
= radeon
->radeonScreen
->driScreen
;
577 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
578 screen
->loaderPrivate
);
582 rrb
= radeon_renderbuffer(rb
);
584 if (ctx
->Driver
.Flush
)
585 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
588 radeon_bo_unref(rrb
->bo
);
590 radeon_bo_ref(rrb
->bo
);
591 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
592 image
->width
, image
->pitch
);
594 rrb
->cpp
= image
->cpp
;
595 rrb
->pitch
= image
->pitch
* image
->cpp
;
597 rb
->Format
= image
->format
;
598 rb
->InternalFormat
= image
->internal_format
;
599 rb
->Width
= image
->width
;
600 rb
->Height
= image
->height
;
601 rb
->Format
= image
->format
;
602 rb
->_BaseFormat
= _mesa_base_fbo_format(&radeon
->glCtx
,
603 image
->internal_format
);
604 rb
->NeedsFinishRenderTexture
= GL_TRUE
;
608 * Called for each hardware renderbuffer when a _window_ is resized.
609 * Just update fields.
610 * Not used for user-created renderbuffers!
613 radeon_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
614 GLenum internalFormat
, GLuint width
, GLuint height
)
616 assert(rb
->Name
== 0);
619 rb
->InternalFormat
= internalFormat
;
620 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
628 /** Dummy function for gl_renderbuffer::AllocStorage() */
630 radeon_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
631 GLenum internalFormat
, GLuint width
, GLuint height
)
633 _mesa_problem(ctx
, "radeon_op_alloc_storage should never be called.");
639 * Create a renderbuffer for a window's color, depth and/or stencil buffer.
640 * Not used for user-created renderbuffers.
642 struct radeon_renderbuffer
*
643 radeon_create_renderbuffer(mesa_format format
, __DRIdrawable
*driDrawPriv
)
645 struct radeon_renderbuffer
*rrb
;
646 struct gl_renderbuffer
*rb
;
648 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
650 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
657 rb
= &rrb
->base
.Base
;
659 _mesa_init_renderbuffer(rb
, 0);
660 rb
->ClassID
= RADEON_RB_CLASS
;
662 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
663 rb
->InternalFormat
= _mesa_get_format_base_format(format
);
665 rrb
->dPriv
= driDrawPriv
;
667 rb
->Delete
= radeon_delete_renderbuffer
;
668 rb
->AllocStorage
= radeon_alloc_window_storage
;
674 static struct gl_renderbuffer
*
675 radeon_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
677 struct radeon_renderbuffer
*rrb
;
678 struct gl_renderbuffer
*rb
;
681 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
683 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
690 rb
= &rrb
->base
.Base
;
692 _mesa_init_renderbuffer(rb
, name
);
693 rb
->ClassID
= RADEON_RB_CLASS
;
694 rb
->Delete
= radeon_delete_renderbuffer
;
695 rb
->AllocStorage
= radeon_alloc_renderbuffer_storage
;
701 radeon_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
702 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
704 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
705 "%s(%p, fb %p, target %s) \n",
707 _mesa_enum_to_string(target
));
709 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
710 radeon_draw_buffer(ctx
, fb
);
713 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
718 radeon_framebuffer_renderbuffer(struct gl_context
* ctx
,
719 struct gl_framebuffer
*fb
,
720 GLenum attachment
, struct gl_renderbuffer
*rb
)
723 if (ctx
->Driver
.Flush
)
724 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
726 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
727 "%s(%p, fb %p, rb %p) \n",
728 __func__
, ctx
, fb
, rb
);
730 _mesa_FramebufferRenderbuffer_sw(ctx
, fb
, attachment
, rb
);
731 radeon_draw_buffer(ctx
, fb
);
735 radeon_update_wrapper(struct gl_context
*ctx
, struct radeon_renderbuffer
*rrb
,
736 struct gl_texture_image
*texImage
)
738 struct gl_renderbuffer
*rb
= &rrb
->base
.Base
;
740 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
741 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
742 __func__
, ctx
, rrb
, texImage
, _mesa_get_format_name(texImage
->TexFormat
));
744 rrb
->cpp
= _mesa_get_format_bytes(texImage
->TexFormat
);
745 rrb
->pitch
= texImage
->Width
* rrb
->cpp
;
746 rb
->Format
= texImage
->TexFormat
;
747 rb
->InternalFormat
= texImage
->InternalFormat
;
748 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, rb
->InternalFormat
);
749 rb
->Width
= texImage
->Width
;
750 rb
->Height
= texImage
->Height
;
751 rb
->Delete
= radeon_delete_renderbuffer
;
752 rb
->AllocStorage
= radeon_nop_alloc_storage
;
758 radeon_render_texture(struct gl_context
* ctx
,
759 struct gl_framebuffer
*fb
,
760 struct gl_renderbuffer_attachment
*att
)
762 struct gl_renderbuffer
*rb
= att
->Renderbuffer
;
763 struct gl_texture_image
*newImage
= rb
->TexImage
;
764 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
765 radeon_texture_image
*radeon_image
;
768 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
769 "%s(%p, fb %p, rrb %p, att %p)\n",
770 __func__
, ctx
, fb
, rrb
, att
);
776 radeon_image
= (radeon_texture_image
*)newImage
;
778 if (!radeon_image
->mt
) {
779 /* Fallback on drawing to a texture without a miptree.
781 _swrast_render_texture(ctx
, fb
, att
);
785 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
786 _swrast_render_texture(ctx
, fb
, att
);
790 DBG("Begin render texture tex=%u w=%d h=%d refcount=%d\n",
791 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
794 /* point the renderbufer's region to the texture image region */
795 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
797 radeon_bo_unref(rrb
->bo
);
798 rrb
->bo
= radeon_image
->mt
->bo
;
799 radeon_bo_ref(rrb
->bo
);
802 /* compute offset of the particular 2D image within the texture region */
803 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
807 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
808 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
809 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
813 /* store that offset in the region, along with the correct pitch for
814 * the image we are rendering to */
815 rrb
->draw_offset
= imageOffset
;
816 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
817 radeon_image
->used_as_render_target
= GL_TRUE
;
819 /* update drawing region, etc */
820 radeon_draw_buffer(ctx
, fb
);
824 radeon_finish_render_texture(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
826 struct gl_texture_image
*image
= rb
->TexImage
;
827 radeon_texture_image
*radeon_image
= (radeon_texture_image
*)image
;
830 radeon_image
->used_as_render_target
= GL_FALSE
;
832 if (ctx
->Driver
.Flush
)
833 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
836 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
838 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
839 mesa_format mesa_format
;
842 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
843 struct gl_renderbuffer_attachment
*att
;
845 att
= &fb
->Attachment
[BUFFER_DEPTH
];
846 } else if (i
== -1) {
847 att
= &fb
->Attachment
[BUFFER_STENCIL
];
849 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
852 if (att
->Type
== GL_TEXTURE
) {
853 mesa_format
= att
->Renderbuffer
->TexImage
->TexFormat
;
855 /* All renderbuffer formats are renderable, but not sampable */
859 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
860 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
861 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
862 "%s: HW doesn't support format %s as output format of attachment %d\n",
863 __func__
, _mesa_get_format_name(mesa_format
), i
);
869 void radeon_fbo_init(struct radeon_context
*radeon
)
871 radeon
->glCtx
.Driver
.NewFramebuffer
= radeon_new_framebuffer
;
872 radeon
->glCtx
.Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
873 radeon
->glCtx
.Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
874 radeon
->glCtx
.Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
875 radeon
->glCtx
.Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
876 radeon
->glCtx
.Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
877 radeon
->glCtx
.Driver
.RenderTexture
= radeon_render_texture
;
878 radeon
->glCtx
.Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
879 radeon
->glCtx
.Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
880 radeon
->glCtx
.Driver
.BlitFramebuffer
= _mesa_meta_and_swrast_BlitFramebuffer
;
881 radeon
->glCtx
.Driver
.EGLImageTargetRenderbufferStorage
=
882 radeon_image_target_renderbuffer_storage
;
886 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
887 struct radeon_bo
*bo
)
889 struct radeon_bo
*old
;
894 radeon_bo_unref(old
);