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/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
));
172 untiled_s8z24_map
= rrb
->map_buffer
;
173 tiled_s8z24_map
= rrb
->bo
->ptr
;
175 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
176 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
177 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
178 uint32_t src_offset
= get_depth_z32(rrb
, x
+ pix_x
, flipped_y
);
179 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
180 untiled_s8z24_map
[dst_offset
/4] = tiled_s8z24_map
[src_offset
/4];
184 radeon_bo_unmap(rrb
->bo
);
186 *out_map
= rrb
->map_buffer
;
187 *out_stride
= rrb
->map_pitch
;
191 radeon_map_renderbuffer_z16(struct gl_context
*ctx
,
192 struct gl_renderbuffer
*rb
,
193 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
198 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
199 uint16_t *untiled_z16_map
, *tiled_z16_map
;
201 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
202 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
203 uint32_t pitch
= w
* rrb
->cpp
;
205 rrb
->map_pitch
= pitch
;
207 rrb
->map_buffer
= malloc(w
* h
* 2);
208 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
211 untiled_z16_map
= rrb
->map_buffer
;
212 tiled_z16_map
= rrb
->bo
->ptr
;
214 for (uint32_t pix_y
= 0; pix_y
< h
; ++ pix_y
) {
215 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
216 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
217 uint32_t src_offset
= get_depth_z16(rrb
, x
+ pix_x
, flipped_y
);
218 uint32_t dst_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
219 untiled_z16_map
[dst_offset
/2] = tiled_z16_map
[src_offset
/2];
223 radeon_bo_unmap(rrb
->bo
);
225 *out_map
= rrb
->map_buffer
;
226 *out_stride
= rrb
->map_pitch
;
230 radeon_map_renderbuffer(struct gl_context
*ctx
,
231 struct gl_renderbuffer
*rb
,
232 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
237 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
238 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
241 int stride
, flip_stride
;
245 if (!rrb
|| !rrb
->bo
) {
251 rrb
->map_mode
= mode
;
256 rrb
->map_pitch
= rrb
->pitch
;
258 ok
= rmesa
->vtbl
.check_blit(rb
->Format
, rrb
->pitch
/ rrb
->cpp
);
265 src_y
= rrb
->base
.Base
.Height
- y
- h
;
268 /* Make a temporary buffer and blit the current contents of the renderbuffer
269 * out to it. This gives us linear access to the buffer, instead of having
270 * to do detiling in software.
273 rrb
->map_pitch
= rrb
->pitch
;
275 assert(!rrb
->map_bo
);
276 rrb
->map_bo
= radeon_bo_open(rmesa
->radeonScreen
->bom
, 0,
277 rrb
->map_pitch
* h
, 4,
278 RADEON_GEM_DOMAIN_GTT
, 0);
280 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->bo
, rrb
->draw_offset
,
281 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
282 rb
->Width
, rb
->Height
,
285 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
292 ret
= radeon_bo_map(rrb
->map_bo
, !!(mode
& GL_MAP_WRITE_BIT
));
295 map
= rrb
->map_bo
->ptr
;
299 *out_stride
= rrb
->map_pitch
;
301 *out_map
= map
+ (h
- 1) * rrb
->map_pitch
;
302 *out_stride
= -rrb
->map_pitch
;
307 /* sw fallback flush stuff */
308 if (radeon_bo_is_referenced_by_cs(rrb
->bo
, rmesa
->cmdbuf
.cs
)) {
309 radeon_firevertices(rmesa
);
312 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
313 if (rb
->Format
== MESA_FORMAT_S8_Z24
|| rb
->Format
== MESA_FORMAT_X8_Z24
) {
314 radeon_map_renderbuffer_s8z24(ctx
, rb
, x
, y
, w
, h
,
315 mode
, out_map
, out_stride
);
318 if (rb
->Format
== MESA_FORMAT_Z16
) {
319 radeon_map_renderbuffer_z16(ctx
, rb
, x
, y
, w
, h
,
320 mode
, out_map
, out_stride
);
325 ret
= radeon_bo_map(rrb
->bo
, !!(mode
& GL_MAP_WRITE_BIT
));
329 stride
= rrb
->map_pitch
;
332 y
= rb
->Height
- 1 - y
;
333 flip_stride
= -stride
;
335 flip_stride
= stride
;
336 map
+= rrb
->draw_offset
;
340 map
+= (int)y
* stride
;
343 *out_stride
= flip_stride
;
347 radeon_unmap_renderbuffer_s8z24(struct gl_context
*ctx
,
348 struct gl_renderbuffer
*rb
)
350 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
352 if (!rrb
->map_buffer
)
355 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
356 uint32_t *untiled_s8z24_map
= rrb
->map_buffer
;
357 uint32_t *tiled_s8z24_map
;
358 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
359 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
361 radeon_bo_map(rrb
->bo
, 1);
363 tiled_s8z24_map
= rrb
->bo
->ptr
;
365 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
366 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
367 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
368 uint32_t dst_offset
= get_depth_z32(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
369 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
370 tiled_s8z24_map
[dst_offset
/4] = untiled_s8z24_map
[src_offset
/4];
373 radeon_bo_unmap(rrb
->bo
);
375 free(rrb
->map_buffer
);
376 rrb
->map_buffer
= NULL
;
380 radeon_unmap_renderbuffer_z16(struct gl_context
*ctx
,
381 struct gl_renderbuffer
*rb
)
383 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
385 if (!rrb
->map_buffer
)
388 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
389 uint16_t *untiled_z16_map
= rrb
->map_buffer
;
390 uint16_t *tiled_z16_map
;
391 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
392 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
394 radeon_bo_map(rrb
->bo
, 1);
396 tiled_z16_map
= rrb
->bo
->ptr
;
398 for (uint32_t pix_y
= 0; pix_y
< rrb
->map_h
; pix_y
++) {
399 for (uint32_t pix_x
= 0; pix_x
< rrb
->map_w
; pix_x
++) {
400 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ rrb
->map_y
) + y_bias
;
401 uint32_t dst_offset
= get_depth_z16(rrb
, rrb
->map_x
+ pix_x
, flipped_y
);
402 uint32_t src_offset
= pix_y
* rrb
->map_pitch
+ pix_x
* rrb
->cpp
;
403 tiled_z16_map
[dst_offset
/2] = untiled_z16_map
[src_offset
/2];
406 radeon_bo_unmap(rrb
->bo
);
408 free(rrb
->map_buffer
);
409 rrb
->map_buffer
= NULL
;
414 radeon_unmap_renderbuffer(struct gl_context
*ctx
,
415 struct gl_renderbuffer
*rb
)
417 struct radeon_context
*const rmesa
= RADEON_CONTEXT(ctx
);
418 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
421 if ((rmesa
->radeonScreen
->chip_flags
& RADEON_CHIPSET_DEPTH_ALWAYS_TILED
) && !rrb
->has_surface
) {
422 if (rb
->Format
== MESA_FORMAT_S8_Z24
|| rb
->Format
== MESA_FORMAT_X8_Z24
) {
423 radeon_unmap_renderbuffer_s8z24(ctx
, rb
);
426 if (rb
->Format
== MESA_FORMAT_Z16
) {
427 radeon_unmap_renderbuffer_z16(ctx
, rb
);
434 radeon_bo_unmap(rrb
->bo
);
438 radeon_bo_unmap(rrb
->map_bo
);
440 if (rrb
->map_mode
& GL_MAP_WRITE_BIT
) {
441 ok
= rmesa
->vtbl
.blit(ctx
, rrb
->map_bo
, 0,
442 rb
->Format
, rrb
->map_pitch
/ rrb
->cpp
,
443 rrb
->map_w
, rrb
->map_h
,
445 rrb
->bo
, rrb
->draw_offset
,
446 rb
->Format
, rrb
->pitch
/ rrb
->cpp
,
447 rb
->Width
, rb
->Height
,
448 rrb
->map_x
, rrb
->map_y
,
449 rrb
->map_w
, rrb
->map_h
,
454 radeon_bo_unref(rrb
->map_bo
);
460 * Called via glRenderbufferStorageEXT() to set the format and allocate
461 * storage for a user-created renderbuffer.
464 radeon_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
465 GLenum internalFormat
,
466 GLuint width
, GLuint height
)
468 struct radeon_context
*radeon
= RADEON_CONTEXT(ctx
);
469 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
470 uint32_t size
, pitch
;
473 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
477 ASSERT(rb
->Name
!= 0);
478 switch (internalFormat
) {
482 rb
->Format
= _radeon_texformat_rgb565
;
490 rb
->Format
= _radeon_texformat_argb8888
;
501 rb
->Format
= _radeon_texformat_argb8888
;
504 case GL_STENCIL_INDEX
:
505 case GL_STENCIL_INDEX1_EXT
:
506 case GL_STENCIL_INDEX4_EXT
:
507 case GL_STENCIL_INDEX8_EXT
:
508 case GL_STENCIL_INDEX16_EXT
:
509 /* alloc a depth+stencil buffer */
510 rb
->Format
= MESA_FORMAT_S8_Z24
;
513 case GL_DEPTH_COMPONENT16
:
514 rb
->Format
= MESA_FORMAT_Z16
;
517 case GL_DEPTH_COMPONENT
:
518 case GL_DEPTH_COMPONENT24
:
519 case GL_DEPTH_COMPONENT32
:
520 rb
->Format
= MESA_FORMAT_X8_Z24
;
523 case GL_DEPTH_STENCIL_EXT
:
524 case GL_DEPTH24_STENCIL8_EXT
:
525 rb
->Format
= MESA_FORMAT_S8_Z24
;
530 "Unexpected format in radeon_alloc_renderbuffer_storage");
534 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
536 if (ctx
->Driver
.Flush
)
537 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
540 radeon_bo_unref(rrb
->bo
);
542 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
;
544 if (RADEON_DEBUG
& RADEON_MEMORY
)
545 fprintf(stderr
,"Allocating %d x %d radeon RBO (pitch %d)\n", width
,
548 size
= pitch
* height
* cpp
;
549 rrb
->pitch
= pitch
* cpp
;
551 rrb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
555 RADEON_GEM_DOMAIN_VRAM
,
563 radeon_image_target_renderbuffer_storage(struct gl_context
*ctx
,
564 struct gl_renderbuffer
*rb
,
567 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
568 struct radeon_renderbuffer
*rrb
;
572 screen
= radeon
->radeonScreen
->driScreen
;
573 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
574 screen
->loaderPrivate
);
578 rrb
= radeon_renderbuffer(rb
);
580 if (ctx
->Driver
.Flush
)
581 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
584 radeon_bo_unref(rrb
->bo
);
586 radeon_bo_ref(rrb
->bo
);
587 fprintf(stderr
, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image
->bo
, image
->bo
->handle
,
588 image
->width
, image
->pitch
);
590 rrb
->cpp
= image
->cpp
;
591 rrb
->pitch
= image
->pitch
* image
->cpp
;
593 rb
->Format
= image
->format
;
594 rb
->InternalFormat
= image
->internal_format
;
595 rb
->Width
= image
->width
;
596 rb
->Height
= image
->height
;
597 rb
->Format
= image
->format
;
598 rb
->_BaseFormat
= _mesa_base_fbo_format(&radeon
->glCtx
,
599 image
->internal_format
);
600 rb
->NeedsFinishRenderTexture
= GL_TRUE
;
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 _swrast_render_texture(ctx
, fb
, att
);
843 if (!radeon_update_wrapper(ctx
, rrb
, newImage
)) {
844 _swrast_render_texture(ctx
, fb
, att
);
848 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
850 att
->Texture
->Name
, newImage
->Width
, newImage
->Height
,
851 rrb
->base
.Base
.RefCount
);
853 /* point the renderbufer's region to the texture image region */
854 if (rrb
->bo
!= radeon_image
->mt
->bo
) {
856 radeon_bo_unref(rrb
->bo
);
857 rrb
->bo
= radeon_image
->mt
->bo
;
858 radeon_bo_ref(rrb
->bo
);
861 /* compute offset of the particular 2D image within the texture region */
862 imageOffset
= radeon_miptree_image_offset(radeon_image
->mt
,
866 if (att
->Texture
->Target
== GL_TEXTURE_3D
) {
867 imageOffset
+= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
*
868 radeon_image
->mt
->levels
[att
->TextureLevel
].height
*
872 /* store that offset in the region, along with the correct pitch for
873 * the image we are rendering to */
874 rrb
->draw_offset
= imageOffset
;
875 rrb
->pitch
= radeon_image
->mt
->levels
[att
->TextureLevel
].rowstride
;
876 radeon_image
->used_as_render_target
= GL_TRUE
;
878 /* update drawing region, etc */
879 radeon_draw_buffer(ctx
, fb
);
883 radeon_finish_render_texture(struct gl_context
* ctx
,
884 struct gl_renderbuffer_attachment
*att
)
886 struct gl_texture_object
*tex_obj
= att
->Texture
;
887 radeon_texture_image
*radeon_image
= NULL
;
890 radeon_image
= (radeon_texture_image
*)_mesa_get_attachment_teximage(att
);
893 radeon_image
->used_as_render_target
= GL_FALSE
;
895 if (ctx
->Driver
.Flush
)
896 ctx
->Driver
.Flush(ctx
); /* +r6/r7 */
899 radeon_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
901 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
902 gl_format mesa_format
;
905 for (i
= -2; i
< (GLint
) ctx
->Const
.MaxColorAttachments
; i
++) {
906 struct gl_renderbuffer_attachment
*att
;
908 att
= &fb
->Attachment
[BUFFER_DEPTH
];
909 } else if (i
== -1) {
910 att
= &fb
->Attachment
[BUFFER_STENCIL
];
912 att
= &fb
->Attachment
[BUFFER_COLOR0
+ i
];
915 if (att
->Type
== GL_TEXTURE
) {
916 mesa_format
= att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
]->TexFormat
;
918 /* All renderbuffer formats are renderable, but not sampable */
922 if (!radeon
->vtbl
.is_format_renderable(mesa_format
)){
923 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
924 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
925 "%s: HW doesn't support format %s as output format of attachment %d\n",
926 __FUNCTION__
, _mesa_get_format_name(mesa_format
), i
);
932 void radeon_fbo_init(struct radeon_context
*radeon
)
934 radeon
->glCtx
.Driver
.NewFramebuffer
= radeon_new_framebuffer
;
935 radeon
->glCtx
.Driver
.NewRenderbuffer
= radeon_new_renderbuffer
;
936 radeon
->glCtx
.Driver
.MapRenderbuffer
= radeon_map_renderbuffer
;
937 radeon
->glCtx
.Driver
.UnmapRenderbuffer
= radeon_unmap_renderbuffer
;
938 radeon
->glCtx
.Driver
.BindFramebuffer
= radeon_bind_framebuffer
;
939 radeon
->glCtx
.Driver
.FramebufferRenderbuffer
= radeon_framebuffer_renderbuffer
;
940 radeon
->glCtx
.Driver
.RenderTexture
= radeon_render_texture
;
941 radeon
->glCtx
.Driver
.FinishRenderTexture
= radeon_finish_render_texture
;
942 radeon
->glCtx
.Driver
.ResizeBuffers
= radeon_resize_buffers
;
943 radeon
->glCtx
.Driver
.ValidateFramebuffer
= radeon_validate_framebuffer
;
944 radeon
->glCtx
.Driver
.BlitFramebuffer
= _mesa_meta_BlitFramebuffer
;
945 radeon
->glCtx
.Driver
.EGLImageTargetRenderbufferStorage
=
946 radeon_image_target_renderbuffer_storage
;
950 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer
*rb
,
951 struct radeon_bo
*bo
)
953 struct radeon_bo
*old
;
958 radeon_bo_unref(old
);