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
;
690 * Destroy the command buffer
692 void rcommonDestroyCmdBuf(radeonContextPtr rmesa
)
694 radeon_cs_destroy(rmesa
->cmdbuf
.cs
);
695 if (rmesa
->radeonScreen
->driScreen
->dri2
.enabled
|| rmesa
->radeonScreen
->kernel_mm
) {
696 radeon_cs_manager_gem_dtor(rmesa
->cmdbuf
.csm
);
698 radeon_cs_manager_legacy_dtor(rmesa
->cmdbuf
.csm
);
702 void rcommonBeginBatch(radeonContextPtr rmesa
, int n
,
705 const char *function
,
708 rcommonEnsureCmdBufSpace(rmesa
, n
, function
);
709 if (!rmesa
->cmdbuf
.cs
->cdw
&& dostate
) {
710 if (RADEON_DEBUG
& DEBUG_IOCTL
)
711 fprintf(stderr
, "Reemit state after flush (from %s)\n", function
);
712 rmesa
->vtbl
.emit_state(rmesa
);
714 radeon_cs_begin(rmesa
->cmdbuf
.cs
, n
, file
, function
, line
);
719 /* Return various strings for glGetString().
721 static const GLubyte
*radeonGetString(GLcontext
* ctx
, GLenum name
)
723 radeonContextPtr radeon
= RADEON_CONTEXT(ctx
);
724 static char buffer
[128];
728 if (IS_R300_CLASS(radeon
->radeonScreen
))
729 return (GLubyte
*) "DRI R300 Project";
731 return (GLubyte
*) "Tungsten Graphics, Inc.";
736 GLuint agp_mode
= (radeon
->radeonScreen
->card_type
==RADEON_CARD_PCI
) ? 0 :
737 radeon
->radeonScreen
->AGPMode
;
738 const char* chipname
;
742 if (IS_R300_CLASS(radeon
->radeonScreen
))
747 offset
= driGetRendererString(buffer
, chipname
, DRIVER_DATE
,
750 if (IS_R300_CLASS(radeon
->radeonScreen
)) {
751 sprintf(&buffer
[offset
], " %sTCL",
752 (radeon
->radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
)
755 sprintf(&buffer
[offset
], " %sTCL",
756 !(radeon
->TclFallback
& RADEON_TCL_FALLBACK_TCL_DISABLE
)
760 if (radeon
->radeonScreen
->driScreen
->dri2
.enabled
)
761 strcat(buffer
, " DRI2");
763 return (GLubyte
*) buffer
;
771 /* Initialize the driver's misc functions.
773 static void radeonInitDriverFuncs(struct dd_function_table
*functions
)
775 functions
->GetString
= radeonGetString
;
779 * Create and initialize all common fields of the context,
780 * including the Mesa context itself.
782 GLboolean
radeonInitContext(radeonContextPtr radeon
,
783 struct dd_function_table
* functions
,
784 const __GLcontextModes
* glVisual
,
785 __DRIcontextPrivate
* driContextPriv
,
786 void *sharedContextPrivate
)
788 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
789 radeonScreenPtr screen
= (radeonScreenPtr
) (sPriv
->private);
794 /* Fill in additional standard functions. */
795 radeonInitDriverFuncs(functions
);
797 radeon
->radeonScreen
= screen
;
798 /* Allocate and initialize the Mesa context */
799 if (sharedContextPrivate
)
800 shareCtx
= ((radeonContextPtr
)sharedContextPrivate
)->glCtx
;
803 radeon
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
804 functions
, (void *)radeon
);
809 driContextPriv
->driverPrivate
= radeon
;
812 radeon
->dri
.context
= driContextPriv
;
813 radeon
->dri
.screen
= sPriv
;
814 radeon
->dri
.drawable
= NULL
;
815 radeon
->dri
.readable
= NULL
;
816 radeon
->dri
.hwContext
= driContextPriv
->hHWContext
;
817 radeon
->dri
.hwLock
= &sPriv
->pSAREA
->lock
;
818 radeon
->dri
.fd
= sPriv
->fd
;
819 radeon
->dri
.drmMinor
= sPriv
->drm_version
.minor
;
821 radeon
->sarea
= (drm_radeon_sarea_t
*) ((GLubyte
*) sPriv
->pSAREA
+
822 screen
->sarea_priv_offset
);
825 fthrottle_mode
= driQueryOptioni(&radeon
->optionCache
, "fthrottle_mode");
826 radeon
->iw
.irq_seq
= -1;
827 radeon
->irqsEmitted
= 0;
828 radeon
->do_irqs
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_IRQS
&&
829 radeon
->radeonScreen
->irq
);
831 radeon
->do_usleeps
= (fthrottle_mode
== DRI_CONF_FTHROTTLE_USLEEPS
);
833 if (!radeon
->do_irqs
)
835 "IRQ's not enabled, falling back to %s: %d %d\n",
836 radeon
->do_usleeps
? "usleeps" : "busy waits",
837 fthrottle_mode
, radeon
->radeonScreen
->irq
);
839 (*sPriv
->systemTime
->getUST
) (&radeon
->swap_ust
);
845 * Cleanup common context fields.
846 * Called by r200DestroyContext/r300DestroyContext
848 void radeonCleanupContext(radeonContextPtr radeon
)
851 struct radeon_renderbuffer
*rb
;
854 fb
= (void*)radeon
->dri
.drawable
->driverPrivate
;
855 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
857 radeon_bo_unref(rb
->bo
);
860 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
862 radeon_bo_unref(rb
->bo
);
865 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
867 radeon_bo_unref(rb
->bo
);
870 fb
= (void*)radeon
->dri
.readable
->driverPrivate
;
871 rb
= (void *)fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
873 radeon_bo_unref(rb
->bo
);
876 rb
= (void *)fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
878 radeon_bo_unref(rb
->bo
);
881 rb
= (void *)fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
883 radeon_bo_unref(rb
->bo
);
887 /* _mesa_destroy_context() might result in calls to functions that
888 * depend on the DriverCtx, so don't set it to NULL before.
890 * radeon->glCtx->DriverCtx = NULL;
893 /* free the Mesa context */
894 _mesa_destroy_context(radeon
->glCtx
);
896 /* free the option cache */
897 driDestroyOptionCache(&radeon
->optionCache
);
899 if (radeon
->state
.scissor
.pClipRects
) {
900 FREE(radeon
->state
.scissor
.pClipRects
);
901 radeon
->state
.scissor
.pClipRects
= 0;
903 track
= fopen("/tmp/tracklog", "w");
905 radeon_tracker_print(&radeon
->radeonScreen
->bom
->tracker
, track
);
911 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon
,
914 /* if radeon->fake */
915 struct radeon_renderbuffer
*rb
;
917 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
920 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
921 radeon
->radeonScreen
->frontOffset
,
924 RADEON_GEM_DOMAIN_VRAM
,
927 rb
->cpp
= radeon
->radeonScreen
->cpp
;
928 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
930 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
932 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
933 radeon
->radeonScreen
->backOffset
,
936 RADEON_GEM_DOMAIN_VRAM
,
939 rb
->cpp
= radeon
->radeonScreen
->cpp
;
940 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
942 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
944 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
945 radeon
->radeonScreen
->depthOffset
,
948 RADEON_GEM_DOMAIN_VRAM
,
951 rb
->cpp
= radeon
->radeonScreen
->cpp
;
952 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
957 radeon_make_renderbuffer_current(radeonContextPtr radeon
,
960 int size
= 4096*4096*4;
961 /* if radeon->fake */
962 struct radeon_renderbuffer
*rb
;
964 if (radeon
->radeonScreen
->kernel_mm
) {
965 radeon_make_kernel_renderbuffer_current(radeon
, draw
);
970 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
972 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
973 radeon
->radeonScreen
->frontOffset
+
974 radeon
->radeonScreen
->fbLocation
,
977 RADEON_GEM_DOMAIN_VRAM
,
980 rb
->cpp
= radeon
->radeonScreen
->cpp
;
981 rb
->pitch
= radeon
->radeonScreen
->frontPitch
* rb
->cpp
;
983 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
985 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
986 radeon
->radeonScreen
->backOffset
+
987 radeon
->radeonScreen
->fbLocation
,
990 RADEON_GEM_DOMAIN_VRAM
,
993 rb
->cpp
= radeon
->radeonScreen
->cpp
;
994 rb
->pitch
= radeon
->radeonScreen
->backPitch
* rb
->cpp
;
996 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
998 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
999 radeon
->radeonScreen
->depthOffset
+
1000 radeon
->radeonScreen
->fbLocation
,
1003 RADEON_GEM_DOMAIN_VRAM
,
1006 rb
->cpp
= radeon
->radeonScreen
->cpp
;
1007 rb
->pitch
= radeon
->radeonScreen
->depthPitch
* rb
->cpp
;
1013 radeon_update_renderbuffers(__DRIcontext
*context
, __DRIdrawable
*drawable
)
1015 unsigned int attachments
[10];
1016 __DRIbuffer
*buffers
;
1017 __DRIscreen
*screen
;
1018 struct radeon_renderbuffer
*rb
;
1020 GLframebuffer
*draw
;
1021 radeonContextPtr radeon
;
1023 draw
= drawable
->driverPrivate
;
1024 screen
= context
->driScreenPriv
;
1025 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1027 if ((rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
)) {
1028 attachments
[i
++] = __DRI_BUFFER_FRONT_LEFT
;
1030 if ((rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
)) {
1031 attachments
[i
++] = __DRI_BUFFER_BACK_LEFT
;
1033 if ((rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)) {
1034 attachments
[i
++] = __DRI_BUFFER_DEPTH
;
1037 buffers
= (*screen
->dri2
.loader
->getBuffers
)(drawable
,
1042 drawable
->loaderPrivate
);
1043 if (buffers
== NULL
)
1046 /* set one cliprect to cover the whole drawable */
1049 drawable
->backX
= 0;
1050 drawable
->backY
= 0;
1051 drawable
->numClipRects
= 1;
1052 drawable
->pClipRects
[0].x1
= 0;
1053 drawable
->pClipRects
[0].y1
= 0;
1054 drawable
->pClipRects
[0].x2
= drawable
->w
;
1055 drawable
->pClipRects
[0].y2
= drawable
->h
;
1056 drawable
->numBackClipRects
= 1;
1057 drawable
->pBackClipRects
[0].x1
= 0;
1058 drawable
->pBackClipRects
[0].y1
= 0;
1059 drawable
->pBackClipRects
[0].x2
= drawable
->w
;
1060 drawable
->pBackClipRects
[0].y2
= drawable
->h
;
1061 for (i
= 0; i
< count
; i
++) {
1062 switch (buffers
[i
].attachment
) {
1063 case __DRI_BUFFER_FRONT_LEFT
:
1064 rb
= (void *)draw
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1066 radeon_bo_unref(rb
->bo
);
1069 rb
->cpp
= buffers
[i
].cpp
;
1070 rb
->pitch
= buffers
[i
].pitch
;
1071 rb
->width
= drawable
->w
;
1072 rb
->height
= drawable
->h
;
1073 rb
->has_surface
= 0;
1074 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1078 RADEON_GEM_DOMAIN_VRAM
,
1080 if (rb
->bo
== NULL
) {
1081 fprintf(stderr
, "failled to attach front %d\n",
1085 case __DRI_BUFFER_BACK_LEFT
:
1086 rb
= (void *)draw
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1088 radeon_bo_unref(rb
->bo
);
1091 rb
->cpp
= buffers
[i
].cpp
;
1092 rb
->pitch
= buffers
[i
].pitch
;
1093 rb
->width
= drawable
->w
;
1094 rb
->height
= drawable
->h
;
1095 rb
->has_surface
= 0;
1096 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1100 RADEON_GEM_DOMAIN_VRAM
,
1103 case __DRI_BUFFER_DEPTH
:
1104 rb
= (void *)draw
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1106 radeon_bo_unref(rb
->bo
);
1109 rb
->cpp
= buffers
[i
].cpp
;
1110 rb
->pitch
= buffers
[i
].pitch
;
1111 rb
->width
= drawable
->w
;
1112 rb
->height
= drawable
->h
;
1113 rb
->has_surface
= 0;
1114 rb
->bo
= radeon_bo_open(radeon
->radeonScreen
->bom
,
1118 RADEON_GEM_DOMAIN_VRAM
,
1121 case __DRI_BUFFER_STENCIL
:
1123 case __DRI_BUFFER_ACCUM
:
1126 "unhandled buffer attach event, attacment type %d\n",
1127 buffers
[i
].attachment
);
1131 radeon
= (radeonContextPtr
) context
->driverPrivate
;
1132 driUpdateFramebufferSize(radeon
->glCtx
, drawable
);
1135 /* Force the context `c' to be the current context and associate with it
1138 GLboolean
radeonMakeCurrent(__DRIcontextPrivate
* driContextPriv
,
1139 __DRIdrawablePrivate
* driDrawPriv
,
1140 __DRIdrawablePrivate
* driReadPriv
)
1142 radeonContextPtr radeon
;
1143 GLframebuffer
*dfb
, *rfb
;
1145 if (!driContextPriv
) {
1146 if (RADEON_DEBUG
& DEBUG_DRI
)
1147 fprintf(stderr
, "%s ctx is null\n", __FUNCTION__
);
1148 _mesa_make_current(NULL
, NULL
, NULL
);
1151 radeon
= (radeonContextPtr
) driContextPriv
->driverPrivate
;
1152 dfb
= driDrawPriv
->driverPrivate
;
1153 rfb
= driReadPriv
->driverPrivate
;
1155 if (driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1156 radeon_update_renderbuffers(driContextPriv
, driDrawPriv
);
1157 if (driDrawPriv
!= driReadPriv
)
1158 radeon_update_renderbuffers(driContextPriv
, driReadPriv
);
1159 radeon
->state
.color
.rrb
=
1160 (void *)dfb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1161 radeon
->state
.depth
.rrb
=
1162 (void *)dfb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1166 if (RADEON_DEBUG
& DEBUG_DRI
)
1167 fprintf(stderr
, "%s ctx %p\n", __FUNCTION__
, radeon
->glCtx
);
1169 driUpdateFramebufferSize(radeon
->glCtx
, driDrawPriv
);
1170 if (driReadPriv
!= driDrawPriv
)
1171 driUpdateFramebufferSize(radeon
->glCtx
, driReadPriv
);
1173 if (!driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1174 radeon_make_renderbuffer_current(radeon
, dfb
);
1177 _mesa_make_current(radeon
->glCtx
, dfb
, rfb
);
1179 if (radeon
->dri
.drawable
!= driDrawPriv
) {
1180 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
1181 driDrawPriv
->vblFlags
=
1182 (radeon
->radeonScreen
->irq
!= 0)
1183 ? driGetDefaultVBlankFlags(&radeon
->
1185 : VBLANK_FLAG_NO_IRQ
;
1187 driDrawableInitVBlank(driDrawPriv
);
1191 radeon
->dri
.readable
= driReadPriv
;
1193 if (radeon
->dri
.drawable
!= driDrawPriv
||
1194 radeon
->lastStamp
!= driDrawPriv
->lastStamp
) {
1195 radeon
->dri
.drawable
= driDrawPriv
;
1197 radeonSetCliprects(radeon
);
1198 radeon
->vtbl
.update_viewport_offset(radeon
->glCtx
);
1201 _mesa_update_state(radeon
->glCtx
);
1203 if (!driContextPriv
->driScreenPriv
->dri2
.enabled
) {
1204 radeonUpdatePageFlipping(radeon
);
1207 if (RADEON_DEBUG
& DEBUG_DRI
)
1208 fprintf(stderr
, "End %s\n", __FUNCTION__
);
1213 #if defined(USE_X86_ASM)
1214 #define COPY_DWORDS( dst, src, nr ) \
1217 __asm__ __volatile__( "rep ; movsl" \
1218 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
1221 "S" ((long)src) ); \
1224 #define COPY_DWORDS( dst, src, nr ) \
1227 for ( j = 0 ; j < nr ; j++ ) \
1228 dst[j] = ((int *)src)[j]; \
1233 static void radeonEmitVec4(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1237 if (RADEON_DEBUG
& DEBUG_VERTS
)
1238 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1239 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1242 COPY_DWORDS(out
, data
, count
);
1244 for (i
= 0; i
< count
; i
++) {
1245 out
[0] = *(int *)data
;
1251 static void radeonEmitVec8(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1255 if (RADEON_DEBUG
& DEBUG_VERTS
)
1256 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1257 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1260 COPY_DWORDS(out
, data
, count
* 2);
1262 for (i
= 0; i
< count
; i
++) {
1263 out
[0] = *(int *)data
;
1264 out
[1] = *(int *)(data
+ 4);
1270 static void radeonEmitVec12(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
* 3);
1282 for (i
= 0; i
< count
; i
++) {
1283 out
[0] = *(int *)data
;
1284 out
[1] = *(int *)(data
+ 4);
1285 out
[2] = *(int *)(data
+ 8);
1291 static void radeonEmitVec16(uint32_t *out
, GLvoid
* data
, int stride
, int count
)
1295 if (RADEON_DEBUG
& DEBUG_VERTS
)
1296 fprintf(stderr
, "%s count %d stride %d out %p data %p\n",
1297 __FUNCTION__
, count
, stride
, (void *)out
, (void *)data
);
1300 COPY_DWORDS(out
, data
, count
* 4);
1302 for (i
= 0; i
< count
; i
++) {
1303 out
[0] = *(int *)data
;
1304 out
[1] = *(int *)(data
+ 4);
1305 out
[2] = *(int *)(data
+ 8);
1306 out
[3] = *(int *)(data
+ 12);
1312 void rcommon_emit_vector(GLcontext
* ctx
, struct radeon_aos
*aos
,
1313 GLvoid
* data
, int size
, int stride
, int count
)
1315 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1320 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* 4, 32);
1324 radeonAllocDmaRegion(rmesa
, &aos
->bo
, &aos
->offset
, size
* count
* 4, 32);
1328 aos
->components
= size
;
1331 // radeon_bo_map(aos->bo, 1);
1332 out
= (uint32_t*)((char*)aos
->bo
->ptr
+ aos
->offset
);
1334 case 1: radeonEmitVec4(out
, data
, stride
, count
); break;
1335 case 2: radeonEmitVec8(out
, data
, stride
, count
); break;
1336 case 3: radeonEmitVec12(out
, data
, stride
, count
); break;
1337 case 4: radeonEmitVec16(out
, data
, stride
, count
); break;
1342 // radeon_bo_unmap(aos->bo);
1346 void radeon_print_state_atom( struct radeon_state_atom
*state
)
1350 fprintf(stderr
, "emit %s/%d\n", state
->name
, state
->cmd_size
);
1352 if (RADEON_DEBUG
& DEBUG_VERBOSE
)
1353 for (i
= 0 ; i
< state
->cmd_size
; i
++)
1354 fprintf(stderr
, "\t%s[%d]: %x\n", state
->name
, i
, state
->cmd
[i
]);
1360 * Allocate an empty texture image object.
1362 struct gl_texture_image
*radeonNewTextureImage(GLcontext
*ctx
)
1364 return CALLOC(sizeof(radeon_texture_image
));
1368 * Free memory associated with this texture image.
1370 void radeonFreeTexImageData(GLcontext
*ctx
, struct gl_texture_image
*timage
)
1372 radeon_texture_image
* image
= get_radeon_texture_image(timage
);
1375 radeon_miptree_unreference(image
->mt
);
1377 assert(!image
->base
.Data
);
1379 _mesa_free_texture_image_data(ctx
, timage
);
1382 radeon_bo_unref(image
->bo
);
1387 /* Set Data pointer and additional data for mapped texture image */
1388 static void teximage_set_map_data(radeon_texture_image
*image
)
1390 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1391 image
->base
.Data
= image
->mt
->bo
->ptr
+ lvl
->faces
[image
->mtface
].offset
;
1392 image
->base
.RowStride
= lvl
->rowstride
/ image
->mt
->bpp
;
1397 * Map a single texture image for glTexImage and friends.
1399 void radeon_teximage_map(radeon_texture_image
*image
, GLboolean write_enable
)
1402 assert(!image
->base
.Data
);
1404 radeon_bo_map(image
->mt
->bo
, write_enable
);
1405 teximage_set_map_data(image
);
1410 void radeon_teximage_unmap(radeon_texture_image
*image
)
1413 assert(image
->base
.Data
);
1415 image
->base
.Data
= 0;
1416 radeon_bo_unmap(image
->mt
->bo
);
1421 * Map a validated texture for reading during software rendering.
1423 void radeonMapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1425 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1428 assert(texObj
->_Complete
);
1431 radeon_bo_map(t
->mt
->bo
, GL_FALSE
);
1432 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1433 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1434 teximage_set_map_data(get_radeon_texture_image(texObj
->Image
[face
][level
]));
1438 void radeonUnmapTexture(GLcontext
*ctx
, struct gl_texture_object
*texObj
)
1440 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1443 assert(texObj
->_Complete
);
1446 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
1447 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
)
1448 texObj
->Image
[face
][level
]->Data
= 0;
1450 radeon_bo_unmap(t
->mt
->bo
);
1453 GLuint
radeon_face_for_target(GLenum target
)
1456 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
1457 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
1458 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
1459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
1460 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
1461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
1462 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
1469 * Wraps Mesa's implementation to ensure that the base level image is mapped.
1471 * This relies on internal details of _mesa_generate_mipmap, in particular
1472 * the fact that the memory for recreated texture images is always freed.
1474 void radeon_generate_mipmap(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*texObj
)
1476 GLuint face
= radeon_face_for_target(target
);
1477 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[face
][texObj
->BaseLevel
]);
1479 radeon_teximage_map(baseimage
, GL_FALSE
);
1480 _mesa_generate_mipmap(ctx
, target
, texObj
);
1481 radeon_teximage_unmap(baseimage
);
1485 /* try to find a format which will only need a memcopy */
1486 static const struct gl_texture_format
*radeonChoose8888TexFormat(GLenum srcFormat
,
1489 const GLuint ui
= 1;
1490 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
1492 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1493 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1494 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1495 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
1496 return &_mesa_texformat_rgba8888
;
1497 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1498 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1499 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1500 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
1501 return &_mesa_texformat_rgba8888_rev
;
1502 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1503 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1504 return &_mesa_texformat_argb8888_rev
;
1505 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1506 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1507 return &_mesa_texformat_argb8888
;
1509 return _dri_texformat_argb8888
;
1512 const struct gl_texture_format
*radeonChooseTextureFormat(GLcontext
* ctx
,
1513 GLint internalFormat
,
1517 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1518 const GLboolean do32bpt
=
1519 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
1520 const GLboolean force16bpt
=
1521 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
1525 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
1526 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
1527 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
1528 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
1531 switch (internalFormat
) {
1534 case GL_COMPRESSED_RGBA
:
1536 case GL_UNSIGNED_INT_10_10_10_2
:
1537 case GL_UNSIGNED_INT_2_10_10_10_REV
:
1538 return do32bpt
? _dri_texformat_argb8888
:
1539 _dri_texformat_argb1555
;
1540 case GL_UNSIGNED_SHORT_4_4_4_4
:
1541 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1542 return _dri_texformat_argb4444
;
1543 case GL_UNSIGNED_SHORT_5_5_5_1
:
1544 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1545 return _dri_texformat_argb1555
;
1547 return do32bpt
? radeonChoose8888TexFormat(format
, type
) :
1548 _dri_texformat_argb4444
;
1553 case GL_COMPRESSED_RGB
:
1555 case GL_UNSIGNED_SHORT_4_4_4_4
:
1556 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
1557 return _dri_texformat_argb4444
;
1558 case GL_UNSIGNED_SHORT_5_5_5_1
:
1559 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
1560 return _dri_texformat_argb1555
;
1561 case GL_UNSIGNED_SHORT_5_6_5
:
1562 case GL_UNSIGNED_SHORT_5_6_5_REV
:
1563 return _dri_texformat_rgb565
;
1565 return do32bpt
? _dri_texformat_argb8888
:
1566 _dri_texformat_rgb565
;
1573 return !force16bpt
?
1574 radeonChoose8888TexFormat(format
,
1575 type
) : _dri_texformat_argb4444
;
1579 return _dri_texformat_argb4444
;
1582 return _dri_texformat_argb1555
;
1588 return !force16bpt
? _dri_texformat_argb8888
:
1589 _dri_texformat_rgb565
;
1594 return _dri_texformat_rgb565
;
1601 case GL_COMPRESSED_ALPHA
:
1602 return _dri_texformat_a8
;
1608 case GL_LUMINANCE12
:
1609 case GL_LUMINANCE16
:
1610 case GL_COMPRESSED_LUMINANCE
:
1611 return _dri_texformat_l8
;
1614 case GL_LUMINANCE_ALPHA
:
1615 case GL_LUMINANCE4_ALPHA4
:
1616 case GL_LUMINANCE6_ALPHA2
:
1617 case GL_LUMINANCE8_ALPHA8
:
1618 case GL_LUMINANCE12_ALPHA4
:
1619 case GL_LUMINANCE12_ALPHA12
:
1620 case GL_LUMINANCE16_ALPHA16
:
1621 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1622 return _dri_texformat_al88
;
1627 case GL_INTENSITY12
:
1628 case GL_INTENSITY16
:
1629 case GL_COMPRESSED_INTENSITY
:
1630 return _dri_texformat_i8
;
1633 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
1634 type
== GL_UNSIGNED_BYTE
)
1635 return &_mesa_texformat_ycbcr
;
1637 return &_mesa_texformat_ycbcr_rev
;
1641 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1642 return &_mesa_texformat_rgb_dxt1
;
1644 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1645 return &_mesa_texformat_rgba_dxt1
;
1649 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1650 return &_mesa_texformat_rgba_dxt3
;
1652 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1653 return &_mesa_texformat_rgba_dxt5
;
1655 case GL_ALPHA16F_ARB
:
1656 return &_mesa_texformat_alpha_float16
;
1657 case GL_ALPHA32F_ARB
:
1658 return &_mesa_texformat_alpha_float32
;
1659 case GL_LUMINANCE16F_ARB
:
1660 return &_mesa_texformat_luminance_float16
;
1661 case GL_LUMINANCE32F_ARB
:
1662 return &_mesa_texformat_luminance_float32
;
1663 case GL_LUMINANCE_ALPHA16F_ARB
:
1664 return &_mesa_texformat_luminance_alpha_float16
;
1665 case GL_LUMINANCE_ALPHA32F_ARB
:
1666 return &_mesa_texformat_luminance_alpha_float32
;
1667 case GL_INTENSITY16F_ARB
:
1668 return &_mesa_texformat_intensity_float16
;
1669 case GL_INTENSITY32F_ARB
:
1670 return &_mesa_texformat_intensity_float32
;
1672 return &_mesa_texformat_rgba_float16
;
1674 return &_mesa_texformat_rgba_float32
;
1675 case GL_RGBA16F_ARB
:
1676 return &_mesa_texformat_rgba_float16
;
1677 case GL_RGBA32F_ARB
:
1678 return &_mesa_texformat_rgba_float32
;
1680 case GL_DEPTH_COMPONENT
:
1681 case GL_DEPTH_COMPONENT16
:
1682 case GL_DEPTH_COMPONENT24
:
1683 case GL_DEPTH_COMPONENT32
:
1686 case GL_UNSIGNED_BYTE
:
1687 case GL_UNSIGNED_SHORT
:
1688 return &_mesa_texformat_z16
;
1689 case GL_UNSIGNED_INT
:
1690 return &_mesa_texformat_z32
;
1691 case GL_UNSIGNED_INT_24_8_EXT
:
1693 return &_mesa_texformat_z24_s8
;
1696 return &_mesa_texformat_z16
;
1701 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
1702 (int)internalFormat
);
1706 return NULL
; /* never get here */
1710 * All glTexImage calls go through this function.
1712 static void radeon_teximage(
1713 GLcontext
*ctx
, int dims
,
1714 GLint face
, GLint level
,
1715 GLint internalFormat
,
1716 GLint width
, GLint height
, GLint depth
,
1718 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1719 const struct gl_pixelstore_attrib
*packing
,
1720 struct gl_texture_object
*texObj
,
1721 struct gl_texture_image
*texImage
,
1724 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1725 radeonTexObj
* t
= radeon_tex_obj(texObj
);
1726 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1728 rmesa
->vtbl
.flush_vertices(rmesa
);
1730 t
->validated
= GL_FALSE
;
1732 /* Choose and fill in the texture format for this image */
1733 texImage
->TexFormat
= radeonChooseTextureFormat(ctx
, internalFormat
, format
, type
);
1734 _mesa_set_fetch_functions(texImage
, dims
);
1736 if (texImage
->TexFormat
->TexelBytes
== 0) {
1737 texImage
->IsCompressed
= GL_TRUE
;
1738 texImage
->CompressedSize
=
1739 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
1740 texImage
->Height
, texImage
->Depth
,
1741 texImage
->TexFormat
->MesaFormat
);
1743 texImage
->IsCompressed
= GL_FALSE
;
1744 texImage
->CompressedSize
= 0;
1747 /* Allocate memory for image */
1748 radeonFreeTexImageData(ctx
, texImage
); /* Mesa core only clears texImage->Data but not image->mt */
1751 radeon_try_alloc_miptree(rmesa
, t
, texImage
, face
, level
);
1752 if (t
->mt
&& radeon_miptree_matches_image(t
->mt
, texImage
, face
, level
)) {
1754 image
->mtlevel
= level
- t
->mt
->firstLevel
;
1755 image
->mtface
= face
;
1756 radeon_miptree_reference(t
->mt
);
1759 if (texImage
->IsCompressed
) {
1760 size
= texImage
->CompressedSize
;
1762 size
= texImage
->Width
* texImage
->Height
* texImage
->Depth
* texImage
->TexFormat
->TexelBytes
;
1764 texImage
->Data
= _mesa_alloc_texmemory(size
);
1767 /* Upload texture image; note that the spec allows pixels to be NULL */
1769 pixels
= _mesa_validate_pbo_compressed_teximage(
1770 ctx
, imageSize
, pixels
, packing
, "glCompressedTexImage");
1772 pixels
= _mesa_validate_pbo_teximage(
1773 ctx
, dims
, width
, height
, depth
,
1774 format
, type
, pixels
, packing
, "glTexImage");
1778 radeon_teximage_map(image
, GL_TRUE
);
1781 memcpy(texImage
->Data
, pixels
, imageSize
);
1783 GLuint dstRowStride
;
1785 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1786 dstRowStride
= lvl
->rowstride
;
1788 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
1790 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
,
1791 texImage
->_BaseFormat
,
1792 texImage
->TexFormat
,
1793 texImage
->Data
, 0, 0, 0, /* dstX/Y/Zoffset */
1795 texImage
->ImageOffsets
,
1796 width
, height
, depth
,
1797 format
, type
, pixels
, packing
))
1798 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
1801 radeon_teximage_unmap(image
);
1804 _mesa_unmap_teximage_pbo(ctx
, packing
);
1806 /* SGIS_generate_mipmap */
1807 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1808 ctx
->Driver
.GenerateMipmap(ctx
, texObj
->Target
, texObj
);
1812 void radeonTexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1813 GLint internalFormat
,
1814 GLint width
, GLint border
,
1815 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1816 const struct gl_pixelstore_attrib
*packing
,
1817 struct gl_texture_object
*texObj
,
1818 struct gl_texture_image
*texImage
)
1820 radeon_teximage(ctx
, 1, 0, level
, internalFormat
, width
, 1, 1,
1821 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1824 void radeonTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1825 GLint internalFormat
,
1826 GLint width
, GLint height
, GLint border
,
1827 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1828 const struct gl_pixelstore_attrib
*packing
,
1829 struct gl_texture_object
*texObj
,
1830 struct gl_texture_image
*texImage
)
1833 GLuint face
= radeon_face_for_target(target
);
1835 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1836 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1839 void radeonCompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
1840 GLint level
, GLint internalFormat
,
1841 GLint width
, GLint height
, GLint border
,
1842 GLsizei imageSize
, const GLvoid
* data
,
1843 struct gl_texture_object
*texObj
,
1844 struct gl_texture_image
*texImage
)
1846 GLuint face
= radeon_face_for_target(target
);
1848 radeon_teximage(ctx
, 2, face
, level
, internalFormat
, width
, height
, 1,
1849 imageSize
, 0, 0, data
, 0, texObj
, texImage
, 1);
1852 void radeonTexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
1853 GLint internalFormat
,
1854 GLint width
, GLint height
, GLint depth
,
1856 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1857 const struct gl_pixelstore_attrib
*packing
,
1858 struct gl_texture_object
*texObj
,
1859 struct gl_texture_image
*texImage
)
1861 radeon_teximage(ctx
, 3, 0, level
, internalFormat
, width
, height
, depth
,
1862 0, format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1866 * Update a subregion of the given texture image.
1868 static void radeon_texsubimage(GLcontext
* ctx
, int dims
, int level
,
1869 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1870 GLsizei width
, GLsizei height
, GLsizei depth
,
1871 GLenum format
, GLenum type
,
1872 const GLvoid
* pixels
,
1873 const struct gl_pixelstore_attrib
*packing
,
1874 struct gl_texture_object
*texObj
,
1875 struct gl_texture_image
*texImage
,
1878 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1879 radeon_texture_image
* image
= get_radeon_texture_image(texImage
);
1881 rmesa
->vtbl
.flush_vertices(rmesa
);
1883 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
,
1884 width
, height
, depth
, format
, type
, pixels
, packing
, "glTexSubImage1D");
1888 radeon_teximage_map(image
, GL_TRUE
);
1891 radeon_mipmap_level
*lvl
= &image
->mt
->levels
[image
->mtlevel
];
1892 dstRowStride
= lvl
->rowstride
;
1894 dstRowStride
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
1897 if (!texImage
->TexFormat
->StoreImage(ctx
, dims
, texImage
->_BaseFormat
,
1898 texImage
->TexFormat
, texImage
->Data
,
1899 xoffset
, yoffset
, zoffset
,
1901 texImage
->ImageOffsets
,
1902 width
, height
, depth
,
1903 format
, type
, pixels
, packing
))
1904 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage");
1906 radeon_teximage_unmap(image
);
1909 _mesa_unmap_teximage_pbo(ctx
, packing
);
1911 /* GL_SGIS_generate_mipmap */
1912 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1913 ctx
->Driver
.GenerateMipmap(ctx
, texObj
->Target
, texObj
);
1917 void radeonTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1920 GLenum format
, GLenum type
,
1921 const GLvoid
* pixels
,
1922 const struct gl_pixelstore_attrib
*packing
,
1923 struct gl_texture_object
*texObj
,
1924 struct gl_texture_image
*texImage
)
1926 radeon_texsubimage(ctx
, 1, level
, xoffset
, 0, 0, width
, 1, 1,
1927 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1930 void radeonTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1931 GLint xoffset
, GLint yoffset
,
1932 GLsizei width
, GLsizei height
,
1933 GLenum format
, GLenum type
,
1934 const GLvoid
* pixels
,
1935 const struct gl_pixelstore_attrib
*packing
,
1936 struct gl_texture_object
*texObj
,
1937 struct gl_texture_image
*texImage
)
1939 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
,
1940 1, format
, type
, pixels
, packing
, texObj
, texImage
,
1944 void radeonCompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
1945 GLint level
, GLint xoffset
,
1946 GLint yoffset
, GLsizei width
,
1947 GLsizei height
, GLenum format
,
1948 GLsizei imageSize
, const GLvoid
* data
,
1949 struct gl_texture_object
*texObj
,
1950 struct gl_texture_image
*texImage
)
1952 radeon_texsubimage(ctx
, 2, level
, xoffset
, yoffset
, 0, width
, height
, 1,
1953 format
, 0, data
, 0, texObj
, texImage
, 1);
1957 void radeonTexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
1958 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1959 GLsizei width
, GLsizei height
, GLsizei depth
,
1960 GLenum format
, GLenum type
,
1961 const GLvoid
* pixels
,
1962 const struct gl_pixelstore_attrib
*packing
,
1963 struct gl_texture_object
*texObj
,
1964 struct gl_texture_image
*texImage
)
1966 radeon_texsubimage(ctx
, 3, level
, xoffset
, yoffset
, zoffset
, width
, height
, depth
,
1967 format
, type
, pixels
, packing
, texObj
, texImage
, 0);
1970 static void copy_rows(void* dst
, GLuint dststride
, const void* src
, GLuint srcstride
,
1971 GLuint numrows
, GLuint rowsize
)
1973 assert(rowsize
<= dststride
);
1974 assert(rowsize
<= srcstride
);
1976 if (rowsize
== srcstride
&& rowsize
== dststride
) {
1977 memcpy(dst
, src
, numrows
*rowsize
);
1980 for(i
= 0; i
< numrows
; ++i
) {
1981 memcpy(dst
, src
, rowsize
);
1990 * Ensure that the given image is stored in the given miptree from now on.
1992 static void migrate_image_to_miptree(radeon_mipmap_tree
*mt
, radeon_texture_image
*image
, int face
, int level
)
1994 radeon_mipmap_level
*dstlvl
= &mt
->levels
[level
- mt
->firstLevel
];
1995 unsigned char *dest
;
1997 assert(image
->mt
!= mt
);
1998 assert(dstlvl
->width
== image
->base
.Width
);
1999 assert(dstlvl
->height
== image
->base
.Height
);
2000 assert(dstlvl
->depth
== image
->base
.Depth
);
2002 radeon_bo_map(mt
->bo
, GL_TRUE
);
2003 dest
= mt
->bo
->ptr
+ dstlvl
->faces
[face
].offset
;
2006 /* Format etc. should match, so we really just need a memcpy().
2007 * In fact, that memcpy() could be done by the hardware in many
2008 * cases, provided that we have a proper memory manager.
2010 radeon_mipmap_level
*srclvl
= &image
->mt
->levels
[image
->mtlevel
];
2012 assert(srclvl
->size
== dstlvl
->size
);
2013 assert(srclvl
->rowstride
== dstlvl
->rowstride
);
2015 radeon_bo_map(image
->mt
->bo
, GL_FALSE
);
2017 image
->mt
->bo
->ptr
+ srclvl
->faces
[face
].offset
,
2019 radeon_bo_unmap(image
->mt
->bo
);
2021 radeon_miptree_unreference(image
->mt
);
2023 uint srcrowstride
= image
->base
.Width
* image
->base
.TexFormat
->TexelBytes
;
2025 // if (mt->tilebits)
2026 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
2028 copy_rows(dest
, dstlvl
->rowstride
, image
->base
.Data
, srcrowstride
,
2029 image
->base
.Height
* image
->base
.Depth
, srcrowstride
);
2031 _mesa_free_texmemory(image
->base
.Data
);
2032 image
->base
.Data
= 0;
2035 radeon_bo_unmap(mt
->bo
);
2038 image
->mtface
= face
;
2039 image
->mtlevel
= level
;
2040 radeon_miptree_reference(image
->mt
);
2043 int radeon_validate_texture_miptree(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
2045 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2046 radeonTexObj
*t
= radeon_tex_obj(texObj
);
2047 radeon_texture_image
*baseimage
= get_radeon_texture_image(texObj
->Image
[0][texObj
->BaseLevel
]);
2050 if (t
->validated
|| t
->image_override
)
2053 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2054 fprintf(stderr
, "%s: Validating texture %p now\n", __FUNCTION__
, texObj
);
2056 if (baseimage
->base
.Border
> 0)
2059 /* Ensure a matching miptree exists.
2061 * Differing mipmap trees can result when the app uses TexImage to
2062 * change texture dimensions.
2064 * Prefer to use base image's miptree if it
2065 * exists, since that most likely contains more valid data (remember
2066 * that the base level is usually significantly larger than the rest
2067 * of the miptree, so cubemaps are the only possible exception).
2069 if (baseimage
->mt
&&
2070 baseimage
->mt
!= t
->mt
&&
2071 radeon_miptree_matches_texture(baseimage
->mt
, &t
->base
)) {
2072 radeon_miptree_unreference(t
->mt
);
2073 t
->mt
= baseimage
->mt
;
2074 radeon_miptree_reference(t
->mt
);
2075 } else if (t
->mt
&& !radeon_miptree_matches_texture(t
->mt
, &t
->base
)) {
2076 radeon_miptree_unreference(t
->mt
);
2081 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2082 fprintf(stderr
, " Allocate new miptree\n");
2083 radeon_try_alloc_miptree(rmesa
, t
, &baseimage
->base
, 0, texObj
->BaseLevel
);
2085 _mesa_problem(ctx
, "r300_validate_texture failed to alloc miptree");
2090 /* Ensure all images are stored in the single main miptree */
2091 for(face
= 0; face
< t
->mt
->faces
; ++face
) {
2092 for(level
= t
->mt
->firstLevel
; level
<= t
->mt
->lastLevel
; ++level
) {
2093 radeon_texture_image
*image
= get_radeon_texture_image(texObj
->Image
[face
][level
]);
2094 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2095 fprintf(stderr
, " face %i, level %i... ", face
, level
);
2096 if (t
->mt
== image
->mt
) {
2097 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2098 fprintf(stderr
, "OK\n");
2102 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
2103 fprintf(stderr
, "migrating\n");
2104 migrate_image_to_miptree(t
->mt
, image
, face
, level
);
2112 GLubyte
*radeon_ptr32(const struct radeon_renderbuffer
* rrb
,
2115 GLubyte
*ptr
= rrb
->bo
->ptr
;
2116 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2121 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2122 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2125 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2126 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2127 nmacroblkpl
= rrb
->pitch
>> 5;
2128 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2129 offset
+= ((y
& 15) >> 1) << 8;
2130 offset
+= (y
& 1) << 4;
2131 offset
+= (x
>> 5) << 11;
2132 offset
+= ((x
& 31) >> 2) << 5;
2133 offset
+= (x
& 3) << 2;
2135 nmacroblkpl
= rrb
->pitch
>> 6;
2136 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2137 offset
+= (y
& 7) << 8;
2138 offset
+= (x
>> 6) << 11;
2139 offset
+= ((x
& 63) >> 3) << 5;
2140 offset
+= (x
& 7) << 2;
2143 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2144 offset
+= (y
* nmicroblkpl
) << 5;
2145 offset
+= (x
>> 3) << 5;
2146 offset
+= (x
& 7) << 2;
2149 return &ptr
[offset
];
2152 GLubyte
*radeon_ptr16(const struct radeon_renderbuffer
* rrb
,
2155 GLubyte
*ptr
= rrb
->bo
->ptr
;
2156 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2161 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2162 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2165 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2166 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2167 nmacroblkpl
= rrb
->pitch
>> 6;
2168 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2169 offset
+= ((y
& 15) >> 1) << 8;
2170 offset
+= (y
& 1) << 4;
2171 offset
+= (x
>> 6) << 11;
2172 offset
+= ((x
& 63) >> 3) << 5;
2173 offset
+= (x
& 7) << 1;
2175 nmacroblkpl
= rrb
->pitch
>> 7;
2176 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2177 offset
+= (y
& 7) << 8;
2178 offset
+= (x
>> 7) << 11;
2179 offset
+= ((x
& 127) >> 4) << 5;
2180 offset
+= (x
& 15) << 2;
2183 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2184 offset
+= (y
* nmicroblkpl
) << 5;
2185 offset
+= (x
>> 4) << 5;
2186 offset
+= (x
& 15) << 2;
2189 return &ptr
[offset
];
2192 GLubyte
*radeon_ptr(const struct radeon_renderbuffer
* rrb
,
2195 GLubyte
*ptr
= rrb
->bo
->ptr
;
2196 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
2203 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
2204 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
2207 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
) {
2208 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MICRO_TILE
) {
2209 microblkxs
= 16 / rrb
->cpp
;
2210 macroblkxs
= 128 / rrb
->cpp
;
2211 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2212 offset
+= ((y
>> 4) * nmacroblkpl
) << 11;
2213 offset
+= ((y
& 15) >> 1) << 8;
2214 offset
+= (y
& 1) << 4;
2215 offset
+= (x
/ macroblkxs
) << 11;
2216 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2217 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2219 microblkxs
= 32 / rrb
->cpp
;
2220 macroblkxs
= 256 / rrb
->cpp
;
2221 nmacroblkpl
= rrb
->pitch
/ macroblkxs
;
2222 offset
+= ((y
>> 3) * nmacroblkpl
) << 11;
2223 offset
+= (y
& 7) << 8;
2224 offset
+= (x
/ macroblkxs
) << 11;
2225 offset
+= ((x
& (macroblkxs
- 1)) / microblkxs
) << 5;
2226 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2229 microblkxs
= 32 / rrb
->cpp
;
2230 nmicroblkpl
= ((rrb
->pitch
+ 31) & ~31) >> 5;
2231 offset
+= (y
* nmicroblkpl
) << 5;
2232 offset
+= (x
/ microblkxs
) << 5;
2233 offset
+= (x
& (microblkxs
- 1)) * rrb
->cpp
;
2236 return &ptr
[offset
];
2240 static void map_buffer(struct gl_renderbuffer
*rb
, GLboolean write
)
2242 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2246 r
= radeon_bo_map(rrb
->bo
, write
);
2248 fprintf(stderr
, "(%s) error(%d) mapping buffer.\n",
2254 static void unmap_buffer(struct gl_renderbuffer
*rb
)
2256 struct radeon_renderbuffer
*rrb
= (void*)rb
;
2259 radeon_bo_unmap(rrb
->bo
);
2263 void radeonSpanRenderStart(GLcontext
* ctx
)
2265 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2268 rmesa
->vtbl
.flush_vertices(rmesa
);
2270 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2271 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2272 ctx
->Driver
.MapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2275 /* color draw buffers */
2276 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
2277 map_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
], GL_TRUE
);
2280 map_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
, GL_FALSE
);
2282 if (ctx
->DrawBuffer
->_DepthBuffer
) {
2283 map_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
, GL_TRUE
);
2285 if (ctx
->DrawBuffer
->_StencilBuffer
)
2286 map_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
, GL_TRUE
);
2288 /* The locking and wait for idle should really only be needed in classic mode.
2289 * In a future memory manager based implementation, this should become
2290 * unnecessary due to the fact that mapping our buffers, textures, etc.
2291 * should implicitly wait for any previous rendering commands that must
2293 LOCK_HARDWARE(rmesa
);
2294 radeonWaitForIdleLocked(rmesa
);
2297 void radeonSpanRenderFinish(GLcontext
* ctx
)
2299 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
2302 UNLOCK_HARDWARE(rmesa
);
2304 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
2305 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
2306 ctx
->Driver
.UnmapTexture(ctx
, ctx
->Texture
.Unit
[i
]._Current
);
2309 /* color draw buffers */
2310 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++)
2311 unmap_buffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
]);
2313 unmap_buffer(ctx
->ReadBuffer
->_ColorReadBuffer
);
2315 if (ctx
->DrawBuffer
->_DepthBuffer
)
2316 unmap_buffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
);
2317 if (ctx
->DrawBuffer
->_StencilBuffer
)
2318 unmap_buffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
);
2321 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa
, int size
)
2323 size
= MAX2(size
, MAX_DMA_BUF_SZ
* 16);
2325 if (RADEON_DEBUG
& (DEBUG_IOCTL
| DEBUG_DMA
))
2326 fprintf(stderr
, "%s\n", __FUNCTION__
);
2328 if (rmesa
->dma
.flush
) {
2329 radeon_bo_unmap(rmesa
->dma
.current
);
2330 rmesa
->dma
.flush(rmesa
->glCtx
);
2335 if (rmesa
->dma
.nr_released_bufs
> 4) {
2336 rcommonFlushCmdBuf(rmesa
, __FUNCTION__
);
2337 rmesa
->dma
.nr_released_bufs
= 0;
2340 if (rmesa
->dma
.current
) {
2341 radeon_bo_unref(rmesa
->dma
.current
);
2342 rmesa
->dma
.current
= 0;
2345 rmesa
->dma
.current
= radeon_bo_open(rmesa
->radeonScreen
->bom
,
2346 0, size
, 4, RADEON_GEM_DOMAIN_GTT
,
2349 rmesa
->dma
.current_used
= 0;
2350 rmesa
->dma
.current_vertexptr
= 0;
2351 radeon_bo_map(rmesa
->dma
.current
, 1);
2354 /* Allocates a region from rmesa->dma.current. If there isn't enough
2355 * space in current, grab a new buffer (and discard what was left of current)
2357 void radeonAllocDmaRegion(radeonContextPtr rmesa
,
2358 struct radeon_bo
**pbo
, int *poffset
,
2359 int bytes
, int alignment
)
2361 if (RADEON_DEBUG
& DEBUG_IOCTL
)
2362 fprintf(stderr
, "%s %d\n", __FUNCTION__
, bytes
);
2364 if (rmesa
->dma
.flush
)
2365 rmesa
->dma
.flush(rmesa
->glCtx
);
2367 assert(rmesa
->dma
.current_used
== rmesa
->dma
.current_vertexptr
);
2370 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ alignment
) & ~alignment
;
2372 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_used
+ bytes
> rmesa
->dma
.current
->size
)
2373 radeonRefillCurrentDmaRegion(rmesa
, (bytes
+ 15) & ~15);
2375 *poffset
= rmesa
->dma
.current_used
;
2376 *pbo
= rmesa
->dma
.current
;
2377 radeon_bo_ref(*pbo
);
2379 /* Always align to at least 16 bytes */
2380 rmesa
->dma
.current_used
= (rmesa
->dma
.current_used
+ bytes
+ 15) & ~15;
2381 rmesa
->dma
.current_vertexptr
= rmesa
->dma
.current_used
;
2383 assert(rmesa
->dma
.current_used
<= rmesa
->dma
.current
->size
);
2386 void radeonReleaseDmaRegion(radeonContextPtr rmesa
)
2388 rmesa
->dma
.nr_released_bufs
++;
2389 radeon_bo_unref(rmesa
->dma
.current
);
2390 rmesa
->dma
.current
= NULL
;
2393 void rcommonEmitVertexAOS(radeonContextPtr rmesa
, GLuint vertex_size
, struct radeon_bo
*bo
, GLuint offset
)
2395 BATCH_LOCALS(rmesa
);
2397 if (RADEON_DEBUG
& DEBUG_VERTS
)
2398 fprintf(stderr
, "%s: vertex_size %d, offset 0x%x \n",
2399 __FUNCTION__
, vertex_size
, offset
);
2402 OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR
, 2);
2404 OUT_BATCH(vertex_size
| (vertex_size
<< 8));
2405 OUT_BATCH_RELOC(offset
, bo
, offset
, RADEON_GEM_DOMAIN_GTT
, 0, 0);
2409 void rcommonEmitVbufPrim(radeonContextPtr rmesa
, GLuint primitive
, GLuint vertex_nr
)
2411 BATCH_LOCALS(rmesa
);
2412 int type
, num_verts
;
2414 type
= r300PrimitiveType(rmesa
, primitive
);
2415 num_verts
= r300NumVerts(rmesa
, vertex_nr
, primitive
);
2418 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2
, 0);
2419 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST
| (num_verts
<< 16) | type
);
2425 /* Alloc space in the current dma region.
2428 rcommonAllocDmaLowVerts( radeonContextPtr rmesa
, int nverts
, int vsize
)
2430 GLuint bytes
= vsize
* nverts
;
2433 if (!rmesa
->dma
.current
|| rmesa
->dma
.current_vertexptr
+ bytes
> rmesa
->dma
.current
->size
) {
2434 radeonRefillCurrentDmaRegion( rmesa
, bytes
);
2437 if (!rmesa
->dma
.flush
) {
2438 rmesa
->glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
2439 rmesa
->dma
.flush
= flush_last_swtcl_prim
;
2442 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
2443 ASSERT( rmesa
->radeon
.dma
.flush
== flush_last_swtcl_prim
);
2444 ASSERT( rmesa
->radeon
.dma
.current_used
+
2445 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
2446 rmesa
->radeon
.dma
.current_vertexptr
);
2448 // fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
2449 // rmesa->radeon.dma.current_vertexptr);
2450 head
= (rmesa
->radeon
.dma
.current
->ptr
+ rmesa
->radeon
.dma
.current_vertexptr
);
2451 rmesa
->radeon
.dma
.current_vertexptr
+= bytes
;
2452 rmesa
->swtcl
.numverts
+= nverts
;