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__); \
50 radeon_delete_renderbuffer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
52 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
54 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
55 "%s(rb %p, rrb %p) \n",
61 radeon_bo_unref(rrb
->bo
);
63 _mesa_delete_renderbuffer(ctx
, rb
);
66 #if defined(RADEON_R100)
67 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
70 GLuint ba
, address
= 0;
72 ba
= (y
>> 4) * (rrb
->pitch
>> 6) + (x
>> 4);
74 address
|= (x
& 0x7) << 2;
75 address
|= (y
& 0x3) << 5;
76 address
|= (((x
& 0x10) >> 2) ^ (y
& 0x4)) << 5;
77 address
|= (ba
& 3) << 8;
78 address
|= (y
& 0x8) << 7;
79 address
|= (((x
& 0x8) << 1) ^ (y
& 0x10)) << 7;
80 address
|= (ba
& ~0x3) << 10;
84 static GLuint
get_depth_z16(const struct radeon_renderbuffer
* rrb
,
87 GLuint ba
, address
= 0; /* a[0] = 0 */
89 ba
= (y
/ 16) * (rrb
->pitch
>> 6) + (x
/ 32);
91 address
|= (x
& 0x7) << 1; /* a[1..3] = x[0..2] */
92 address
|= (y
& 0x7) << 4; /* a[4..6] = y[0..2] */
93 address
|= (x
& 0x8) << 4; /* a[7] = x[3] */
94 address
|= (ba
& 0x3) << 8; /* a[8..9] = ba[0..1] */
95 address
|= (y
& 0x8) << 7; /* a[10] = y[3] */
96 address
|= ((x
& 0x10) ^ (y
& 0x10)) << 7;/* a[11] = x[4] ^ y[4] */
97 address
|= (ba
& ~0x3) << 10; /* a[12..] = ba[2..] */
102 #if defined(RADEON_R200)
103 static GLuint
get_depth_z32(const struct radeon_renderbuffer
* rrb
,
109 b
= (((y
& 0x7ff) >> 4) * (rrb
->pitch
>> 7) + (x
>> 5));
110 offset
+= (b
>> 1) << 12;
111 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
112 offset
+= ((y
>> 2) & 0x3) << 9;
113 offset
+= ((x
>> 2) & 0x1) << 8;
114 offset
+= ((x
>> 3) & 0x3) << 6;
115 offset
+= ((y
>> 1) & 0x1) << 5;
116 offset
+= ((x
>> 1) & 0x1) << 4;
117 offset
+= (y
& 0x1) << 3;
118 offset
+= (x
& 0x1) << 2;
123 static GLuint
get_depth_z16(const struct radeon_renderbuffer
*rrb
,
130 b
= (((y
>> 4) * (rrb
->pitch
>> 7) + (x
>> 6)));
131 offset
+= (b
>> 1) << 12;
132 offset
+= (((rrb
->pitch
>> 7) & 0x1) ? (b
& 0x1) : ((b
& 0x1) ^ ((y
>> 4) & 0x1))) << 11;
133 offset
+= ((y
>> 2) & 0x3) << 9;
134 offset
+= ((x
>> 3) & 0x1) << 8;
135 offset
+= ((x
>> 4) & 0x3) << 6;
136 offset
+= ((x
>> 2) & 0x1) << 5;
137 offset
+= ((y
>> 1) & 0x1) << 4;
138 offset
+= ((x
>> 1) & 0x1) << 3;
139 offset
+= (y
& 0x1) << 2;
140 offset
+= (x
& 0x1) << 1;
147 radeon_map_renderbuffer_s8z24(struct gl_context
*ctx
,
148 struct gl_renderbuffer
*rb
,
149 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
154 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
155 uint32_t *untiled_s8z24_map
, *tiled_s8z24_map
;
157 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
158 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
159 uint32_t pitch
= w
* rrb
->cpp
;
161 rrb
->map_pitch
= pitch
;
163 rrb
->map_buffer
= malloc(w
* h
* 4);
164 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
167 untiled_s8z24_map
= rrb
->map_buffer
;
168 tiled_s8z24_map
= rrb
->bo
->ptr
;
170 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
171 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
172 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
173 uint32_t src_offset
= get_depth_z32(rrb
, x
+ pix_x
, flipped_y
);
174 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
175 untiled_s8z24_map
[dst_offset
/4] = tiled_s8z24_map
[src_offset
/4];
179 radeon_bo_unmap(rrb
->bo
);
181 *out_map
= rrb
->map_buffer
;
182 *out_stride
= rrb
->map_pitch
;
186 radeon_map_renderbuffer_z16(struct gl_context
*ctx
,
187 struct gl_renderbuffer
*rb
,
188 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
193 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
194 uint16_t *untiled_z16_map
, *tiled_z16_map
;
196 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
197 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
198 uint32_t pitch
= w
* rrb
->cpp
;
200 rrb
->map_pitch
= pitch
;
202 rrb
->map_buffer
= malloc(w
* h
* 2);
203 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
207 untiled_z16_map
= rrb
->map_buffer
;
208 tiled_z16_map
= rrb
->bo
->ptr
;
210 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
211 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
212 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
213 uint32_t src_offset
= get_depth_z16(rrb
, x
+ pix_x
, flipped_y
);
214 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
215 untiled_z16_map
[dst_offset
/2] = tiled_z16_map
[src_offset
/2];
219 radeon_bo_unmap(rrb
->bo
);
221 *out_map
= rrb
->map_buffer
;
222 *out_stride
= rrb
->map_pitch
;
226 radeon_map_renderbuffer(struct gl_context
*ctx
,
227 struct gl_renderbuffer
*rb
,
228 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
233 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
234 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
237 int stride
, flip_stride
;
241 if (!rrb
|| !rrb
->bo
) {
247 rrb
->map_mode
= mode
;
252 rrb
->map_pitch
= rrb
->pitch
;
254 ok
= rmesa
->vtbl
.check_blit(rb
->Format
, rrb
->pitch
/ rrb
->cpp
);
261 src_y
= rrb
->base
.Base
.Height
- y
- h
;
264 /* Make a temporary buffer and blit the current contents of the renderbuffer
265 * out to it. This gives us linear access to the buffer, instead of having
266 * to do detiling in software.
269 rrb
->map_pitch
= rrb
->pitch
;
271 assert(!rrb
->map_bo
);
272 rrb
->map_bo
= radeon_bo_open(rmesa
->radeonScreen
->bom
, 0,
273 rrb
->map_pitch
* h
, 4,
274 RADEON_GEM_DOMAIN_GTT
, 0);
276 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->bo
, rrb
->draw_offset
,
277 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
278 rb
->Width
, rb
->Height
,
281 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
288 ret
= radeon_bo_map(rrb
->map_bo
, !!(mode
& GL_MAP_WRITE_BIT
));
291 map
= rrb
->map_bo
->ptr
;
295 *out_stride
= rrb
->map_pitch
;
297 *out_map
= map
+ (h
- 1) * rrb
->map_pitch
;
298 *out_stride
= -rrb
->map_pitch
;
303 /* sw fallback flush stuff */
304 if (radeon_bo_is_referenced_by_cs(rrb
->bo
, rmesa
->cmdbuf
.cs
)) {
305 radeon_firevertices(rmesa
);
308 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
309 if (rb
->Format
== MESA_FORMAT_Z24_UNORM_S8_UINT
|| rb
->Format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) {
310 radeon_map_renderbuffer_s8z24(ctx
, rb
, x
, y
, w
, h
,
311 mode
, out_map
, out_stride
);
314 if (rb
->Format
== MESA_FORMAT_Z_UNORM16
) {
315 radeon_map_renderbuffer_z16(ctx
, rb
, x
, y
, w
, h
,
316 mode
, out_map
, out_stride
);
321 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
326 stride
= rrb
->map_pitch
;
329 y
= rb
->Height
- 1 - y
;
330 flip_stride
= -stride
;
332 flip_stride
= stride
;
333 map
+= rrb
->draw_offset
;
337 map
+= (int)y
* stride
;
340 *out_stride
= flip_stride
;
344 radeon_unmap_renderbuffer_s8z24(struct gl_context
*ctx
,
345 struct gl_renderbuffer
*rb
)
347 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
349 if (!rrb
->map_buffer
)
352 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
353 uint32_t *untiled_s8z24_map
= rrb
->map_buffer
;
354 uint32_t *tiled_s8z24_map
;
355 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
356 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
358 radeon_bo_map(rrb
->bo
, 1);
360 tiled_s8z24_map
= rrb
->bo
->ptr
;
362 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
363 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
364 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
365 uint32_t dst_offset
= get_depth_z32(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
366 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
367 tiled_s8z24_map
[dst_offset
/4] = untiled_s8z24_map
[src_offset
/4];
370 radeon_bo_unmap(rrb
->bo
);
372 free(rrb
->map_buffer
);
373 rrb
->map_buffer
= NULL
;
377 radeon_unmap_renderbuffer_z16(struct gl_context
*ctx
,
378 struct gl_renderbuffer
*rb
)
380 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
382 if (!rrb
->map_buffer
)
385 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
386 uint16_t *untiled_z16_map
= rrb
->map_buffer
;
387 uint16_t *tiled_z16_map
;
388 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
389 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
391 radeon_bo_map(rrb
->bo
, 1);
393 tiled_z16_map
= rrb
->bo
->ptr
;
395 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
396 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
397 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
398 uint32_t dst_offset
= get_depth_z16(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
399 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
400 tiled_z16_map
[dst_offset
/2] = untiled_z16_map
[src_offset
/2];
403 radeon_bo_unmap(rrb
->bo
);
405 free(rrb
->map_buffer
);
406 rrb
->map_buffer
= NULL
;
411 radeon_unmap_renderbuffer(struct gl_context
*ctx
,
412 struct gl_renderbuffer
*rb
)
414 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
415 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
417 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
418 if (rb
->Format
== MESA_FORMAT_Z24_UNORM_S8_UINT
|| rb
->Format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) {
419 radeon_unmap_renderbuffer_s8z24(ctx
, rb
);
422 if (rb
->Format
== MESA_FORMAT_Z_UNORM16
) {
423 radeon_unmap_renderbuffer_z16(ctx
, rb
);
430 radeon_bo_unmap(rrb
->bo
);
434 radeon_bo_unmap(rrb
->map_bo
);
436 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
438 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->map_bo
, 0,
439 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
440 rrb
->map_w
, rrb
->map_h
,
442 rrb
->bo
, rrb
->draw_offset
,
443 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
444 rb
->Width
, rb
->Height
,
445 rrb
->map_x
, rrb
->map_y
,
446 rrb
->map_w
, rrb
->map_h
,
452 radeon_bo_unref(rrb
->map_bo
);
458 * Called via glRenderbufferStorageEXT() to set the format and allocate
459 * storage for a user-created renderbuffer.
462 radeon_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
463 GLenum internalFormat
,
464 GLuint width
, GLuint height
)
466 struct radeon_context
*radeon
= RADEON_CONTEXT(ctx
);
467 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
468 uint32_t size
, pitch
;
471 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
475 assert(rb
->Name
!= 0);
476 switch (internalFormat
) {
480 rb
->Format
= _radeon_texformat_rgb565
;
488 rb
->Format
= _radeon_texformat_argb8888
;
499 rb
->Format
= _radeon_texformat_argb8888
;
502 case GL_STENCIL_INDEX
:
503 case GL_STENCIL_INDEX1_EXT
:
504 case GL_STENCIL_INDEX4_EXT
:
505 case GL_STENCIL_INDEX8_EXT
:
506 case GL_STENCIL_INDEX16_EXT
:
507 /* alloc a depth+stencil buffer */
508 rb
->Format
= MESA_FORMAT_Z24_UNORM_S8_UINT
;
511 case GL_DEPTH_COMPONENT16
:
512 rb
->Format
= MESA_FORMAT_Z_UNORM16
;
515 case GL_DEPTH_COMPONENT
:
516 case GL_DEPTH_COMPONENT24
:
517 case GL_DEPTH_COMPONENT32
:
518 rb
->Format
= MESA_FORMAT_Z24_UNORM_X8_UINT
;
521 case GL_DEPTH_STENCIL_EXT
:
522 case GL_DEPTH24_STENCIL8_EXT
:
523 rb
->Format
= MESA_FORMAT_Z24_UNORM_S8_UINT
;
528 "Unexpected format in radeon_alloc_renderbuffer_storage");
532 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
534 if (ctx
->Driver
.Flush
)
535 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
538 radeon_bo_unref(rrb
->bo
);
540 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
;
542 if (RADEON_DEBUG
& RADEON_MEMORY
)
543 fprintf(stderr
,"Allocating %d x %d radeon RBO (pitch %d)\n", width
,
546 size
= pitch
* height
* cpp
;
547 rrb
->pitch
= pitch
* cpp
;
549 rrb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
553 RADEON_GEM_DOMAIN_VRAM
,
561 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
562 struct gl_renderbuffer
*rb
,
565 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
566 struct radeon_renderbuffer
*rrb
;
570 screen
= radeon
->radeonScreen
->driScreen
;
571 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
572 screen
->loaderPrivate
);
576 rrb
= radeon_renderbuffer(rb
);
578 if (ctx
->Driver
.Flush
)
579 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
582 radeon_bo_unref(rrb
->bo
);
584 radeon_bo_ref(rrb
->bo
);
585 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
586 image
->width
, image
->pitch
);
588 rrb
->cpp
= image
->cpp
;
589 rrb
->pitch
= image
->pitch
* image
->cpp
;
591 rb
->Format
= image
->format
;
592 rb
->InternalFormat
= image
->internal_format
;
593 rb
->Width
= image
->width
;
594 rb
->Height
= image
->height
;
595 rb
->Format
= image
->format
;
596 rb
->_BaseFormat
= _mesa_base_fbo_format(&radeon
->glCtx
,
597 image
->internal_format
);
598 rb
->NeedsFinishRenderTexture
= GL_TRUE
;
602 * Called for each hardware renderbuffer when a _window_ is resized.
603 * Just update fields.
604 * Not used for user-created renderbuffers!
607 radeon_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
608 GLenum internalFormat
, GLuint width
, GLuint height
)
610 assert(rb
->Name
== 0);
613 rb
->InternalFormat
= internalFormat
;
614 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
622 /** Dummy function for gl_renderbuffer::AllocStorage() */
624 radeon_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
625 GLenum internalFormat
, GLuint width
, GLuint height
)
627 _mesa_problem(ctx
, "radeon_op_alloc_storage should never be called.");
633 * Create a renderbuffer for a window's color, depth and/or stencil buffer.
634 * Not used for user-created renderbuffers.
636 struct radeon_renderbuffer
*
637 radeon_create_renderbuffer(mesa_format format
, __DRIdrawable
*driDrawPriv
)
639 struct radeon_renderbuffer
*rrb
;
640 struct gl_renderbuffer
*rb
;
642 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
644 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
651 rb
= &rrb
->base
.Base
;
653 _mesa_init_renderbuffer(rb
, 0);
654 rb
->ClassID
= RADEON_RB_CLASS
;
656 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
657 rb
->InternalFormat
= _mesa_get_format_base_format(format
);
659 rrb
->dPriv
= driDrawPriv
;
661 rb
->Delete
= radeon_delete_renderbuffer
;
662 rb
->AllocStorage
= radeon_alloc_window_storage
;
668 static struct gl_renderbuffer
*
669 radeon_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
671 struct radeon_renderbuffer
*rrb
;
672 struct gl_renderbuffer
*rb
;
675 rrb
= CALLOC_STRUCT(radeon_renderbuffer
);
677 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
684 rb
= &rrb
->base
.Base
;
686 _mesa_init_renderbuffer(rb
, name
);
687 rb
->ClassID
= RADEON_RB_CLASS
;
688 rb
->Delete
= radeon_delete_renderbuffer
;
689 rb
->AllocStorage
= radeon_alloc_renderbuffer_storage
;
695 radeon_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
696 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
698 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
699 "%s(%p, fb %p, target %s) \n",
701 _mesa_enum_to_string(target
));
703 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
704 radeon_draw_buffer(ctx
, fb
);
707 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
712 radeon_framebuffer_renderbuffer(struct gl_context
* ctx
,
713 struct gl_framebuffer
*fb
,
714 GLenum attachment
, struct gl_renderbuffer
*rb
)
717 if (ctx
->Driver
.Flush
)
718 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
720 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
721 "%s(%p, fb %p, rb %p) \n",
722 __func__
, ctx
, fb
, rb
);
724 _mesa_FramebufferRenderbuffer_sw(ctx
, fb
, attachment
, rb
);
725 radeon_draw_buffer(ctx
, fb
);
729 radeon_update_wrapper(struct gl_context
*ctx
, struct radeon_renderbuffer
*rrb
,
730 struct gl_texture_image
*texImage
)
732 struct gl_renderbuffer
*rb
= &rrb
->base
.Base
;
734 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
735 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
736 __func__
, ctx
, rrb
, texImage
, _mesa_get_format_name(texImage
->TexFormat
));
738 rrb
->cpp
= _mesa_get_format_bytes(texImage
->TexFormat
);
739 rrb
->pitch
= texImage
->Width
* rrb
->cpp
;
740 rb
->Format
= texImage
->TexFormat
;
741 rb
->InternalFormat
= texImage
->InternalFormat
;
742 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, rb
->InternalFormat
);
743 rb
->Width
= texImage
->Width
;
744 rb
->Height
= texImage
->Height
;
745 rb
->Delete
= radeon_delete_renderbuffer
;
746 rb
->AllocStorage
= radeon_nop_alloc_storage
;
752 radeon_render_texture(struct gl_context
* ctx
,
753 struct gl_framebuffer
*fb
,
754 struct gl_renderbuffer_attachment
*att
)
756 struct gl_renderbuffer
*rb
= att
->Renderbuffer
;
757 struct gl_texture_image
*newImage
= rb
->TexImage
;
758 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
759 radeon_texture_image
*radeon_image
;
762 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
763 "%s(%p, fb %p, rrb %p, att %p)\n",
764 __func__
, ctx
, fb
, rrb
, att
);
770 radeon_image
= (radeon_texture_image
*)newImage
;
772 if (!radeon_image
->mt
) {
773 /* Fallback on drawing to a texture without a miptree.
775 _swrast_render_texture(ctx
, fb
, att
);
779 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
780 _swrast_render_texture(ctx
, fb
, att
);
784 DBG("Begin render texture tex=%u w=%d h=%d refcount=%d\n",
785 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
788 /* point the renderbufer's region to the texture image region */
789 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
791 radeon_bo_unref(rrb
->bo
);
792 rrb
->bo
= radeon_image
->mt
->bo
;
793 radeon_bo_ref(rrb
->bo
);
796 /* compute offset of the particular 2D image within the texture region */
797 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
801 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
802 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
803 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
807 /* store that offset in the region, along with the correct pitch for
808 * the image we are rendering to */
809 rrb
->draw_offset
= imageOffset
;
810 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
811 radeon_image
->used_as_render_target
= GL_TRUE
;
813 /* update drawing region, etc */
814 radeon_draw_buffer(ctx
, fb
);
818 radeon_finish_render_texture(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
820 struct gl_texture_image
*image
= rb
->TexImage
;
821 radeon_texture_image
*radeon_image
= (radeon_texture_image
*)image
;
824 radeon_image
->used_as_render_target
= GL_FALSE
;
826 if (ctx
->Driver
.Flush
)
827 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
830 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
832 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
833 mesa_format mesa_format
;
836 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
837 struct gl_renderbuffer_attachment
*att
;
839 att
= &fb
->Attachment
[BUFFER_DEPTH
];
840 } else if (i
== -1) {
841 att
= &fb
->Attachment
[BUFFER_STENCIL
];
843 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
846 if (att
->Type
== GL_TEXTURE
) {
847 mesa_format
= att
->Renderbuffer
->TexImage
->TexFormat
;
849 /* All renderbuffer formats are renderable, but not sampable */
853 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
854 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
855 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
856 "%s: HW doesn't support format %s as output format of attachment %d\n",
857 __func__
, _mesa_get_format_name(mesa_format
), i
);
863 void radeon_fbo_init(struct radeon_context
*radeon
)
865 radeon
->glCtx
.Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
866 radeon
->glCtx
.Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
867 radeon
->glCtx
.Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
868 radeon
->glCtx
.Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
869 radeon
->glCtx
.Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
870 radeon
->glCtx
.Driver
.RenderTexture
= radeon_render_texture
;
871 radeon
->glCtx
.Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
872 radeon
->glCtx
.Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
873 radeon
->glCtx
.Driver
.BlitFramebuffer
= _mesa_meta_and_swrast_BlitFramebuffer
;
874 radeon
->glCtx
.Driver
.EGLImageTargetRenderbufferStorage
=
875 radeon_image_target_renderbuffer_storage
;
879 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
880 struct radeon_bo
*bo
)
882 struct radeon_bo
*old
;
887 radeon_bo_unref(old
);