1 /**************************************************************************
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
37 #include "main/glheader.h"
38 #include "main/imports.h"
39 #include "main/context.h"
40 #include "main/api_arrayelt.h"
41 #include "main/enums.h"
42 #include "main/colormac.h"
43 #include "main/light.h"
44 #include "main/framebuffer.h"
46 #include "swrast/swrast.h"
49 #include "tnl/t_pipeline.h"
50 #include "swrast_setup/swrast_setup.h"
51 #include "main/mipmap.h"
52 #include "main/texformat.h"
53 #include "main/texstore.h"
54 #include "main/teximage.h"
55 #include "main/texobj.h"
57 #include "drirenderbuffer.h"
59 #include "xmlpool.h" /* for symbolic values of enum-type options */
61 #include "radeon_bo.h"
62 #include "radeon_cs.h"
63 #include "radeon_bo_legacy.h"
64 #include "radeon_cs_legacy.h"
65 #include "radeon_bo_gem.h"
66 #include "radeon_cs_gem.h"
68 #include "radeon_drm.h"
69 #include "radeon_buffer.h"
70 #include "radeon_screen.h"
71 #include "common_context.h"
72 #include "common_misc.h"
73 #include "common_lock.h"
74 #include "common_cmdbuf.h"
75 #include "radeon_mipmap_tree.h"
77 #define DRIVER_DATE "20090101"
80 int RADEON_DEBUG
= (0);
83 /* =============================================================
87 static GLboolean
intersect_rect(drm_clip_rect_t
* out
,
88 drm_clip_rect_t
* a
, drm_clip_rect_t
* b
)
99 if (out
->x1
>= out
->x2
)
101 if (out
->y1
>= out
->y2
)
106 void radeonRecalcScissorRects(radeonContextPtr radeon
)
108 drm_clip_rect_t
*out
;
111 /* Grow cliprect store?
113 if (radeon
->state
.scissor
.numAllocedClipRects
< radeon
->numClipRects
) {
114 while (radeon
->state
.scissor
.numAllocedClipRects
<
115 radeon
->numClipRects
) {
116 radeon
->state
.scissor
.numAllocedClipRects
+= 1; /* zero case */
117 radeon
->state
.scissor
.numAllocedClipRects
*= 2;
120 if (radeon
->state
.scissor
.pClipRects
)
121 FREE(radeon
->state
.scissor
.pClipRects
);
123 radeon
->state
.scissor
.pClipRects
=
124 MALLOC(radeon
->state
.scissor
.numAllocedClipRects
*
125 sizeof(drm_clip_rect_t
));
127 if (radeon
->state
.scissor
.pClipRects
== NULL
) {
128 radeon
->state
.scissor
.numAllocedClipRects
= 0;
133 out
= radeon
->state
.scissor
.pClipRects
;
134 radeon
->state
.scissor
.numClipRects
= 0;
136 for (i
= 0; i
< radeon
->numClipRects
; i
++) {
137 if (intersect_rect(out
,
138 &radeon
->pClipRects
[i
],
139 &radeon
->state
.scissor
.rect
)) {
140 radeon
->state
.scissor
.numClipRects
++;
147 * Update cliprects and scissors.
149 void radeonSetCliprects(radeonContextPtr radeon
)
151 __DRIdrawablePrivate
*const drawable
= radeon
->dri
.drawable
;
152 __DRIdrawablePrivate
*const readable
= radeon
->dri
.readable
;
153 GLframebuffer
*const draw_fb
= (GLframebuffer
*)drawable
->driverPrivate
;
154 GLframebuffer
*const read_fb
= (GLframebuffer
*)readable
->driverPrivate
;
156 if (!radeon
->radeonScreen
->driScreen
->dri2
.enabled
) {
157 if (draw_fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
158 /* Can't ignore 2d windows if we are page flipping. */
159 if (drawable
->numBackClipRects
== 0 || radeon
->doPageFlip
||
160 radeon
->sarea
->pfCurrentPage
== 1) {
161 radeon
->numClipRects
= drawable
->numClipRects
;
162 radeon
->pClipRects
= drawable
->pClipRects
;
164 radeon
->numClipRects
= drawable
->numBackClipRects
;
165 radeon
->pClipRects
= drawable
->pBackClipRects
;
168 /* front buffer (or none, or multiple buffers */
169 radeon
->numClipRects
= drawable
->numClipRects
;
170 radeon
->pClipRects
= drawable
->pClipRects
;
174 if ((draw_fb
->Width
!= drawable
->w
) ||
175 (draw_fb
->Height
!= drawable
->h
)) {
176 _mesa_resize_framebuffer(radeon
->glCtx
, draw_fb
,
177 drawable
->w
, drawable
->h
);
178 draw_fb
->Initialized
= GL_TRUE
;
181 if (drawable
!= readable
) {
182 if ((read_fb
->Width
!= readable
->w
) ||
183 (read_fb
->Height
!= readable
->h
)) {
184 _mesa_resize_framebuffer(radeon
->glCtx
, read_fb
,
185 readable
->w
, readable
->h
);
186 read_fb
->Initialized
= GL_TRUE
;
190 if (radeon
->state
.scissor
.enabled
)
191 radeonRecalcScissorRects(radeon
);
193 radeon
->lastStamp
= drawable
->lastStamp
;
196 void radeonUpdateScissor( GLcontext
*ctx
)
198 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
200 if ( rmesa
->dri
.drawable
) {
201 __DRIdrawablePrivate
*dPriv
= rmesa
->dri
.drawable
;
203 int x
= ctx
->Scissor
.X
;
204 int y
= dPriv
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
205 int w
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
206 int h
= dPriv
->h
- ctx
->Scissor
.Y
- 1;
208 rmesa
->state
.scissor
.rect
.x1
= x
+ dPriv
->x
;
209 rmesa
->state
.scissor
.rect
.y1
= y
+ dPriv
->y
;
210 rmesa
->state
.scissor
.rect
.x2
= w
+ dPriv
->x
+ 1;
211 rmesa
->state
.scissor
.rect
.y2
= h
+ dPriv
->y
+ 1;
213 radeonRecalcScissorRects( rmesa
);
217 /* ================================================================
218 * SwapBuffers with client-side throttling
221 static uint32_t radeonGetLastFrame(radeonContextPtr radeon
)
223 drm_radeon_getparam_t gp
;
227 gp
.param
= RADEON_PARAM_LAST_FRAME
;
228 gp
.value
= (int *)&frame
;
229 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
232 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
240 uint32_t radeonGetAge(radeonContextPtr radeon
)
242 drm_radeon_getparam_t gp
;
246 gp
.param
= RADEON_PARAM_LAST_CLEAR
;
247 gp
.value
= (int *)&age
;
248 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_GETPARAM
,
251 fprintf(stderr
, "%s: drmRadeonGetParam: %d\n", __FUNCTION__
,
259 static void radeonEmitIrqLocked(radeonContextPtr radeon
)
261 drm_radeon_irq_emit_t ie
;
264 ie
.irq_seq
= &radeon
->iw
.irq_seq
;
265 ret
= drmCommandWriteRead(radeon
->dri
.fd
, DRM_RADEON_IRQ_EMIT
,
268 fprintf(stderr
, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__
,
274 static void radeonWaitIrq(radeonContextPtr radeon
)
279 ret
= drmCommandWrite(radeon
->dri
.fd
, DRM_RADEON_IRQ_WAIT
,
280 &radeon
->iw
, sizeof(radeon
->iw
));
281 } while (ret
&& (errno
== EINTR
|| errno
== EBUSY
));
284 fprintf(stderr
, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__
,
290 static void radeonWaitForFrameCompletion(radeonContextPtr radeon
)
292 drm_radeon_sarea_t
*sarea
= radeon
->sarea
;
294 if (radeon
->do_irqs
) {
295 if (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
296 if (!radeon
->irqsEmitted
) {
297 while (radeonGetLastFrame(radeon
) <
300 UNLOCK_HARDWARE(radeon
);
301 radeonWaitIrq(radeon
);
302 LOCK_HARDWARE(radeon
);
304 radeon
->irqsEmitted
= 10;
307 if (radeon
->irqsEmitted
) {
308 radeonEmitIrqLocked(radeon
);
309 radeon
->irqsEmitted
--;
312 while (radeonGetLastFrame(radeon
) < sarea
->last_frame
) {
313 UNLOCK_HARDWARE(radeon
);
314 if (radeon
->do_usleeps
)
316 LOCK_HARDWARE(radeon
);
322 void radeonWaitForIdleLocked(radeonContextPtr radeon
)
328 ret
= drmCommandNone(radeon
->dri
.fd
, DRM_RADEON_CP_IDLE
);
331 } while (ret
&& ++i
< 100);
334 UNLOCK_HARDWARE(radeon
);
335 fprintf(stderr
, "Error: R300 timed out... exiting\n");
340 static void radeonWaitForIdle(radeonContextPtr radeon
)
342 LOCK_HARDWARE(radeon
);
343 radeonWaitForIdleLocked(radeon
);
344 UNLOCK_HARDWARE(radeon
);
348 /* Copy the back color buffer to the front color buffer.
350 void radeonCopyBuffer( __DRIdrawablePrivate
*dPriv
,
351 const drm_clip_rect_t
*rect
)
353 radeonContextPtr rmesa
;
355 GLboolean missed_target
;
357 __DRIscreenPrivate
*psp
;
360 assert(dPriv
->driContextPriv
);
361 assert(dPriv
->driContextPriv
->driverPrivate
);
363 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
365 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
366 fprintf( stderr
, "\n%s( %p )\n\n", __FUNCTION__
, (void *) rmesa
->glCtx
);
369 rmesa
->vtbl
.flush(rmesa
->glCtx
);
370 LOCK_HARDWARE( rmesa
);
372 /* Throttle the frame rate -- only allow one pending swap buffers
375 radeonWaitForFrameCompletion( rmesa
);
378 UNLOCK_HARDWARE( rmesa
);
379 driWaitForVBlank( dPriv
, & missed_target
);
380 LOCK_HARDWARE( rmesa
);
383 nbox
= dPriv
->numClipRects
; /* must be in locked region */
385 for ( i
= 0 ; i
< nbox
; ) {
386 GLint nr
= MIN2( i
+ RADEON_NR_SAREA_CLIPRECTS
, nbox
);
387 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
388 drm_clip_rect_t
*b
= rmesa
->sarea
->boxes
;
391 for ( ; i
< nr
; i
++ ) {
397 if (rect
->x1
> b
->x1
)
399 if (rect
->y1
> b
->y1
)
401 if (rect
->x2
< b
->x2
)
403 if (rect
->y2
< b
->y2
)
406 if (b
->x1
>= b
->x2
|| b
->y1
>= b
->y2
)
413 rmesa
->sarea
->nbox
= n
;
418 ret
= drmCommandNone( rmesa
->dri
.fd
, DRM_RADEON_SWAP
);
421 fprintf( stderr
, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret
);
422 UNLOCK_HARDWARE( rmesa
);
427 UNLOCK_HARDWARE( rmesa
);
430 psp
= dPriv
->driScreenPriv
;
432 (*psp
->systemTime
->getUST
)( & ust
);
433 if ( missed_target
) {
434 rmesa
->swap_missed_count
++;
435 rmesa
->swap_missed_ust
= ust
- rmesa
->swap_ust
;
438 rmesa
->swap_ust
= ust
;
439 rmesa
->vtbl
.set_all_dirty(rmesa
->glCtx
);
444 void radeonPageFlip( __DRIdrawablePrivate
*dPriv
)
446 radeonContextPtr rmesa
;
448 GLboolean missed_target
;
449 __DRIscreenPrivate
*psp
;
450 struct radeon_renderbuffer
*rrb
;
451 GLframebuffer
*fb
= dPriv
->driverPrivate
;
454 assert(dPriv
->driContextPriv
);
455 assert(dPriv
->driContextPriv
->driverPrivate
);
457 rmesa
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
458 rrb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
460 psp
= dPriv
->driScreenPriv
;
462 if ( RADEON_DEBUG
& DEBUG_IOCTL
) {
463 fprintf(stderr
, "%s: pfCurrentPage: %d\n", __FUNCTION__
,
464 rmesa
->sarea
->pfCurrentPage
);
467 rmesa
->vtbl
.flush(rmesa
->glCtx
);
469 LOCK_HARDWARE( rmesa
);
471 if (!dPriv
->numClipRects
) {
472 UNLOCK_HARDWARE(rmesa
);
473 usleep(10000); /* throttle invisible client 10ms */
477 drm_clip_rect_t
*box
= dPriv
->pClipRects
;
478 drm_clip_rect_t
*b
= rmesa
->sarea
->boxes
;
480 rmesa
->sarea
->nbox
= 1;
482 /* Throttle the frame rate -- only allow a few pending swap buffers
485 radeonWaitForFrameCompletion( rmesa
);
486 UNLOCK_HARDWARE( rmesa
);
487 driWaitForVBlank( dPriv
, & missed_target
);
488 if ( missed_target
) {
489 rmesa
->swap_missed_count
++;
490 (void) (*psp
->systemTime
->getUST
)( & rmesa
->swap_missed_ust
);
492 LOCK_HARDWARE( rmesa
);
494 ret
= drmCommandNone( rmesa
->dri
.fd
, DRM_RADEON_FLIP
);
496 UNLOCK_HARDWARE( rmesa
);
499 fprintf( stderr
, "DRM_RADEON_FLIP: return = %d\n", ret
);
504 (void) (*psp
->systemTime
->getUST
)( & rmesa
->swap_ust
);
506 /* Get ready for drawing next frame. Update the renderbuffers'
507 * flippedOffset/Pitch fields so we draw into the right place.
509 driFlipRenderbuffers(rmesa
->glCtx
->WinSysDrawBuffer
,
510 rmesa
->sarea
->pfCurrentPage
);
512 rmesa
->state
.color
.rrb
= rrb
;
514 if (rmesa
->vtbl
.update_draw_buffer
)
515 rmesa
->vtbl
.update_draw_buffer(rmesa
->glCtx
);
519 /* Make sure all commands have been sent to the hardware and have
520 * completed processing.
522 void radeon_common_finish(GLcontext
* ctx
)
524 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
525 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
528 if (radeon
->radeonScreen
->kernel_mm
) {
529 for (i
= 0; i
< fb
->_NumColorDrawBuffers
; i
++) {
530 struct radeon_renderbuffer
*rrb
;
531 rrb
= (struct radeon_renderbuffer
*)fb
->_ColorDrawBuffers
[i
];
533 radeon_bo_wait(rrb
->bo
);
535 } else if (radeon
->do_irqs
) {
536 LOCK_HARDWARE(radeon
);
537 radeonEmitIrqLocked(radeon
);
538 UNLOCK_HARDWARE(radeon
);
539 radeonWaitIrq(radeon
);
541 radeonWaitForIdle(radeon
);
546 * Swap front and back buffer.
548 void radeonSwapBuffers(__DRIdrawablePrivate
* dPriv
)
550 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
551 radeonContextPtr radeon
;
554 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
557 if (ctx
->Visual
.doubleBufferMode
) {
558 _mesa_notifySwapBuffers(ctx
);/* flush pending rendering comands */
559 if (radeon
->doPageFlip
) {
560 radeonPageFlip(dPriv
);
562 radeonCopyBuffer(dPriv
, NULL
);
566 /* XXX this shouldn't be an error but we can't handle it for now */
567 _mesa_problem(NULL
, "%s: drawable has no context!",
572 void radeonCopySubBuffer(__DRIdrawablePrivate
* dPriv
,
573 int x
, int y
, int w
, int h
)
575 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
576 radeonContextPtr radeon
;
579 radeon
= (radeonContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
582 if (ctx
->Visual
.doubleBufferMode
) {
583 drm_clip_rect_t rect
;
584 rect
.x1
= x
+ dPriv
->x
;
585 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
586 rect
.x2
= rect
.x1
+ w
;
587 rect
.y2
= rect
.y1
+ h
;
588 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
589 radeonCopyBuffer(dPriv
, &rect
);
592 /* XXX this shouldn't be an error but we can't handle it for now */
593 _mesa_problem(NULL
, "%s: drawable has no context!",
600 * Send the current command buffer via ioctl to the hardware.
602 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa
, const char *caller
)
606 if (rmesa
->cmdbuf
.flushing
) {
607 fprintf(stderr
, "Recursive call into r300FlushCmdBufLocked!\n");
610 rmesa
->cmdbuf
.flushing
= 1;
611 if (rmesa
->cmdbuf
.cs
->cdw
) {
612 ret
= radeon_cs_emit(rmesa
->cmdbuf
.cs
);
613 rmesa
->vtbl
.set_all_dirty(rmesa
->glCtx
);
615 radeon_cs_erase(rmesa
->cmdbuf
.cs
);
616 rmesa
->cmdbuf
.flushing
= 0;
620 int rcommonFlushCmdBuf(radeonContextPtr rmesa
, const char *caller
)
624 radeonReleaseDmaRegion(rmesa
);
626 LOCK_HARDWARE(rmesa
);
627 ret
= rcommonFlushCmdBufLocked(rmesa
, caller
);
628 UNLOCK_HARDWARE(rmesa
);
631 fprintf(stderr
, "drmRadeonCmdBuffer: %d\n", ret
);
639 * Make sure that enough space is available in the command buffer
640 * by flushing if necessary.
642 * \param dwords The number of dwords we need to be free on the command buffer
644 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa
, int dwords
, const char *caller
)
646 if ((rmesa
->cmdbuf
.cs
->cdw
+ dwords
+ 128) > rmesa
->cmdbuf
.size
||
647 radeon_cs_need_flush(rmesa
->cmdbuf
.cs
)) {
648 rcommonFlushCmdBuf(rmesa
, caller
);
652 void rcommonInitCmdBuf(radeonContextPtr rmesa
, int max_state_size
)
655 /* Initialize command buffer */
656 size
= 256 * driQueryOptioni(&rmesa
->optionCache
,
657 "command_buffer_size");
658 if (size
< 2 * max_state_size
) {
659 size
= 2 * max_state_size
+ 65535;
664 size
= 64 * 1024 / 4;
666 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
)) {
667 fprintf(stderr
, "sizeof(drm_r300_cmd_header_t)=%zd\n",
668 sizeof(drm_r300_cmd_header_t
));
669 fprintf(stderr
, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
670 sizeof(drm_radeon_cmd_buffer_t
));
672 "Allocating %d bytes command buffer (max state is %d bytes)\n",
673 size
* 4, max_state_size
* 4);
676 if (rmesa
->radeonScreen
->kernel_mm
) {
677 int fd
= rmesa
->radeonScreen
->driScreen
->fd
;
678 rmesa
->cmdbuf
.csm
= radeon_cs_manager_gem_ctor(fd
);
680 rmesa
->cmdbuf
.csm
= radeon_cs_manager_legacy_ctor(rmesa
);
682 if (rmesa
->cmdbuf
.csm
== NULL
) {
683 /* FIXME: fatal error */
686 rmesa
->cmdbuf
.cs
= radeon_cs_create(rmesa
->cmdbuf
.csm
, size
);
687 assert(rmesa
->cmdbuf
.cs
!= NULL
);
688 rmesa
->cmdbuf
.size
= size
;
690 if (!rmesa
->radeonScreen
->kernel_mm
) {
691 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
692 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
694 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
695 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
700 * Destroy the command buffer
702 void rcommonDestroyCmdBuf(radeonContextPtr rmesa
)
704 radeon_cs_destroy(rmesa
->cmdbuf
.cs
);
705 if (rmesa
->radeonScreen
->driScreen
->dri2
.enabled
|| rmesa
->radeonScreen
->kernel_mm
) {
706 radeon_cs_manager_gem_dtor(rmesa
->cmdbuf
.csm
);
708 radeon_cs_manager_legacy_dtor(rmesa
->cmdbuf
.csm
);
712 void rcommonBeginBatch(radeonContextPtr rmesa
, int n
,
715 const char *function
,
718 rcommonEnsureCmdBufSpace(rmesa
, n
, function
);
719 if (!rmesa
->cmdbuf
.cs
->cdw
&& dostate
) {
720 if (RADEON_DEBUG
& DEBUG_IOCTL
)
721 fprintf(stderr
, "Reemit state after flush (from %s)\n", function
);
722 rmesa
->vtbl
.emit_state(rmesa
);
724 radeon_cs_begin(rmesa
->cmdbuf
.cs
, n
, file
, function
, line
);
729 /* Return various strings for glGetString().
731 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
733 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
734 static char buffer
[128];
738 if (IS_R300_CLASS(radeon
->radeonScreen
))
739 return (GLubyte
*) "DRI R300 Project";
741 return (GLubyte
*) "Tungsten Graphics, Inc.";
746 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
747 radeon
->radeonScreen
->AGPMode
;
748 const char* chipname
;
752 if (IS_R300_CLASS(radeon
->radeonScreen
))
757 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
760 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
761 sprintf(&buffer
[offset
], " %sTCL",
762 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
765 sprintf(&buffer
[offset
], " %sTCL",
766 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
770 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
771 strcat(buffer
, " DRI2");
773 return (GLubyte
*) buffer
;
781 /* Initialize the driver's misc functions.
783 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
785 functions
->GetString
= radeonGetString
;
789 * Create and initialize all common fields of the context,
790 * including the Mesa context itself.
792 GLboolean
radeonInitContext(radeonContextPtr radeon
,
793 struct dd_function_table
* functions
,
794 const __GLcontextModes
* glVisual
,
795 __DRIcontextPrivate
* driContextPriv
,
796 void *sharedContextPrivate
)
798 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
799 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
804 /* Fill in additional standard functions. */
805 radeonInitDriverFuncs(functions
);
807 radeon
->radeonScreen
= screen
;
808 /* Allocate and initialize the Mesa context */
809 if (sharedContextPrivate
)
810 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
813 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
814 functions
, (void *)radeon
);
819 driContextPriv
->driverPrivate
= radeon
;
822 radeon
->dri
.context
= driContextPriv
;
823 radeon
->dri
.screen
= sPriv
;
824 radeon
->dri
.drawable
= NULL
;
825 radeon
->dri
.readable
= NULL
;
826 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
827 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
828 radeon
->dri
.fd
= sPriv
->fd
;
829 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
831 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
832 screen
->sarea_priv_offset
);
835 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
836 radeon
->iw
.irq_seq
= -1;
837 radeon
->irqsEmitted
= 0;
838 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
839 radeon
->radeonScreen
->irq
);
841 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
843 if (!radeon
->do_irqs
)
845 "IRQ's not enabled, falling back to %s: %d %d\n",
846 radeon
->do_usleeps
? "usleeps" : "busy waits",
847 fthrottle_mode
, radeon
->radeonScreen
->irq
);
849 (*sPriv
->systemTime
->getUST
) (&radeon
->swap_ust
);
855 * Cleanup common context fields.
856 * Called by r200DestroyContext/r300DestroyContext
858 void radeonCleanupContext(radeonContextPtr radeon
)
861 struct radeon_renderbuffer
*rb
;
864 fb
= (void*)radeon
->dri
.drawable
->driverPrivate
;
865 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
867 radeon_bo_unref(rb
->bo
);
870 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
872 radeon_bo_unref(rb
->bo
);
875 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
877 radeon_bo_unref(rb
->bo
);
880 fb
= (void*)radeon
->dri
.readable
->driverPrivate
;
881 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
883 radeon_bo_unref(rb
->bo
);
886 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
888 radeon_bo_unref(rb
->bo
);
891 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
893 radeon_bo_unref(rb
->bo
);
897 /* _mesa_destroy_context() might result in calls to functions that
898 * depend on the DriverCtx, so don't set it to NULL before.
900 * radeon->glCtx->DriverCtx = NULL;
903 /* free the Mesa context */
904 _mesa_destroy_context(radeon
->glCtx
);
906 /* free the option cache */
907 driDestroyOptionCache(&radeon
->optionCache
);
909 if (radeon
->state
.scissor
.pClipRects
) {
910 FREE(radeon
->state
.scissor
.pClipRects
);
911 radeon
->state
.scissor
.pClipRects
= 0;
913 track
= fopen("/tmp/tracklog", "w");
915 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
921 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
924 /* if radeon->fake */
925 struct radeon_renderbuffer
*rb
;
927 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
929 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
930 radeon
->radeonScreen
->frontOffset
,
933 RADEON_GEM_DOMAIN_VRAM
,
936 rb
->cpp
= radeon
->radeonScreen
->cpp
;
937 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
939 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
941 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
942 radeon
->radeonScreen
->backOffset
,
945 RADEON_GEM_DOMAIN_VRAM
,
948 rb
->cpp
= radeon
->radeonScreen
->cpp
;
949 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
951 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
953 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
954 radeon
->radeonScreen
->depthOffset
,
957 RADEON_GEM_DOMAIN_VRAM
,
960 rb
->cpp
= radeon
->radeonScreen
->cpp
;
961 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
963 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
965 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
966 radeon
->radeonScreen
->depthOffset
,
969 RADEON_GEM_DOMAIN_VRAM
,
972 rb
->cpp
= radeon
->radeonScreen
->cpp
;
973 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
978 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
981 int size
= 4096*4096*4;
982 /* if radeon->fake */
983 struct radeon_renderbuffer
*rb
;
985 if (radeon
->radeonScreen
->kernel_mm
) {
986 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
991 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
993 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
994 radeon
->radeonScreen
->frontOffset
+
995 radeon
->radeonScreen
->fbLocation
,
998 RADEON_GEM_DOMAIN_VRAM
,
1001 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1002 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
1004 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
1006 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1007 radeon
->radeonScreen
->backOffset
+
1008 radeon
->radeonScreen
->fbLocation
,
1011 RADEON_GEM_DOMAIN_VRAM
,
1014 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1015 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
1017 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
1019 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1020 radeon
->radeonScreen
->depthOffset
+
1021 radeon
->radeonScreen
->fbLocation
,
1024 RADEON_GEM_DOMAIN_VRAM
,
1027 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1028 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
1030 if ((rb
= (void *)draw
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)) {
1032 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1033 radeon
->radeonScreen
->depthOffset
+
1034 radeon
->radeonScreen
->fbLocation
,
1037 RADEON_GEM_DOMAIN_VRAM
,
1040 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1041 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
1047 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
1049 unsigned int attachments
[10];
1050 __DRIbuffer
*buffers
;
1051 __DRIscreen
*screen
;
1052 struct radeon_renderbuffer
*rb
;
1054 GLframebuffer
*draw
;
1055 radeonContextPtr radeon
;
1057 if (RADEON_DEBUG
& DEBUG_DRI
)
1058 fprintf(stderr
, "enter %s, drawable %p\n", __func__
, drawable
);
1060 draw
= drawable
->driverPrivate
;
1061 screen
= context
->driScreenPriv
;
1062 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1064 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
1065 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
1067 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
1068 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
1070 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
1071 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
1074 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
1079 drawable
->loaderPrivate
);
1080 if (buffers
== NULL
)
1083 /* set one cliprect to cover the whole drawable */
1086 drawable
->backX
= 0;
1087 drawable
->backY
= 0;
1088 drawable
->numClipRects
= 1;
1089 drawable
->pClipRects
[0].x1
= 0;
1090 drawable
->pClipRects
[0].y1
= 0;
1091 drawable
->pClipRects
[0].x2
= drawable
->w
;
1092 drawable
->pClipRects
[0].y2
= drawable
->h
;
1093 drawable
->numBackClipRects
= 1;
1094 drawable
->pBackClipRects
[0].x1
= 0;
1095 drawable
->pBackClipRects
[0].y1
= 0;
1096 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
1097 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
1098 for (i
= 0; i
< count
; i
++) {
1099 switch (buffers
[i
].attachment
) {
1100 case __DRI_BUFFER_FRONT_LEFT
:
1101 rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1103 radeon_bo_unref(rb
->bo
);
1106 rb
->cpp
= buffers
[i
].cpp
;
1107 rb
->pitch
= buffers
[i
].pitch
;
1108 rb
->width
= drawable
->w
;
1109 rb
->height
= drawable
->h
;
1110 rb
->has_surface
= 0;
1111 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1115 RADEON_GEM_DOMAIN_VRAM
,
1117 if (rb
->bo
== NULL
) {
1118 fprintf(stderr
, "failled to attach front %d\n",
1122 case __DRI_BUFFER_BACK_LEFT
:
1123 rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1125 radeon_bo_unref(rb
->bo
);
1128 rb
->cpp
= buffers
[i
].cpp
;
1129 rb
->pitch
= buffers
[i
].pitch
;
1130 rb
->width
= drawable
->w
;
1131 rb
->height
= drawable
->h
;
1132 rb
->has_surface
= 0;
1133 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1137 RADEON_GEM_DOMAIN_VRAM
,
1140 case __DRI_BUFFER_DEPTH
:
1141 rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1143 radeon_bo_unref(rb
->bo
);
1146 rb
->cpp
= buffers
[i
].cpp
;
1147 rb
->pitch
= buffers
[i
].pitch
;
1148 rb
->width
= drawable
->w
;
1149 rb
->height
= drawable
->h
;
1150 rb
->has_surface
= 0;
1151 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1155 RADEON_GEM_DOMAIN_VRAM
,
1158 case __DRI_BUFFER_STENCIL
:
1160 case __DRI_BUFFER_ACCUM
:
1163 "unhandled buffer attach event, attacment type %d\n",
1164 buffers
[i
].attachment
);
1168 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1169 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
1172 /* Force the context `c' to be the current context and associate with it
1175 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
1176 __DRIdrawablePrivate
* driDrawPriv
,
1177 __DRIdrawablePrivate
* driReadPriv
)
1179 radeonContextPtr radeon
;
1180 GLframebuffer
*dfb
, *rfb
;
1182 if (!driContextPriv
) {
1183 if (RADEON_DEBUG
& DEBUG_DRI
)
1184 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
1185 _mesa_make_current(NULL
, NULL
, NULL
);
1188 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
1189 dfb
= driDrawPriv
->driverPrivate
;
1190 rfb
= driReadPriv
->driverPrivate
;
1192 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1193 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
1194 if (driDrawPriv
!= driReadPriv
)
1195 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
1196 radeon
->state
.color
.rrb
=
1197 (void *)dfb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1198 radeon
->state
.depth
.rrb
=
1199 (void *)dfb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1201 radeon_make_renderbuffer_current(radeon
, dfb
);
1205 if (RADEON_DEBUG
& DEBUG_DRI
)
1206 fprintf(stderr
, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__
, radeon
->glCtx
, dfb
, rfb
);
1208 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
1209 if (driReadPriv
!= driDrawPriv
)
1210 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
1214 _mesa_make_current(radeon
->glCtx
, dfb
, rfb
);
1216 if (radeon
->dri
.drawable
!= driDrawPriv
) {
1217 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
1218 driDrawPriv
->vblFlags
=
1219 (radeon
->radeonScreen
->irq
!= 0)
1220 ? driGetDefaultVBlankFlags(&radeon
->
1222 : VBLANK_FLAG_NO_IRQ
;
1224 driDrawableInitVBlank(driDrawPriv
);
1228 radeon
->dri
.readable
= driReadPriv
;
1230 if (radeon
->dri
.drawable
!= driDrawPriv
||
1231 radeon
->lastStamp
!= driDrawPriv
->lastStamp
) {
1232 radeon
->dri
.drawable
= driDrawPriv
;
1234 radeonSetCliprects(radeon
);
1235 radeon
->vtbl
.update_viewport_offset(radeon
->glCtx
);
1238 _mesa_update_state(radeon
->glCtx
);
1240 if (!driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1241 radeonUpdatePageFlipping(radeon
);
1244 if (RADEON_DEBUG
& DEBUG_DRI
)
1245 fprintf(stderr
, "End %s\n", __FUNCTION__
);
1250 #if defined(USE_X86_ASM)
1251 #define COPY_DWORDS( dst, src, nr ) \
1254 __asm__ __volatile__( "rep ; movsl" \
1255 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
1258 "S" ((long)src) ); \
1261 #define COPY_DWORDS( dst, src, nr ) \
1264 for ( j = 0 ; j < nr ; j++ ) \
1265 dst[j] = ((int *)src)[j]; \
1270 static void radeonEmitVec4(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1274 if (RADEON_DEBUG
& DEBUG_VERTS
)
1275 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1276 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1279 COPY_DWORDS(out
, data
, count
);
1281 for (i
= 0; i
< count
; i
++) {
1282 out
[0] = *(int *)data
;
1288 static void radeonEmitVec8(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1292 if (RADEON_DEBUG
& DEBUG_VERTS
)
1293 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1294 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1297 COPY_DWORDS(out
, data
, count
* 2);
1299 for (i
= 0; i
< count
; i
++) {
1300 out
[0] = *(int *)data
;
1301 out
[1] = *(int *)(data
+ 4);
1307 static void radeonEmitVec12(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1311 if (RADEON_DEBUG
& DEBUG_VERTS
)
1312 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1313 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1316 COPY_DWORDS(out
, data
, count
* 3);
1319 for (i
= 0; i
< count
; i
++) {
1320 out
[0] = *(int *)data
;
1321 out
[1] = *(int *)(data
+ 4);
1322 out
[2] = *(int *)(data
+ 8);
1328 static void radeonEmitVec16(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1332 if (RADEON_DEBUG
& DEBUG_VERTS
)
1333 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1334 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1337 COPY_DWORDS(out
, data
, count
* 4);
1339 for (i
= 0; i
< count
; i
++) {
1340 out
[0] = *(int *)data
;
1341 out
[1] = *(int *)(data
+ 4);
1342 out
[2] = *(int *)(data
+ 8);
1343 out
[3] = *(int *)(data
+ 12);
1349 void rcommon_emit_vector(GLcontext
* ctx
, struct radeon_aos
*aos
,
1350 GLvoid
* data
, int size
, int stride
, int count
)
1352 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1356 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* 4, 32);
1360 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* count
* 4, 32);
1364 aos
->components
= size
;
1367 out
= (uint32_t*)((char*)aos
->bo
->ptr
+ aos
->offset
);
1369 case 1: radeonEmitVec4(out
, data
, stride
, count
); break;
1370 case 2: radeonEmitVec8(out
, data
, stride
, count
); break;
1371 case 3: radeonEmitVec12(out
, data
, stride
, count
); break;
1372 case 4: radeonEmitVec16(out
, data
, stride
, count
); break;
1380 void radeon_print_state_atom( struct radeon_state_atom
*state
)
1384 fprintf(stderr
, "emit %s/%d\n", state
->name
, state
->cmd_size
);
1386 if (RADEON_DEBUG
& DEBUG_VERBOSE
)
1387 for (i
= 0 ; i
< state
->cmd_size
; i
++)
1388 fprintf(stderr
, "\t%s[%d]: %x\n", state
->name
, i
, state
->cmd
[i
]);
1394 * Allocate an empty texture image object.
1396 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
1398 return CALLOC(sizeof(radeon_texture_image
));
1402 * Free memory associated with this texture image.
1404 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
1406 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
1409 radeon_miptree_unreference(image
->mt
);
1411 assert(!image
->base
.Data
);
1413 _mesa_free_texture_image_data(ctx
, timage
);
1416 radeon_bo_unref(image
->bo
);
1420 _mesa_free_texmemory(timage
->Data
);
1421 timage
->Data
= NULL
;
1425 /* Set Data pointer and additional data for mapped texture image */
1426 static void teximage_set_map_data(radeon_texture_image
*image
)
1428 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1430 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
1431 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
1436 * Map a single texture image for glTexImage and friends.
1438 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
1441 assert(!image
->base
.Data
);
1443 radeon_bo_map(image
->mt
->bo
, write_enable
);
1444 teximage_set_map_data(image
);
1449 void radeon_teximage_unmap(radeon_texture_image
*image
)
1452 assert(image
->base
.Data
);
1454 image
->base
.Data
= 0;
1455 radeon_bo_unmap(image
->mt
->bo
);
1460 * Map a validated texture for reading during software rendering.
1462 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1464 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1467 // assert(texObj->_Complete);
1470 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
1471 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1472 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1473 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
1477 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1479 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1482 // assert(texObj->_Complete);
1485 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1486 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1487 texObj
->Image
[face
][level
]->Data
= 0;
1489 radeon_bo_unmap(t
->mt
->bo
);
1492 GLuint
radeon_face_for_target(GLenum target
)
1495 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
1496 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
1497 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
1498 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
1499 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
1500 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
1501 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
1508 * Wraps Mesa's implementation to ensure that the base level image is mapped.
1510 * This relies on internal details of _mesa_generate_mipmap, in particular
1511 * the fact that the memory for recreated texture images is always freed.
1513 void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
1514 struct gl_texture_object
*texObj
)
1516 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1517 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
1521 _mesa_generate_mipmap(ctx
, target
, texObj
);
1523 for (face
= 0; face
< nr_faces
; face
++) {
1524 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
1525 radeon_texture_image
*image
;
1527 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
1533 image
->mtface
= face
;
1535 radeon_miptree_unreference(image
->mt
);
1542 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
1544 GLuint face
= radeon_face_for_target(target
);
1545 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
1547 radeon_teximage_map(baseimage
, GL_FALSE
);
1548 radeon_generate_mipmap(ctx
, target
, texObj
);
1549 radeon_teximage_unmap(baseimage
);
1553 /* try to find a format which will only need a memcopy */
1554 static const struct gl_texture_format
*radeonChoose8888TexFormat(GLenum srcFormat
,
1557 const GLuint ui
= 1;
1558 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
1560 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1561 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1562 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1563 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
1564 return &_mesa_texformat_rgba8888
;
1565 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1566 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1567 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1568 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
1569 return &_mesa_texformat_rgba8888_rev
;
1570 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1571 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1572 return &_mesa_texformat_argb8888_rev
;
1573 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1574 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1575 return &_mesa_texformat_argb8888
;
1577 return _dri_texformat_argb8888
;
1580 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
1581 GLint internalFormat
,
1585 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1586 const GLboolean do32bpt
=
1587 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
1588 const GLboolean force16bpt
=
1589 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
1593 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
1594 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
1595 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
1596 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
1599 switch (internalFormat
) {
1602 case GL_COMPRESSED_RGBA
:
1604 case GL_UNSIGNED_INT_10_10_10_2
:
1605 case GL_UNSIGNED_INT_2_10_10_10_REV
:
1606 return do32bpt
? _dri_texformat_argb8888
:
1607 _dri_texformat_argb1555
;
1608 case GL_UNSIGNED_SHORT_4_4_4_4
:
1609 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1610 return _dri_texformat_argb4444
;
1611 case GL_UNSIGNED_SHORT_5_5_5_1
:
1612 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1613 return _dri_texformat_argb1555
;
1615 return do32bpt
? radeonChoose8888TexFormat(format
, type
) :
1616 _dri_texformat_argb4444
;
1621 case GL_COMPRESSED_RGB
:
1623 case GL_UNSIGNED_SHORT_4_4_4_4
:
1624 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1625 return _dri_texformat_argb4444
;
1626 case GL_UNSIGNED_SHORT_5_5_5_1
:
1627 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1628 return _dri_texformat_argb1555
;
1629 case GL_UNSIGNED_SHORT_5_6_5
:
1630 case GL_UNSIGNED_SHORT_5_6_5_REV
:
1631 return _dri_texformat_rgb565
;
1633 return do32bpt
? _dri_texformat_argb8888
:
1634 _dri_texformat_rgb565
;
1641 return !force16bpt
?
1642 radeonChoose8888TexFormat(format
,
1643 type
) : _dri_texformat_argb4444
;
1647 return _dri_texformat_argb4444
;
1650 return _dri_texformat_argb1555
;
1656 return !force16bpt
? _dri_texformat_argb8888
:
1657 _dri_texformat_rgb565
;
1662 return _dri_texformat_rgb565
;
1669 case GL_COMPRESSED_ALPHA
:
1670 return _dri_texformat_a8
;
1676 case GL_LUMINANCE12
:
1677 case GL_LUMINANCE16
:
1678 case GL_COMPRESSED_LUMINANCE
:
1679 return _dri_texformat_l8
;
1682 case GL_LUMINANCE_ALPHA
:
1683 case GL_LUMINANCE4_ALPHA4
:
1684 case GL_LUMINANCE6_ALPHA2
:
1685 case GL_LUMINANCE8_ALPHA8
:
1686 case GL_LUMINANCE12_ALPHA4
:
1687 case GL_LUMINANCE12_ALPHA12
:
1688 case GL_LUMINANCE16_ALPHA16
:
1689 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1690 return _dri_texformat_al88
;
1695 case GL_INTENSITY12
:
1696 case GL_INTENSITY16
:
1697 case GL_COMPRESSED_INTENSITY
:
1698 return _dri_texformat_i8
;
1701 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
1702 type
== GL_UNSIGNED_BYTE
)
1703 return &_mesa_texformat_ycbcr
;
1705 return &_mesa_texformat_ycbcr_rev
;
1709 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1710 return &_mesa_texformat_rgb_dxt1
;
1712 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1713 return &_mesa_texformat_rgba_dxt1
;
1717 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1718 return &_mesa_texformat_rgba_dxt3
;
1720 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1721 return &_mesa_texformat_rgba_dxt5
;
1723 case GL_ALPHA16F_ARB
:
1724 return &_mesa_texformat_alpha_float16
;
1725 case GL_ALPHA32F_ARB
:
1726 return &_mesa_texformat_alpha_float32
;
1727 case GL_LUMINANCE16F_ARB
:
1728 return &_mesa_texformat_luminance_float16
;
1729 case GL_LUMINANCE32F_ARB
:
1730 return &_mesa_texformat_luminance_float32
;
1731 case GL_LUMINANCE_ALPHA16F_ARB
:
1732 return &_mesa_texformat_luminance_alpha_float16
;
1733 case GL_LUMINANCE_ALPHA32F_ARB
:
1734 return &_mesa_texformat_luminance_alpha_float32
;
1735 case GL_INTENSITY16F_ARB
:
1736 return &_mesa_texformat_intensity_float16
;
1737 case GL_INTENSITY32F_ARB
:
1738 return &_mesa_texformat_intensity_float32
;
1740 return &_mesa_texformat_rgba_float16
;
1742 return &_mesa_texformat_rgba_float32
;
1743 case GL_RGBA16F_ARB
:
1744 return &_mesa_texformat_rgba_float16
;
1745 case GL_RGBA32F_ARB
:
1746 return &_mesa_texformat_rgba_float32
;
1748 case GL_DEPTH_COMPONENT
:
1749 case GL_DEPTH_COMPONENT16
:
1750 case GL_DEPTH_COMPONENT24
:
1751 case GL_DEPTH_COMPONENT32
:
1754 case GL_UNSIGNED_BYTE
:
1755 case GL_UNSIGNED_SHORT
:
1756 return &_mesa_texformat_z16
;
1757 case GL_UNSIGNED_INT
:
1758 return &_mesa_texformat_z32
;
1759 case GL_UNSIGNED_INT_24_8_EXT
:
1761 return &_mesa_texformat_z24_s8
;
1764 return &_mesa_texformat_z16
;
1769 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
1770 (int)internalFormat
);
1774 return NULL
; /* never get here */
1778 * All glTexImage calls go through this function.
1780 static void radeon_teximage(
1781 GLcontext
*ctx
, int dims
,
1782 GLint face
, GLint level
,
1783 GLint internalFormat
,
1784 GLint width
, GLint height
, GLint depth
,
1786 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1787 const struct gl_pixelstore_attrib
*packing
,
1788 struct gl_texture_object
*texObj
,
1789 struct gl_texture_image
*texImage
,
1792 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1793 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1794 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1796 rmesa
->vtbl
.flush_vertices(rmesa
);
1798 t
->validated
= GL_FALSE
;
1800 /* Choose and fill in the texture format for this image */
1801 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
);
1802 _mesa_set_fetch_functions(texImage
, dims
);
1804 if (texImage
->TexFormat
->TexelBytes
== 0) {
1805 texImage
->IsCompressed
= GL_TRUE
;
1806 texImage
->CompressedSize
=
1807 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
1808 texImage
->Height
, texImage
->Depth
,
1809 texImage
->TexFormat
->MesaFormat
);
1811 texImage
->IsCompressed
= GL_FALSE
;
1812 texImage
->CompressedSize
= 0;
1815 /* Allocate memory for image */
1816 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
1819 radeon_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
1820 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
1822 image
->mtlevel
= level
- t
->mt
->firstLevel
;
1823 image
->mtface
= face
;
1824 radeon_miptree_reference(t
->mt
);
1827 if (texImage
->IsCompressed
) {
1828 size
= texImage
->CompressedSize
;
1830 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
1832 texImage
->Data
= _mesa_alloc_texmemory(size
);
1835 /* Upload texture image; note that the spec allows pixels to be NULL */
1837 pixels
= _mesa_validate_pbo_compressed_teximage(
1838 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
1840 pixels
= _mesa_validate_pbo_teximage(
1841 ctx
, dims
, width
, height
, depth
,
1842 format
, type
, pixels
, packing
, "glTexImage");
1846 radeon_teximage_map(image
, GL_TRUE
);
1849 memcpy(texImage
->Data
, pixels
, imageSize
);
1851 GLuint dstRowStride
;
1853 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1854 dstRowStride
= lvl
->rowstride
;
1856 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
1858 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
1859 texImage
->_BaseFormat
,
1860 texImage
->TexFormat
,
1861 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
1863 texImage
->ImageOffsets
,
1864 width
, height
, depth
,
1865 format
, type
, pixels
, packing
))
1866 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
1871 /* SGIS_generate_mipmap */
1872 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1873 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
1877 radeon_teximage_unmap(image
);
1879 _mesa_unmap_teximage_pbo(ctx
, packing
);
1884 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1885 GLint internalFormat
,
1886 GLint width
, GLint border
,
1887 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1888 const struct gl_pixelstore_attrib
*packing
,
1889 struct gl_texture_object
*texObj
,
1890 struct gl_texture_image
*texImage
)
1892 radeon_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
1893 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1896 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1897 GLint internalFormat
,
1898 GLint width
, GLint height
, GLint border
,
1899 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1900 const struct gl_pixelstore_attrib
*packing
,
1901 struct gl_texture_object
*texObj
,
1902 struct gl_texture_image
*texImage
)
1905 GLuint face
= radeon_face_for_target(target
);
1907 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1908 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1911 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
1912 GLint level
, GLint internalFormat
,
1913 GLint width
, GLint height
, GLint border
,
1914 GLsizei imageSize
, const GLvoid
* data
,
1915 struct gl_texture_object
*texObj
,
1916 struct gl_texture_image
*texImage
)
1918 GLuint face
= radeon_face_for_target(target
);
1920 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1921 imageSize
, 0, 0, data
, 0, texObj
, texImage
, 1);
1924 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
1925 GLint internalFormat
,
1926 GLint width
, GLint height
, GLint depth
,
1928 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1929 const struct gl_pixelstore_attrib
*packing
,
1930 struct gl_texture_object
*texObj
,
1931 struct gl_texture_image
*texImage
)
1933 radeon_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
1934 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1938 * Update a subregion of the given texture image.
1940 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, int level
,
1941 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1942 GLsizei width
, GLsizei height
, GLsizei depth
,
1943 GLenum format
, GLenum type
,
1944 const GLvoid
* pixels
,
1945 const struct gl_pixelstore_attrib
*packing
,
1946 struct gl_texture_object
*texObj
,
1947 struct gl_texture_image
*texImage
,
1950 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1951 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1952 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1954 rmesa
->vtbl
.flush_vertices(rmesa
);
1956 t
->validated
= GL_FALSE
;
1957 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
1958 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
1962 radeon_teximage_map(image
, GL_TRUE
);
1965 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1966 dstRowStride
= lvl
->rowstride
;
1968 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
1971 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
1972 texImage
->TexFormat
, texImage
->Data
,
1973 xoffset
, yoffset
, zoffset
,
1975 texImage
->ImageOffsets
,
1976 width
, height
, depth
,
1977 format
, type
, pixels
, packing
))
1978 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
1983 /* GL_SGIS_generate_mipmap */
1984 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1985 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
1987 radeon_teximage_unmap(image
);
1989 _mesa_unmap_teximage_pbo(ctx
, packing
);
1994 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1997 GLenum format
, GLenum type
,
1998 const GLvoid
* pixels
,
1999 const struct gl_pixelstore_attrib
*packing
,
2000 struct gl_texture_object
*texObj
,
2001 struct gl_texture_image
*texImage
)
2003 radeon_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1,
2004 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
2007 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
2008 GLint xoffset
, GLint yoffset
,
2009 GLsizei width
, GLsizei height
,
2010 GLenum format
, GLenum type
,
2011 const GLvoid
* pixels
,
2012 const struct gl_pixelstore_attrib
*packing
,
2013 struct gl_texture_object
*texObj
,
2014 struct gl_texture_image
*texImage
)
2016 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
,
2017 1, format
, type
, pixels
, packing
, texObj
, texImage
,
2021 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
2022 GLint level
, GLint xoffset
,
2023 GLint yoffset
, GLsizei width
,
2024 GLsizei height
, GLenum format
,
2025 GLsizei imageSize
, const GLvoid
* data
,
2026 struct gl_texture_object
*texObj
,
2027 struct gl_texture_image
*texImage
)
2029 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
2030 format
, 0, data
, 0, texObj
, texImage
, 1);
2034 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
2035 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2036 GLsizei width
, GLsizei height
, GLsizei depth
,
2037 GLenum format
, GLenum type
,
2038 const GLvoid
* pixels
,
2039 const struct gl_pixelstore_attrib
*packing
,
2040 struct gl_texture_object
*texObj
,
2041 struct gl_texture_image
*texImage
)
2043 radeon_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
,
2044 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
2047 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
2048 GLuint numrows
, GLuint rowsize
)
2050 assert(rowsize
<= dststride
);
2051 assert(rowsize
<= srcstride
);
2053 if (rowsize
== srcstride
&& rowsize
== dststride
) {
2054 memcpy(dst
, src
, numrows
*rowsize
);
2057 for(i
= 0; i
< numrows
; ++i
) {
2058 memcpy(dst
, src
, rowsize
);
2067 * Ensure that the given image is stored in the given miptree from now on.
2069 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
2071 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
2072 unsigned char *dest
;
2074 assert(image
->mt
!= mt
);
2075 assert(dstlvl
->width
== image
->base
.Width
);
2076 assert(dstlvl
->height
== image
->base
.Height
);
2077 assert(dstlvl
->depth
== image
->base
.Depth
);
2080 radeon_bo_map(mt
->bo
, GL_TRUE
);
2081 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
2084 /* Format etc. should match, so we really just need a memcpy().
2085 * In fact, that memcpy() could be done by the hardware in many
2086 * cases, provided that we have a proper memory manager.
2088 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
];
2090 assert(srclvl
->size
== dstlvl
->size
);
2091 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
2093 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
2096 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
2098 radeon_bo_unmap(image
->mt
->bo
);
2100 radeon_miptree_unreference(image
->mt
);
2102 uint srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
2104 // if (mt->tilebits)
2105 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
2107 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
2108 image
->base
.Height
* image
->base
.Depth
, srcrowstride
);
2110 _mesa_free_texmemory(image
->base
.Data
);
2111 image
->base
.Data
= 0;
2114 radeon_bo_unmap(mt
->bo
);
2117 image
->mtface
= face
;
2118 image
->mtlevel
= level
;
2119 radeon_miptree_reference(image
->mt
);
2122 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
2124 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2125 radeonTexObj
*t
= radeon_tex_obj(texObj
);
2126 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
2129 if (t
->validated
|| t
->image_override
)
2132 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2133 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
2135 if (baseimage
->base
.Border
> 0)
2138 /* Ensure a matching miptree exists.
2140 * Differing mipmap trees can result when the app uses TexImage to
2141 * change texture dimensions.
2143 * Prefer to use base image's miptree if it
2144 * exists, since that most likely contains more valid data (remember
2145 * that the base level is usually significantly larger than the rest
2146 * of the miptree, so cubemaps are the only possible exception).
2148 if (baseimage
->mt
&&
2149 baseimage
->mt
!= t
->mt
&&
2150 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
2151 radeon_miptree_unreference(t
->mt
);
2152 t
->mt
= baseimage
->mt
;
2153 radeon_miptree_reference(t
->mt
);
2154 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
2155 radeon_miptree_unreference(t
->mt
);
2160 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2161 fprintf(stderr
, " Allocate new miptree\n");
2162 radeon_try_alloc_miptree(rmesa
, t
, &baseimage
->base
, 0, texObj
->BaseLevel
);
2164 _mesa_problem(ctx
, "r300_validate_texture failed to alloc miptree");
2169 /* Ensure all images are stored in the single main miptree */
2170 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
2171 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
2172 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
2173 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2174 fprintf(stderr
, " face %i, level %i... %p vs %p ", face
, level
, t
->mt
, image
->mt
);
2175 if (t
->mt
== image
->mt
) {
2176 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2177 fprintf(stderr
, "OK\n");
2181 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2182 fprintf(stderr
, "migrating\n");
2183 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
2191 GLubyte
*radeon_ptr32(const struct radeon_renderbuffer
* rrb
,
2194 GLubyte
*ptr
= rrb
->bo
->ptr
;
2195 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2196 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2204 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2205 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2208 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2209 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2210 nmacroblkpl
= rrb
->pitch
>> 5;
2211 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2212 offset
+= ((y
& 15) >> 1) << 8;
2213 offset
+= (y
& 1) << 4;
2214 offset
+= (x
>> 5) << 11;
2215 offset
+= ((x
& 31) >> 2) << 5;
2216 offset
+= (x
& 3) << 2;
2218 nmacroblkpl
= rrb
->pitch
>> 6;
2219 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2220 offset
+= (y
& 7) << 8;
2221 offset
+= (x
>> 6) << 11;
2222 offset
+= ((x
& 63) >> 3) << 5;
2223 offset
+= (x
& 7) << 2;
2226 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2227 offset
+= (y
* nmicroblkpl
) << 5;
2228 offset
+= (x
>> 3) << 5;
2229 offset
+= (x
& 7) << 2;
2232 return &ptr
[offset
];
2235 GLubyte
*radeon_ptr16(const struct radeon_renderbuffer
* rrb
,
2238 GLubyte
*ptr
= rrb
->bo
->ptr
;
2239 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2240 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2248 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2249 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2252 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2253 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2254 nmacroblkpl
= rrb
->pitch
>> 6;
2255 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2256 offset
+= ((y
& 15) >> 1) << 8;
2257 offset
+= (y
& 1) << 4;
2258 offset
+= (x
>> 6) << 11;
2259 offset
+= ((x
& 63) >> 3) << 5;
2260 offset
+= (x
& 7) << 1;
2262 nmacroblkpl
= rrb
->pitch
>> 7;
2263 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2264 offset
+= (y
& 7) << 8;
2265 offset
+= (x
>> 7) << 11;
2266 offset
+= ((x
& 127) >> 4) << 5;
2267 offset
+= (x
& 15) << 2;
2270 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2271 offset
+= (y
* nmicroblkpl
) << 5;
2272 offset
+= (x
>> 4) << 5;
2273 offset
+= (x
& 15) << 2;
2276 return &ptr
[offset
];
2279 GLubyte
*radeon_ptr(const struct radeon_renderbuffer
* rrb
,
2282 GLubyte
*ptr
= rrb
->bo
->ptr
;
2283 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2284 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2294 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2295 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2298 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2299 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2300 microblkxs
= 16 / rrb
->cpp
;
2301 macroblkxs
= 128 / rrb
->cpp
;
2302 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2303 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2304 offset
+= ((y
& 15) >> 1) << 8;
2305 offset
+= (y
& 1) << 4;
2306 offset
+= (x
/ macroblkxs
) << 11;
2307 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2308 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2310 microblkxs
= 32 / rrb
->cpp
;
2311 macroblkxs
= 256 / rrb
->cpp
;
2312 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2313 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2314 offset
+= (y
& 7) << 8;
2315 offset
+= (x
/ macroblkxs
) << 11;
2316 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2317 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2320 microblkxs
= 32 / rrb
->cpp
;
2321 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2322 offset
+= (y
* nmicroblkpl
) << 5;
2323 offset
+= (x
/ microblkxs
) << 5;
2324 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2327 return &ptr
[offset
];
2331 static void map_buffer(struct gl_renderbuffer
*rb
, GLboolean write
)
2333 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2337 r
= radeon_bo_map(rrb
->bo
, write
);
2339 fprintf(stderr
, "(%s) error(%d) mapping buffer.\n",
2345 static void unmap_buffer(struct gl_renderbuffer
*rb
)
2347 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2350 radeon_bo_unmap(rrb
->bo
);
2354 void radeonSpanRenderStart(GLcontext
* ctx
)
2356 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2359 rmesa
->vtbl
.flush_vertices(rmesa
);
2361 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2362 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2363 ctx
->Driver
.MapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2366 /* color draw buffers */
2367 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
2368 map_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
], GL_TRUE
);
2371 map_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
, GL_FALSE
);
2373 if (ctx
->DrawBuffer
->_DepthBuffer
) {
2374 map_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
, GL_TRUE
);
2376 if (ctx
->DrawBuffer
->_StencilBuffer
)
2377 map_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
, GL_TRUE
);
2379 /* The locking and wait for idle should really only be needed in classic mode.
2380 * In a future memory manager based implementation, this should become
2381 * unnecessary due to the fact that mapping our buffers, textures, etc.
2382 * should implicitly wait for any previous rendering commands that must
2384 LOCK_HARDWARE(rmesa
);
2385 radeonWaitForIdleLocked(rmesa
);
2388 void radeonSpanRenderFinish(GLcontext
* ctx
)
2390 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2393 UNLOCK_HARDWARE(rmesa
);
2395 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2396 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2397 ctx
->Driver
.UnmapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2400 /* color draw buffers */
2401 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++)
2402 unmap_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
]);
2404 unmap_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
);
2406 if (ctx
->DrawBuffer
->_DepthBuffer
)
2407 unmap_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
);
2408 if (ctx
->DrawBuffer
->_StencilBuffer
)
2409 unmap_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
);
2412 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa
, int size
)
2414 struct radeon_cs_space_check bos
[1];
2417 size
= MAX2(size
, MAX_DMA_BUF_SZ
* 16);
2419 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
2420 fprintf(stderr
, "%s\n", __FUNCTION__
);
2422 if (rmesa
->dma
.flush
) {
2423 rmesa
->dma
.flush(rmesa
->glCtx
);
2426 if (rmesa
->dma
.nr_released_bufs
> 4) {
2427 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2428 rmesa
->dma
.nr_released_bufs
= 0;
2431 if (rmesa
->dma
.current
) {
2432 radeon_bo_unref(rmesa
->dma
.current
);
2433 rmesa
->dma
.current
= 0;
2437 rmesa
->dma
.current
= radeon_bo_open(rmesa
->radeonScreen
->bom
,
2438 0, size
, 4, RADEON_GEM_DOMAIN_GTT
,
2441 if (!rmesa
->dma
.current
) {
2442 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2443 rmesa
->dma
.nr_released_bufs
= 0;
2447 rmesa
->dma
.current_used
= 0;
2448 rmesa
->dma
.current_vertexptr
= 0;
2450 bos
[0].bo
= rmesa
->dma
.current
;
2451 bos
[0].read_domains
= RADEON_GEM_DOMAIN_GTT
;
2452 bos
[0].write_domain
=0 ;
2453 bos
[0].new_accounted
= 0;
2456 ret
= radeon_cs_space_check(rmesa
->cmdbuf
.cs
, bos
, 1);
2457 if (ret
== RADEON_CS_SPACE_OP_TO_BIG
) {
2458 fprintf(stderr
,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
2460 } else if (ret
== RADEON_CS_SPACE_FLUSH
) {
2461 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2463 fprintf(stderr
,"flushed but still no space\n");
2471 radeon_bo_map(rmesa
->dma
.current
, 1);
2474 /* Allocates a region from rmesa->dma.current. If there isn't enough
2475 * space in current, grab a new buffer (and discard what was left of current)
2477 void radeonAllocDmaRegion(radeonContextPtr rmesa
,
2478 struct radeon_bo
**pbo
, int *poffset
,
2479 int bytes
, int alignment
)
2481 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2482 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
2484 if (rmesa
->dma
.flush
)
2485 rmesa
->dma
.flush(rmesa
->glCtx
);
2487 assert(rmesa
->dma
.current_used
== rmesa
->dma
.current_vertexptr
);
2490 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ alignment
) & ~alignment
;
2492 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_used
+ bytes
> rmesa
->dma
.current
->size
)
2493 radeonRefillCurrentDmaRegion(rmesa
, (bytes
+ 15) & ~15);
2495 *poffset
= rmesa
->dma
.current_used
;
2496 *pbo
= rmesa
->dma
.current
;
2497 radeon_bo_ref(*pbo
);
2499 /* Always align to at least 16 bytes */
2500 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ bytes
+ 15) & ~15;
2501 rmesa
->dma
.current_vertexptr
= rmesa
->dma
.current_used
;
2503 assert(rmesa
->dma
.current_used
<= rmesa
->dma
.current
->size
);
2506 void radeonReleaseDmaRegion(radeonContextPtr rmesa
)
2508 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2509 fprintf(stderr
, "%s %p\n", __FUNCTION__
, rmesa
->dma
.current
);
2510 if (rmesa
->dma
.current
) {
2511 rmesa
->dma
.nr_released_bufs
++;
2512 radeon_bo_unmap(rmesa
->dma
.current
);
2513 radeon_bo_unref(rmesa
->dma
.current
);
2515 rmesa
->dma
.current
= NULL
;
2519 /* Flush vertices in the current dma region.
2521 void rcommon_flush_last_swtcl_prim( GLcontext
*ctx
)
2523 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2524 struct radeon_dma
*dma
= &rmesa
->dma
;
2527 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2528 fprintf(stderr
, "%s\n", __FUNCTION__
);
2532 GLuint current_offset
= dma
->current_used
;
2534 assert (dma
->current_used
+
2535 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
2536 dma
->current_vertexptr
);
2538 radeon_bo_unmap(dma
->current
);
2539 if (dma
->current_used
!= dma
->current_vertexptr
) {
2540 dma
->current_used
= dma
->current_vertexptr
;
2542 rmesa
->vtbl
.swtcl_flush(ctx
, current_offset
);
2544 radeonReleaseDmaRegion(rmesa
);
2545 rmesa
->swtcl
.numverts
= 0;
2548 /* Alloc space in the current dma region.
2551 rcommonAllocDmaLowVerts( radeonContextPtr rmesa
, int nverts
, int vsize
)
2553 GLuint bytes
= vsize
* nverts
;
2556 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_vertexptr
+ bytes
> rmesa
->dma
.current
->size
) {
2557 radeonRefillCurrentDmaRegion( rmesa
, bytes
);
2560 if (!rmesa
->dma
.flush
) {
2561 rmesa
->glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
2562 rmesa
->dma
.flush
= rcommon_flush_last_swtcl_prim
;
2565 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
2566 ASSERT( rmesa
->dma
.flush
== rcommon_flush_last_swtcl_prim
);
2567 ASSERT( rmesa
->dma
.current_used
+
2568 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
2569 rmesa
->dma
.current_vertexptr
);
2571 // fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
2572 // rmesa->radeon.dma.current_vertexptr);
2573 head
= (rmesa
->dma
.current
->ptr
+ rmesa
->dma
.current_vertexptr
);
2574 rmesa
->dma
.current_vertexptr
+= bytes
;
2575 rmesa
->swtcl
.numverts
+= nverts
;