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 LOCK_HARDWARE(rmesa
);
625 ret
= rcommonFlushCmdBufLocked(rmesa
, caller
);
626 UNLOCK_HARDWARE(rmesa
);
629 fprintf(stderr
, "drmRadeonCmdBuffer: %d\n", ret
);
637 * Make sure that enough space is available in the command buffer
638 * by flushing if necessary.
640 * \param dwords The number of dwords we need to be free on the command buffer
642 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa
, int dwords
, const char *caller
)
644 if ((rmesa
->cmdbuf
.cs
->cdw
+ dwords
+ 128) > rmesa
->cmdbuf
.size
||
645 radeon_cs_need_flush(rmesa
->cmdbuf
.cs
)) {
646 rcommonFlushCmdBuf(rmesa
, caller
);
650 void rcommonInitCmdBuf(radeonContextPtr rmesa
, int max_state_size
)
653 /* Initialize command buffer */
654 size
= 256 * driQueryOptioni(&rmesa
->optionCache
,
655 "command_buffer_size");
656 if (size
< 2 * max_state_size
) {
657 size
= 2 * max_state_size
+ 65535;
662 size
= 64 * 1024 / 4;
664 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
)) {
665 fprintf(stderr
, "sizeof(drm_r300_cmd_header_t)=%zd\n",
666 sizeof(drm_r300_cmd_header_t
));
667 fprintf(stderr
, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
668 sizeof(drm_radeon_cmd_buffer_t
));
670 "Allocating %d bytes command buffer (max state is %d bytes)\n",
671 size
* 4, max_state_size
* 4);
674 if (rmesa
->radeonScreen
->kernel_mm
) {
675 int fd
= rmesa
->radeonScreen
->driScreen
->fd
;
676 rmesa
->cmdbuf
.csm
= radeon_cs_manager_gem_ctor(fd
);
678 rmesa
->cmdbuf
.csm
= radeon_cs_manager_legacy_ctor(rmesa
);
680 if (rmesa
->cmdbuf
.csm
== NULL
) {
681 /* FIXME: fatal error */
684 rmesa
->cmdbuf
.cs
= radeon_cs_create(rmesa
->cmdbuf
.csm
, size
);
685 assert(rmesa
->cmdbuf
.cs
!= NULL
);
686 rmesa
->cmdbuf
.size
= size
;
688 if (!rmesa
->radeonScreen
->kernel_mm
) {
689 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
690 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
692 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_VRAM
, rmesa
->radeonScreen
->texSize
[0]);
693 radeon_cs_set_limit(rmesa
->cmdbuf
.cs
, RADEON_GEM_DOMAIN_GTT
, rmesa
->radeonScreen
->gartTextures
.size
);
698 * Destroy the command buffer
700 void rcommonDestroyCmdBuf(radeonContextPtr rmesa
)
702 radeon_cs_destroy(rmesa
->cmdbuf
.cs
);
703 if (rmesa
->radeonScreen
->driScreen
->dri2
.enabled
|| rmesa
->radeonScreen
->kernel_mm
) {
704 radeon_cs_manager_gem_dtor(rmesa
->cmdbuf
.csm
);
706 radeon_cs_manager_legacy_dtor(rmesa
->cmdbuf
.csm
);
710 void rcommonBeginBatch(radeonContextPtr rmesa
, int n
,
713 const char *function
,
716 rcommonEnsureCmdBufSpace(rmesa
, n
, function
);
717 if (!rmesa
->cmdbuf
.cs
->cdw
&& dostate
) {
718 if (RADEON_DEBUG
& DEBUG_IOCTL
)
719 fprintf(stderr
, "Reemit state after flush (from %s)\n", function
);
720 rmesa
->vtbl
.emit_state(rmesa
);
722 radeon_cs_begin(rmesa
->cmdbuf
.cs
, n
, file
, function
, line
);
727 /* Return various strings for glGetString().
729 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
731 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
732 static char buffer
[128];
736 if (IS_R300_CLASS(radeon
->radeonScreen
))
737 return (GLubyte
*) "DRI R300 Project";
739 return (GLubyte
*) "Tungsten Graphics, Inc.";
744 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
745 radeon
->radeonScreen
->AGPMode
;
746 const char* chipname
;
750 if (IS_R300_CLASS(radeon
->radeonScreen
))
755 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
758 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
759 sprintf(&buffer
[offset
], " %sTCL",
760 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
763 sprintf(&buffer
[offset
], " %sTCL",
764 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
768 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
769 strcat(buffer
, " DRI2");
771 return (GLubyte
*) buffer
;
779 /* Initialize the driver's misc functions.
781 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
783 functions
->GetString
= radeonGetString
;
787 * Create and initialize all common fields of the context,
788 * including the Mesa context itself.
790 GLboolean
radeonInitContext(radeonContextPtr radeon
,
791 struct dd_function_table
* functions
,
792 const __GLcontextModes
* glVisual
,
793 __DRIcontextPrivate
* driContextPriv
,
794 void *sharedContextPrivate
)
796 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
797 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
802 /* Fill in additional standard functions. */
803 radeonInitDriverFuncs(functions
);
805 radeon
->radeonScreen
= screen
;
806 /* Allocate and initialize the Mesa context */
807 if (sharedContextPrivate
)
808 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
811 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
812 functions
, (void *)radeon
);
817 driContextPriv
->driverPrivate
= radeon
;
820 radeon
->dri
.context
= driContextPriv
;
821 radeon
->dri
.screen
= sPriv
;
822 radeon
->dri
.drawable
= NULL
;
823 radeon
->dri
.readable
= NULL
;
824 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
825 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
826 radeon
->dri
.fd
= sPriv
->fd
;
827 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
829 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
830 screen
->sarea_priv_offset
);
833 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
834 radeon
->iw
.irq_seq
= -1;
835 radeon
->irqsEmitted
= 0;
836 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
837 radeon
->radeonScreen
->irq
);
839 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
841 if (!radeon
->do_irqs
)
843 "IRQ's not enabled, falling back to %s: %d %d\n",
844 radeon
->do_usleeps
? "usleeps" : "busy waits",
845 fthrottle_mode
, radeon
->radeonScreen
->irq
);
847 (*sPriv
->systemTime
->getUST
) (&radeon
->swap_ust
);
853 * Cleanup common context fields.
854 * Called by r200DestroyContext/r300DestroyContext
856 void radeonCleanupContext(radeonContextPtr radeon
)
859 struct radeon_renderbuffer
*rb
;
862 fb
= (void*)radeon
->dri
.drawable
->driverPrivate
;
863 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
865 radeon_bo_unref(rb
->bo
);
868 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
870 radeon_bo_unref(rb
->bo
);
873 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
875 radeon_bo_unref(rb
->bo
);
878 fb
= (void*)radeon
->dri
.readable
->driverPrivate
;
879 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
881 radeon_bo_unref(rb
->bo
);
884 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
886 radeon_bo_unref(rb
->bo
);
889 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
891 radeon_bo_unref(rb
->bo
);
895 /* _mesa_destroy_context() might result in calls to functions that
896 * depend on the DriverCtx, so don't set it to NULL before.
898 * radeon->glCtx->DriverCtx = NULL;
901 /* free the Mesa context */
902 _mesa_destroy_context(radeon
->glCtx
);
904 /* free the option cache */
905 driDestroyOptionCache(&radeon
->optionCache
);
907 if (radeon
->state
.scissor
.pClipRects
) {
908 FREE(radeon
->state
.scissor
.pClipRects
);
909 radeon
->state
.scissor
.pClipRects
= 0;
911 track
= fopen("/tmp/tracklog", "w");
913 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
919 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
922 /* if radeon->fake */
923 struct radeon_renderbuffer
*rb
;
925 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
928 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
929 radeon
->radeonScreen
->frontOffset
,
932 RADEON_GEM_DOMAIN_VRAM
,
935 rb
->cpp
= radeon
->radeonScreen
->cpp
;
936 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
938 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
940 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
941 radeon
->radeonScreen
->backOffset
,
944 RADEON_GEM_DOMAIN_VRAM
,
947 rb
->cpp
= radeon
->radeonScreen
->cpp
;
948 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
950 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
952 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
953 radeon
->radeonScreen
->depthOffset
,
956 RADEON_GEM_DOMAIN_VRAM
,
959 rb
->cpp
= radeon
->radeonScreen
->cpp
;
960 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
965 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
968 int size
= 4096*4096*4;
969 /* if radeon->fake */
970 struct radeon_renderbuffer
*rb
;
972 if (radeon
->radeonScreen
->kernel_mm
) {
973 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
978 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
980 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
981 radeon
->radeonScreen
->frontOffset
+
982 radeon
->radeonScreen
->fbLocation
,
985 RADEON_GEM_DOMAIN_VRAM
,
988 rb
->cpp
= radeon
->radeonScreen
->cpp
;
989 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
991 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
993 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
994 radeon
->radeonScreen
->backOffset
+
995 radeon
->radeonScreen
->fbLocation
,
998 RADEON_GEM_DOMAIN_VRAM
,
1001 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1002 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
1004 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
1006 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1007 radeon
->radeonScreen
->depthOffset
+
1008 radeon
->radeonScreen
->fbLocation
,
1011 RADEON_GEM_DOMAIN_VRAM
,
1014 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1015 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
1021 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
1023 unsigned int attachments
[10];
1024 __DRIbuffer
*buffers
;
1025 __DRIscreen
*screen
;
1026 struct radeon_renderbuffer
*rb
;
1028 GLframebuffer
*draw
;
1029 radeonContextPtr radeon
;
1031 draw
= drawable
->driverPrivate
;
1032 screen
= context
->driScreenPriv
;
1033 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1035 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
1036 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
1038 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
1039 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
1041 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
1042 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
1045 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
1050 drawable
->loaderPrivate
);
1051 if (buffers
== NULL
)
1054 /* set one cliprect to cover the whole drawable */
1057 drawable
->backX
= 0;
1058 drawable
->backY
= 0;
1059 drawable
->numClipRects
= 1;
1060 drawable
->pClipRects
[0].x1
= 0;
1061 drawable
->pClipRects
[0].y1
= 0;
1062 drawable
->pClipRects
[0].x2
= drawable
->w
;
1063 drawable
->pClipRects
[0].y2
= drawable
->h
;
1064 drawable
->numBackClipRects
= 1;
1065 drawable
->pBackClipRects
[0].x1
= 0;
1066 drawable
->pBackClipRects
[0].y1
= 0;
1067 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
1068 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
1069 for (i
= 0; i
< count
; i
++) {
1070 switch (buffers
[i
].attachment
) {
1071 case __DRI_BUFFER_FRONT_LEFT
:
1072 rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1074 radeon_bo_unref(rb
->bo
);
1077 rb
->cpp
= buffers
[i
].cpp
;
1078 rb
->pitch
= buffers
[i
].pitch
;
1079 rb
->width
= drawable
->w
;
1080 rb
->height
= drawable
->h
;
1081 rb
->has_surface
= 0;
1082 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1086 RADEON_GEM_DOMAIN_VRAM
,
1088 if (rb
->bo
== NULL
) {
1089 fprintf(stderr
, "failled to attach front %d\n",
1093 case __DRI_BUFFER_BACK_LEFT
:
1094 rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1096 radeon_bo_unref(rb
->bo
);
1099 rb
->cpp
= buffers
[i
].cpp
;
1100 rb
->pitch
= buffers
[i
].pitch
;
1101 rb
->width
= drawable
->w
;
1102 rb
->height
= drawable
->h
;
1103 rb
->has_surface
= 0;
1104 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1108 RADEON_GEM_DOMAIN_VRAM
,
1111 case __DRI_BUFFER_DEPTH
:
1112 rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1114 radeon_bo_unref(rb
->bo
);
1117 rb
->cpp
= buffers
[i
].cpp
;
1118 rb
->pitch
= buffers
[i
].pitch
;
1119 rb
->width
= drawable
->w
;
1120 rb
->height
= drawable
->h
;
1121 rb
->has_surface
= 0;
1122 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1126 RADEON_GEM_DOMAIN_VRAM
,
1129 case __DRI_BUFFER_STENCIL
:
1131 case __DRI_BUFFER_ACCUM
:
1134 "unhandled buffer attach event, attacment type %d\n",
1135 buffers
[i
].attachment
);
1139 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1140 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
1143 /* Force the context `c' to be the current context and associate with it
1146 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
1147 __DRIdrawablePrivate
* driDrawPriv
,
1148 __DRIdrawablePrivate
* driReadPriv
)
1150 radeonContextPtr radeon
;
1151 GLframebuffer
*dfb
, *rfb
;
1153 if (!driContextPriv
) {
1154 if (RADEON_DEBUG
& DEBUG_DRI
)
1155 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
1156 _mesa_make_current(NULL
, NULL
, NULL
);
1159 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
1160 dfb
= driDrawPriv
->driverPrivate
;
1161 rfb
= driReadPriv
->driverPrivate
;
1163 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1164 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
1165 if (driDrawPriv
!= driReadPriv
)
1166 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
1167 radeon
->state
.color
.rrb
=
1168 (void *)dfb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1169 radeon
->state
.depth
.rrb
=
1170 (void *)dfb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1174 if (RADEON_DEBUG
& DEBUG_DRI
)
1175 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
, radeon
->glCtx
);
1177 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
1178 if (driReadPriv
!= driDrawPriv
)
1179 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
1181 if (!driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1182 radeon_make_renderbuffer_current(radeon
, dfb
);
1185 _mesa_make_current(radeon
->glCtx
, dfb
, rfb
);
1187 if (radeon
->dri
.drawable
!= driDrawPriv
) {
1188 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
1189 driDrawPriv
->vblFlags
=
1190 (radeon
->radeonScreen
->irq
!= 0)
1191 ? driGetDefaultVBlankFlags(&radeon
->
1193 : VBLANK_FLAG_NO_IRQ
;
1195 driDrawableInitVBlank(driDrawPriv
);
1199 radeon
->dri
.readable
= driReadPriv
;
1201 if (radeon
->dri
.drawable
!= driDrawPriv
||
1202 radeon
->lastStamp
!= driDrawPriv
->lastStamp
) {
1203 radeon
->dri
.drawable
= driDrawPriv
;
1205 radeonSetCliprects(radeon
);
1206 radeon
->vtbl
.update_viewport_offset(radeon
->glCtx
);
1209 _mesa_update_state(radeon
->glCtx
);
1211 if (!driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1212 radeonUpdatePageFlipping(radeon
);
1215 if (RADEON_DEBUG
& DEBUG_DRI
)
1216 fprintf(stderr
, "End %s\n", __FUNCTION__
);
1221 #if defined(USE_X86_ASM)
1222 #define COPY_DWORDS( dst, src, nr ) \
1225 __asm__ __volatile__( "rep ; movsl" \
1226 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
1229 "S" ((long)src) ); \
1232 #define COPY_DWORDS( dst, src, nr ) \
1235 for ( j = 0 ; j < nr ; j++ ) \
1236 dst[j] = ((int *)src)[j]; \
1241 static void radeonEmitVec4(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1245 if (RADEON_DEBUG
& DEBUG_VERTS
)
1246 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1247 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1250 COPY_DWORDS(out
, data
, count
);
1252 for (i
= 0; i
< count
; i
++) {
1253 out
[0] = *(int *)data
;
1259 static void radeonEmitVec8(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1263 if (RADEON_DEBUG
& DEBUG_VERTS
)
1264 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1265 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1268 COPY_DWORDS(out
, data
, count
* 2);
1270 for (i
= 0; i
< count
; i
++) {
1271 out
[0] = *(int *)data
;
1272 out
[1] = *(int *)(data
+ 4);
1278 static void radeonEmitVec12(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1282 if (RADEON_DEBUG
& DEBUG_VERTS
)
1283 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1284 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1287 COPY_DWORDS(out
, data
, count
* 3);
1290 for (i
= 0; i
< count
; i
++) {
1291 out
[0] = *(int *)data
;
1292 out
[1] = *(int *)(data
+ 4);
1293 out
[2] = *(int *)(data
+ 8);
1299 static void radeonEmitVec16(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1303 if (RADEON_DEBUG
& DEBUG_VERTS
)
1304 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1305 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1308 COPY_DWORDS(out
, data
, count
* 4);
1310 for (i
= 0; i
< count
; i
++) {
1311 out
[0] = *(int *)data
;
1312 out
[1] = *(int *)(data
+ 4);
1313 out
[2] = *(int *)(data
+ 8);
1314 out
[3] = *(int *)(data
+ 12);
1320 void rcommon_emit_vector(GLcontext
* ctx
, struct radeon_aos
*aos
,
1321 GLvoid
* data
, int size
, int stride
, int count
)
1323 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1327 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* 4, 32);
1331 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* count
* 4, 32);
1335 aos
->components
= size
;
1338 out
= (uint32_t*)((char*)aos
->bo
->ptr
+ aos
->offset
);
1340 case 1: radeonEmitVec4(out
, data
, stride
, count
); break;
1341 case 2: radeonEmitVec8(out
, data
, stride
, count
); break;
1342 case 3: radeonEmitVec12(out
, data
, stride
, count
); break;
1343 case 4: radeonEmitVec16(out
, data
, stride
, count
); break;
1351 void radeon_print_state_atom( struct radeon_state_atom
*state
)
1355 fprintf(stderr
, "emit %s/%d\n", state
->name
, state
->cmd_size
);
1357 if (RADEON_DEBUG
& DEBUG_VERBOSE
)
1358 for (i
= 0 ; i
< state
->cmd_size
; i
++)
1359 fprintf(stderr
, "\t%s[%d]: %x\n", state
->name
, i
, state
->cmd
[i
]);
1365 * Allocate an empty texture image object.
1367 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
1369 return CALLOC(sizeof(radeon_texture_image
));
1373 * Free memory associated with this texture image.
1375 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
1377 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
1380 radeon_miptree_unreference(image
->mt
);
1382 assert(!image
->base
.Data
);
1384 _mesa_free_texture_image_data(ctx
, timage
);
1387 radeon_bo_unref(image
->bo
);
1392 /* Set Data pointer and additional data for mapped texture image */
1393 static void teximage_set_map_data(radeon_texture_image
*image
)
1395 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1396 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
1397 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
1402 * Map a single texture image for glTexImage and friends.
1404 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
1407 assert(!image
->base
.Data
);
1409 radeon_bo_map(image
->mt
->bo
, write_enable
);
1410 teximage_set_map_data(image
);
1415 void radeon_teximage_unmap(radeon_texture_image
*image
)
1418 assert(image
->base
.Data
);
1420 image
->base
.Data
= 0;
1421 radeon_bo_unmap(image
->mt
->bo
);
1426 * Map a validated texture for reading during software rendering.
1428 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1430 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1433 assert(texObj
->_Complete
);
1436 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
1437 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1438 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1439 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
1443 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1445 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1448 assert(texObj
->_Complete
);
1451 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1452 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1453 texObj
->Image
[face
][level
]->Data
= 0;
1455 radeon_bo_unmap(t
->mt
->bo
);
1458 GLuint
radeon_face_for_target(GLenum target
)
1461 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
1462 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
1463 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
1464 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
1465 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
1466 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
1467 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
1474 * Wraps Mesa's implementation to ensure that the base level image is mapped.
1476 * This relies on internal details of _mesa_generate_mipmap, in particular
1477 * the fact that the memory for recreated texture images is always freed.
1479 void radeon_generate_mipmap(GLcontext
*ctx
, GLenum target
,
1480 struct gl_texture_object
*texObj
)
1482 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1483 GLuint nr_faces
= (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
1487 _mesa_generate_mipmap(ctx
, target
, texObj
);
1489 for (face
= 0; face
< nr_faces
; face
++) {
1490 for (i
= texObj
->BaseLevel
+ 1; i
< texObj
->MaxLevel
; i
++) {
1491 radeon_texture_image
*image
;
1493 image
= get_radeon_texture_image(texObj
->Image
[face
][i
]);
1499 image
->mtface
= face
;
1501 radeon_miptree_unreference(image
->mt
);
1508 void radeonGenerateMipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
1510 GLuint face
= radeon_face_for_target(target
);
1511 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
1513 radeon_teximage_map(baseimage
, GL_FALSE
);
1514 radeon_generate_mipmap(ctx
, target
, texObj
);
1515 radeon_teximage_unmap(baseimage
);
1519 /* try to find a format which will only need a memcopy */
1520 static const struct gl_texture_format
*radeonChoose8888TexFormat(GLenum srcFormat
,
1523 const GLuint ui
= 1;
1524 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
1526 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1527 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1528 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1529 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
1530 return &_mesa_texformat_rgba8888
;
1531 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1532 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1533 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1534 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
1535 return &_mesa_texformat_rgba8888_rev
;
1536 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1537 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1538 return &_mesa_texformat_argb8888_rev
;
1539 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1540 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1541 return &_mesa_texformat_argb8888
;
1543 return _dri_texformat_argb8888
;
1546 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
1547 GLint internalFormat
,
1551 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1552 const GLboolean do32bpt
=
1553 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
1554 const GLboolean force16bpt
=
1555 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
1559 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
1560 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
1561 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
1562 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
1565 switch (internalFormat
) {
1568 case GL_COMPRESSED_RGBA
:
1570 case GL_UNSIGNED_INT_10_10_10_2
:
1571 case GL_UNSIGNED_INT_2_10_10_10_REV
:
1572 return do32bpt
? _dri_texformat_argb8888
:
1573 _dri_texformat_argb1555
;
1574 case GL_UNSIGNED_SHORT_4_4_4_4
:
1575 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1576 return _dri_texformat_argb4444
;
1577 case GL_UNSIGNED_SHORT_5_5_5_1
:
1578 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1579 return _dri_texformat_argb1555
;
1581 return do32bpt
? radeonChoose8888TexFormat(format
, type
) :
1582 _dri_texformat_argb4444
;
1587 case GL_COMPRESSED_RGB
:
1589 case GL_UNSIGNED_SHORT_4_4_4_4
:
1590 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1591 return _dri_texformat_argb4444
;
1592 case GL_UNSIGNED_SHORT_5_5_5_1
:
1593 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1594 return _dri_texformat_argb1555
;
1595 case GL_UNSIGNED_SHORT_5_6_5
:
1596 case GL_UNSIGNED_SHORT_5_6_5_REV
:
1597 return _dri_texformat_rgb565
;
1599 return do32bpt
? _dri_texformat_argb8888
:
1600 _dri_texformat_rgb565
;
1607 return !force16bpt
?
1608 radeonChoose8888TexFormat(format
,
1609 type
) : _dri_texformat_argb4444
;
1613 return _dri_texformat_argb4444
;
1616 return _dri_texformat_argb1555
;
1622 return !force16bpt
? _dri_texformat_argb8888
:
1623 _dri_texformat_rgb565
;
1628 return _dri_texformat_rgb565
;
1635 case GL_COMPRESSED_ALPHA
:
1636 return _dri_texformat_a8
;
1642 case GL_LUMINANCE12
:
1643 case GL_LUMINANCE16
:
1644 case GL_COMPRESSED_LUMINANCE
:
1645 return _dri_texformat_l8
;
1648 case GL_LUMINANCE_ALPHA
:
1649 case GL_LUMINANCE4_ALPHA4
:
1650 case GL_LUMINANCE6_ALPHA2
:
1651 case GL_LUMINANCE8_ALPHA8
:
1652 case GL_LUMINANCE12_ALPHA4
:
1653 case GL_LUMINANCE12_ALPHA12
:
1654 case GL_LUMINANCE16_ALPHA16
:
1655 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1656 return _dri_texformat_al88
;
1661 case GL_INTENSITY12
:
1662 case GL_INTENSITY16
:
1663 case GL_COMPRESSED_INTENSITY
:
1664 return _dri_texformat_i8
;
1667 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
1668 type
== GL_UNSIGNED_BYTE
)
1669 return &_mesa_texformat_ycbcr
;
1671 return &_mesa_texformat_ycbcr_rev
;
1675 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1676 return &_mesa_texformat_rgb_dxt1
;
1678 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1679 return &_mesa_texformat_rgba_dxt1
;
1683 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1684 return &_mesa_texformat_rgba_dxt3
;
1686 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1687 return &_mesa_texformat_rgba_dxt5
;
1689 case GL_ALPHA16F_ARB
:
1690 return &_mesa_texformat_alpha_float16
;
1691 case GL_ALPHA32F_ARB
:
1692 return &_mesa_texformat_alpha_float32
;
1693 case GL_LUMINANCE16F_ARB
:
1694 return &_mesa_texformat_luminance_float16
;
1695 case GL_LUMINANCE32F_ARB
:
1696 return &_mesa_texformat_luminance_float32
;
1697 case GL_LUMINANCE_ALPHA16F_ARB
:
1698 return &_mesa_texformat_luminance_alpha_float16
;
1699 case GL_LUMINANCE_ALPHA32F_ARB
:
1700 return &_mesa_texformat_luminance_alpha_float32
;
1701 case GL_INTENSITY16F_ARB
:
1702 return &_mesa_texformat_intensity_float16
;
1703 case GL_INTENSITY32F_ARB
:
1704 return &_mesa_texformat_intensity_float32
;
1706 return &_mesa_texformat_rgba_float16
;
1708 return &_mesa_texformat_rgba_float32
;
1709 case GL_RGBA16F_ARB
:
1710 return &_mesa_texformat_rgba_float16
;
1711 case GL_RGBA32F_ARB
:
1712 return &_mesa_texformat_rgba_float32
;
1714 case GL_DEPTH_COMPONENT
:
1715 case GL_DEPTH_COMPONENT16
:
1716 case GL_DEPTH_COMPONENT24
:
1717 case GL_DEPTH_COMPONENT32
:
1720 case GL_UNSIGNED_BYTE
:
1721 case GL_UNSIGNED_SHORT
:
1722 return &_mesa_texformat_z16
;
1723 case GL_UNSIGNED_INT
:
1724 return &_mesa_texformat_z32
;
1725 case GL_UNSIGNED_INT_24_8_EXT
:
1727 return &_mesa_texformat_z24_s8
;
1730 return &_mesa_texformat_z16
;
1735 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
1736 (int)internalFormat
);
1740 return NULL
; /* never get here */
1744 * All glTexImage calls go through this function.
1746 static void radeon_teximage(
1747 GLcontext
*ctx
, int dims
,
1748 GLint face
, GLint level
,
1749 GLint internalFormat
,
1750 GLint width
, GLint height
, GLint depth
,
1752 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1753 const struct gl_pixelstore_attrib
*packing
,
1754 struct gl_texture_object
*texObj
,
1755 struct gl_texture_image
*texImage
,
1758 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1759 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1760 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1762 rmesa
->vtbl
.flush_vertices(rmesa
);
1764 t
->validated
= GL_FALSE
;
1766 /* Choose and fill in the texture format for this image */
1767 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
);
1768 _mesa_set_fetch_functions(texImage
, dims
);
1770 if (texImage
->TexFormat
->TexelBytes
== 0) {
1771 texImage
->IsCompressed
= GL_TRUE
;
1772 texImage
->CompressedSize
=
1773 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
1774 texImage
->Height
, texImage
->Depth
,
1775 texImage
->TexFormat
->MesaFormat
);
1777 texImage
->IsCompressed
= GL_FALSE
;
1778 texImage
->CompressedSize
= 0;
1781 /* Allocate memory for image */
1782 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
1785 radeon_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
1786 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
1788 image
->mtlevel
= level
- t
->mt
->firstLevel
;
1789 image
->mtface
= face
;
1790 radeon_miptree_reference(t
->mt
);
1793 if (texImage
->IsCompressed
) {
1794 size
= texImage
->CompressedSize
;
1796 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
1798 texImage
->Data
= _mesa_alloc_texmemory(size
);
1801 /* Upload texture image; note that the spec allows pixels to be NULL */
1803 pixels
= _mesa_validate_pbo_compressed_teximage(
1804 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
1806 pixels
= _mesa_validate_pbo_teximage(
1807 ctx
, dims
, width
, height
, depth
,
1808 format
, type
, pixels
, packing
, "glTexImage");
1812 radeon_teximage_map(image
, GL_TRUE
);
1815 memcpy(texImage
->Data
, pixels
, imageSize
);
1817 GLuint dstRowStride
;
1819 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1820 dstRowStride
= lvl
->rowstride
;
1822 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
1824 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
1825 texImage
->_BaseFormat
,
1826 texImage
->TexFormat
,
1827 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
1829 texImage
->ImageOffsets
,
1830 width
, height
, depth
,
1831 format
, type
, pixels
, packing
))
1832 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
1837 /* SGIS_generate_mipmap */
1838 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1839 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
1841 radeon_teximage_unmap(image
);
1843 _mesa_unmap_teximage_pbo(ctx
, packing
);
1848 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1849 GLint internalFormat
,
1850 GLint width
, GLint border
,
1851 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1852 const struct gl_pixelstore_attrib
*packing
,
1853 struct gl_texture_object
*texObj
,
1854 struct gl_texture_image
*texImage
)
1856 radeon_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
1857 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1860 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1861 GLint internalFormat
,
1862 GLint width
, GLint height
, GLint border
,
1863 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1864 const struct gl_pixelstore_attrib
*packing
,
1865 struct gl_texture_object
*texObj
,
1866 struct gl_texture_image
*texImage
)
1869 GLuint face
= radeon_face_for_target(target
);
1871 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1872 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1875 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
1876 GLint level
, GLint internalFormat
,
1877 GLint width
, GLint height
, GLint border
,
1878 GLsizei imageSize
, const GLvoid
* data
,
1879 struct gl_texture_object
*texObj
,
1880 struct gl_texture_image
*texImage
)
1882 GLuint face
= radeon_face_for_target(target
);
1884 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1885 imageSize
, 0, 0, data
, 0, texObj
, texImage
, 1);
1888 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
1889 GLint internalFormat
,
1890 GLint width
, GLint height
, GLint depth
,
1892 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1893 const struct gl_pixelstore_attrib
*packing
,
1894 struct gl_texture_object
*texObj
,
1895 struct gl_texture_image
*texImage
)
1897 radeon_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
1898 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1902 * Update a subregion of the given texture image.
1904 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, int level
,
1905 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1906 GLsizei width
, GLsizei height
, GLsizei depth
,
1907 GLenum format
, GLenum type
,
1908 const GLvoid
* pixels
,
1909 const struct gl_pixelstore_attrib
*packing
,
1910 struct gl_texture_object
*texObj
,
1911 struct gl_texture_image
*texImage
,
1914 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1915 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1916 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1918 rmesa
->vtbl
.flush_vertices(rmesa
);
1920 t
->validated
= GL_FALSE
;
1921 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
1922 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
1926 radeon_teximage_map(image
, GL_TRUE
);
1929 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1930 dstRowStride
= lvl
->rowstride
;
1932 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
1935 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
1936 texImage
->TexFormat
, texImage
->Data
,
1937 xoffset
, yoffset
, zoffset
,
1939 texImage
->ImageOffsets
,
1940 width
, height
, depth
,
1941 format
, type
, pixels
, packing
))
1942 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
1947 /* GL_SGIS_generate_mipmap */
1948 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1949 radeon_generate_mipmap(ctx
, texObj
->Target
, texObj
);
1951 radeon_teximage_unmap(image
);
1953 _mesa_unmap_teximage_pbo(ctx
, packing
);
1958 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1961 GLenum format
, GLenum type
,
1962 const GLvoid
* pixels
,
1963 const struct gl_pixelstore_attrib
*packing
,
1964 struct gl_texture_object
*texObj
,
1965 struct gl_texture_image
*texImage
)
1967 radeon_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1,
1968 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1971 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1972 GLint xoffset
, GLint yoffset
,
1973 GLsizei width
, GLsizei height
,
1974 GLenum format
, GLenum type
,
1975 const GLvoid
* pixels
,
1976 const struct gl_pixelstore_attrib
*packing
,
1977 struct gl_texture_object
*texObj
,
1978 struct gl_texture_image
*texImage
)
1980 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
,
1981 1, format
, type
, pixels
, packing
, texObj
, texImage
,
1985 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
1986 GLint level
, GLint xoffset
,
1987 GLint yoffset
, GLsizei width
,
1988 GLsizei height
, GLenum format
,
1989 GLsizei imageSize
, const GLvoid
* data
,
1990 struct gl_texture_object
*texObj
,
1991 struct gl_texture_image
*texImage
)
1993 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
1994 format
, 0, data
, 0, texObj
, texImage
, 1);
1998 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
1999 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2000 GLsizei width
, GLsizei height
, GLsizei depth
,
2001 GLenum format
, GLenum type
,
2002 const GLvoid
* pixels
,
2003 const struct gl_pixelstore_attrib
*packing
,
2004 struct gl_texture_object
*texObj
,
2005 struct gl_texture_image
*texImage
)
2007 radeon_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
,
2008 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
2011 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
2012 GLuint numrows
, GLuint rowsize
)
2014 assert(rowsize
<= dststride
);
2015 assert(rowsize
<= srcstride
);
2017 if (rowsize
== srcstride
&& rowsize
== dststride
) {
2018 memcpy(dst
, src
, numrows
*rowsize
);
2021 for(i
= 0; i
< numrows
; ++i
) {
2022 memcpy(dst
, src
, rowsize
);
2031 * Ensure that the given image is stored in the given miptree from now on.
2033 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
2035 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
2036 unsigned char *dest
;
2038 assert(image
->mt
!= mt
);
2039 assert(dstlvl
->width
== image
->base
.Width
);
2040 assert(dstlvl
->height
== image
->base
.Height
);
2041 assert(dstlvl
->depth
== image
->base
.Depth
);
2043 radeon_bo_map(mt
->bo
, GL_TRUE
);
2044 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
2047 /* Format etc. should match, so we really just need a memcpy().
2048 * In fact, that memcpy() could be done by the hardware in many
2049 * cases, provided that we have a proper memory manager.
2051 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
];
2053 assert(srclvl
->size
== dstlvl
->size
);
2054 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
2056 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
2058 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
2060 radeon_bo_unmap(image
->mt
->bo
);
2062 radeon_miptree_unreference(image
->mt
);
2064 uint srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
2066 // if (mt->tilebits)
2067 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
2069 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
2070 image
->base
.Height
* image
->base
.Depth
, srcrowstride
);
2072 _mesa_free_texmemory(image
->base
.Data
);
2073 image
->base
.Data
= 0;
2076 radeon_bo_unmap(mt
->bo
);
2079 image
->mtface
= face
;
2080 image
->mtlevel
= level
;
2081 radeon_miptree_reference(image
->mt
);
2084 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
2086 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2087 radeonTexObj
*t
= radeon_tex_obj(texObj
);
2088 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
2091 if (t
->validated
|| t
->image_override
)
2094 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2095 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
2097 if (baseimage
->base
.Border
> 0)
2100 /* Ensure a matching miptree exists.
2102 * Differing mipmap trees can result when the app uses TexImage to
2103 * change texture dimensions.
2105 * Prefer to use base image's miptree if it
2106 * exists, since that most likely contains more valid data (remember
2107 * that the base level is usually significantly larger than the rest
2108 * of the miptree, so cubemaps are the only possible exception).
2110 if (baseimage
->mt
&&
2111 baseimage
->mt
!= t
->mt
&&
2112 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
2113 radeon_miptree_unreference(t
->mt
);
2114 t
->mt
= baseimage
->mt
;
2115 radeon_miptree_reference(t
->mt
);
2116 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
2117 radeon_miptree_unreference(t
->mt
);
2122 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2123 fprintf(stderr
, " Allocate new miptree\n");
2124 radeon_try_alloc_miptree(rmesa
, t
, &baseimage
->base
, 0, texObj
->BaseLevel
);
2126 _mesa_problem(ctx
, "r300_validate_texture failed to alloc miptree");
2131 /* Ensure all images are stored in the single main miptree */
2132 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
2133 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
2134 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
2135 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2136 fprintf(stderr
, " face %i, level %i... ", face
, level
);
2137 if (t
->mt
== image
->mt
) {
2138 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2139 fprintf(stderr
, "OK\n");
2143 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2144 fprintf(stderr
, "migrating\n");
2145 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
2153 GLubyte
*radeon_ptr32(const struct radeon_renderbuffer
* rrb
,
2156 GLubyte
*ptr
= rrb
->bo
->ptr
;
2157 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2158 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2166 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2167 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2170 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2171 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2172 nmacroblkpl
= rrb
->pitch
>> 5;
2173 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2174 offset
+= ((y
& 15) >> 1) << 8;
2175 offset
+= (y
& 1) << 4;
2176 offset
+= (x
>> 5) << 11;
2177 offset
+= ((x
& 31) >> 2) << 5;
2178 offset
+= (x
& 3) << 2;
2180 nmacroblkpl
= rrb
->pitch
>> 6;
2181 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2182 offset
+= (y
& 7) << 8;
2183 offset
+= (x
>> 6) << 11;
2184 offset
+= ((x
& 63) >> 3) << 5;
2185 offset
+= (x
& 7) << 2;
2188 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2189 offset
+= (y
* nmicroblkpl
) << 5;
2190 offset
+= (x
>> 3) << 5;
2191 offset
+= (x
& 7) << 2;
2194 return &ptr
[offset
];
2197 GLubyte
*radeon_ptr16(const struct radeon_renderbuffer
* rrb
,
2200 GLubyte
*ptr
= rrb
->bo
->ptr
;
2201 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2202 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2210 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2211 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2214 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2215 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2216 nmacroblkpl
= rrb
->pitch
>> 6;
2217 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2218 offset
+= ((y
& 15) >> 1) << 8;
2219 offset
+= (y
& 1) << 4;
2220 offset
+= (x
>> 6) << 11;
2221 offset
+= ((x
& 63) >> 3) << 5;
2222 offset
+= (x
& 7) << 1;
2224 nmacroblkpl
= rrb
->pitch
>> 7;
2225 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2226 offset
+= (y
& 7) << 8;
2227 offset
+= (x
>> 7) << 11;
2228 offset
+= ((x
& 127) >> 4) << 5;
2229 offset
+= (x
& 15) << 2;
2232 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2233 offset
+= (y
* nmicroblkpl
) << 5;
2234 offset
+= (x
>> 4) << 5;
2235 offset
+= (x
& 15) << 2;
2238 return &ptr
[offset
];
2241 GLubyte
*radeon_ptr(const struct radeon_renderbuffer
* rrb
,
2244 GLubyte
*ptr
= rrb
->bo
->ptr
;
2245 const __DRIdrawablePrivate
*dPriv
= rrb
->dPriv
;
2246 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2256 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2257 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2260 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2261 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2262 microblkxs
= 16 / rrb
->cpp
;
2263 macroblkxs
= 128 / rrb
->cpp
;
2264 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2265 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2266 offset
+= ((y
& 15) >> 1) << 8;
2267 offset
+= (y
& 1) << 4;
2268 offset
+= (x
/ macroblkxs
) << 11;
2269 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2270 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2272 microblkxs
= 32 / rrb
->cpp
;
2273 macroblkxs
= 256 / rrb
->cpp
;
2274 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2275 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2276 offset
+= (y
& 7) << 8;
2277 offset
+= (x
/ macroblkxs
) << 11;
2278 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2279 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2282 microblkxs
= 32 / rrb
->cpp
;
2283 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2284 offset
+= (y
* nmicroblkpl
) << 5;
2285 offset
+= (x
/ microblkxs
) << 5;
2286 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2289 return &ptr
[offset
];
2293 static void map_buffer(struct gl_renderbuffer
*rb
, GLboolean write
)
2295 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2299 r
= radeon_bo_map(rrb
->bo
, write
);
2301 fprintf(stderr
, "(%s) error(%d) mapping buffer.\n",
2307 static void unmap_buffer(struct gl_renderbuffer
*rb
)
2309 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2312 radeon_bo_unmap(rrb
->bo
);
2316 void radeonSpanRenderStart(GLcontext
* ctx
)
2318 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2321 rmesa
->vtbl
.flush_vertices(rmesa
);
2323 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2324 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2325 ctx
->Driver
.MapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2328 /* color draw buffers */
2329 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
2330 map_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
], GL_TRUE
);
2333 map_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
, GL_FALSE
);
2335 if (ctx
->DrawBuffer
->_DepthBuffer
) {
2336 map_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
, GL_TRUE
);
2338 if (ctx
->DrawBuffer
->_StencilBuffer
)
2339 map_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
, GL_TRUE
);
2341 /* The locking and wait for idle should really only be needed in classic mode.
2342 * In a future memory manager based implementation, this should become
2343 * unnecessary due to the fact that mapping our buffers, textures, etc.
2344 * should implicitly wait for any previous rendering commands that must
2346 LOCK_HARDWARE(rmesa
);
2347 radeonWaitForIdleLocked(rmesa
);
2350 void radeonSpanRenderFinish(GLcontext
* ctx
)
2352 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2355 UNLOCK_HARDWARE(rmesa
);
2357 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2358 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2359 ctx
->Driver
.UnmapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2362 /* color draw buffers */
2363 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++)
2364 unmap_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
]);
2366 unmap_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
);
2368 if (ctx
->DrawBuffer
->_DepthBuffer
)
2369 unmap_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
);
2370 if (ctx
->DrawBuffer
->_StencilBuffer
)
2371 unmap_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
);
2374 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa
, int size
)
2376 struct radeon_cs_space_check bos
[1];
2379 size
= MAX2(size
, MAX_DMA_BUF_SZ
* 16);
2381 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
2382 fprintf(stderr
, "%s\n", __FUNCTION__
);
2384 if (rmesa
->dma
.flush
) {
2385 radeon_bo_unmap(rmesa
->dma
.current
);
2386 rmesa
->dma
.flush(rmesa
->glCtx
);
2389 if (rmesa
->dma
.nr_released_bufs
> 4) {
2390 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2391 rmesa
->dma
.nr_released_bufs
= 0;
2394 if (rmesa
->dma
.current
) {
2395 radeon_bo_unref(rmesa
->dma
.current
);
2396 rmesa
->dma
.current
= 0;
2400 rmesa
->dma
.current
= radeon_bo_open(rmesa
->radeonScreen
->bom
,
2401 0, size
, 4, RADEON_GEM_DOMAIN_GTT
,
2404 if (!rmesa
->dma
.current
) {
2405 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2406 rmesa
->dma
.nr_released_bufs
= 0;
2410 rmesa
->dma
.current_used
= 0;
2411 rmesa
->dma
.current_vertexptr
= 0;
2413 bos
[0].bo
= rmesa
->dma
.current
;
2414 bos
[0].read_domains
= RADEON_GEM_DOMAIN_GTT
;
2415 bos
[0].write_domain
=0 ;
2416 bos
[0].new_accounted
= 0;
2419 ret
= radeon_cs_space_check(rmesa
->cmdbuf
.cs
, bos
, 1);
2420 if (ret
== RADEON_CS_SPACE_OP_TO_BIG
) {
2421 fprintf(stderr
,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
2423 } else if (ret
== RADEON_CS_SPACE_FLUSH
) {
2424 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2426 fprintf(stderr
,"flushed but still no space\n");
2434 radeon_bo_map(rmesa
->dma
.current
, 1);
2437 /* Allocates a region from rmesa->dma.current. If there isn't enough
2438 * space in current, grab a new buffer (and discard what was left of current)
2440 void radeonAllocDmaRegion(radeonContextPtr rmesa
,
2441 struct radeon_bo
**pbo
, int *poffset
,
2442 int bytes
, int alignment
)
2444 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2445 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
2447 if (rmesa
->dma
.flush
)
2448 rmesa
->dma
.flush(rmesa
->glCtx
);
2450 assert(rmesa
->dma
.current_used
== rmesa
->dma
.current_vertexptr
);
2453 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ alignment
) & ~alignment
;
2455 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_used
+ bytes
> rmesa
->dma
.current
->size
)
2456 radeonRefillCurrentDmaRegion(rmesa
, (bytes
+ 15) & ~15);
2458 *poffset
= rmesa
->dma
.current_used
;
2459 *pbo
= rmesa
->dma
.current
;
2460 radeon_bo_ref(*pbo
);
2462 /* Always align to at least 16 bytes */
2463 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ bytes
+ 15) & ~15;
2464 rmesa
->dma
.current_vertexptr
= rmesa
->dma
.current_used
;
2466 assert(rmesa
->dma
.current_used
<= rmesa
->dma
.current
->size
);
2469 void radeonReleaseDmaRegion(radeonContextPtr rmesa
)
2471 if (rmesa
->dma
.current
) {
2472 rmesa
->dma
.nr_released_bufs
++;
2473 radeon_bo_unref(rmesa
->dma
.current
);
2475 rmesa
->dma
.current
= NULL
;
2479 /* Flush vertices in the current dma region.
2481 void rcommon_flush_last_swtcl_prim( GLcontext
*ctx
)
2483 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2484 struct radeon_dma
*dma
= &rmesa
->dma
;
2487 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2488 fprintf(stderr
, "%s\n", __FUNCTION__
);
2492 GLuint current_offset
= dma
->current_used
;
2494 assert (dma
->current_used
+
2495 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
2496 dma
->current_vertexptr
);
2498 radeon_bo_unmap(dma
->current
);
2499 if (dma
->current_used
!= dma
->current_vertexptr
) {
2500 dma
->current_used
= dma
->current_vertexptr
;
2502 rmesa
->vtbl
.swtcl_flush(ctx
, current_offset
);
2504 radeonReleaseDmaRegion(rmesa
);
2505 rmesa
->swtcl
.numverts
= 0;
2508 /* Alloc space in the current dma region.
2511 rcommonAllocDmaLowVerts( radeonContextPtr rmesa
, int nverts
, int vsize
)
2513 GLuint bytes
= vsize
* nverts
;
2516 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_vertexptr
+ bytes
> rmesa
->dma
.current
->size
) {
2517 radeonRefillCurrentDmaRegion( rmesa
, bytes
);
2520 if (!rmesa
->dma
.flush
) {
2521 rmesa
->glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
2522 rmesa
->dma
.flush
= rcommon_flush_last_swtcl_prim
;
2525 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
2526 ASSERT( rmesa
->dma
.flush
== rcommon_flush_last_swtcl_prim
);
2527 ASSERT( rmesa
->dma
.current_used
+
2528 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
2529 rmesa
->dma
.current_vertexptr
);
2531 // fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
2532 // rmesa->radeon.dma.current_vertexptr);
2533 head
= (rmesa
->dma
.current
->ptr
+ rmesa
->dma
.current_vertexptr
);
2534 rmesa
->dma
.current_vertexptr
+= bytes
;
2535 rmesa
->swtcl
.numverts
+= nverts
;