radeon: call getpagesize once and store in a static
[mesa.git] / src / mesa / drivers / dri / radeon / common_misc.c
1 /**************************************************************************
2
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
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.
8
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:
16
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.
20
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.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include <errno.h>
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"
45
46 #include "swrast/swrast.h"
47 #include "vbo/vbo.h"
48 #include "tnl/tnl.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"
56
57 #include "drirenderbuffer.h"
58 #include "vblank.h"
59 #include "xmlpool.h" /* for symbolic values of enum-type options */
60
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"
67 #include "dri_util.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"
76
77 #define DRIVER_DATE "20090101"
78
79 #ifndef RADEON_DEBUG
80 int RADEON_DEBUG = (0);
81 #endif
82
83 /* =============================================================
84 * Scissoring
85 */
86
87 static GLboolean intersect_rect(drm_clip_rect_t * out,
88 drm_clip_rect_t * a, drm_clip_rect_t * b)
89 {
90 *out = *a;
91 if (b->x1 > out->x1)
92 out->x1 = b->x1;
93 if (b->y1 > out->y1)
94 out->y1 = b->y1;
95 if (b->x2 < out->x2)
96 out->x2 = b->x2;
97 if (b->y2 < out->y2)
98 out->y2 = b->y2;
99 if (out->x1 >= out->x2)
100 return GL_FALSE;
101 if (out->y1 >= out->y2)
102 return GL_FALSE;
103 return GL_TRUE;
104 }
105
106 void radeonRecalcScissorRects(radeonContextPtr radeon)
107 {
108 drm_clip_rect_t *out;
109 int i;
110
111 /* Grow cliprect store?
112 */
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;
118 }
119
120 if (radeon->state.scissor.pClipRects)
121 FREE(radeon->state.scissor.pClipRects);
122
123 radeon->state.scissor.pClipRects =
124 MALLOC(radeon->state.scissor.numAllocedClipRects *
125 sizeof(drm_clip_rect_t));
126
127 if (radeon->state.scissor.pClipRects == NULL) {
128 radeon->state.scissor.numAllocedClipRects = 0;
129 return;
130 }
131 }
132
133 out = radeon->state.scissor.pClipRects;
134 radeon->state.scissor.numClipRects = 0;
135
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++;
141 out++;
142 }
143 }
144 }
145
146 /**
147 * Update cliprects and scissors.
148 */
149 void radeonSetCliprects(radeonContextPtr radeon)
150 {
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;
155
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;
163 } else {
164 radeon->numClipRects = drawable->numBackClipRects;
165 radeon->pClipRects = drawable->pBackClipRects;
166 }
167 } else {
168 /* front buffer (or none, or multiple buffers */
169 radeon->numClipRects = drawable->numClipRects;
170 radeon->pClipRects = drawable->pClipRects;
171 }
172 }
173
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;
179 }
180
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;
187 }
188 }
189
190 if (radeon->state.scissor.enabled)
191 radeonRecalcScissorRects(radeon);
192
193 radeon->lastStamp = drawable->lastStamp;
194 }
195
196 void radeonUpdateScissor( GLcontext *ctx )
197 {
198 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
199
200 if ( rmesa->dri.drawable ) {
201 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
202
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;
207
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;
212
213 radeonRecalcScissorRects( rmesa );
214 }
215 }
216
217 /* ================================================================
218 * SwapBuffers with client-side throttling
219 */
220
221 static uint32_t radeonGetLastFrame(radeonContextPtr radeon)
222 {
223 drm_radeon_getparam_t gp;
224 int ret;
225 uint32_t frame;
226
227 gp.param = RADEON_PARAM_LAST_FRAME;
228 gp.value = (int *)&frame;
229 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
230 &gp, sizeof(gp));
231 if (ret) {
232 fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
233 ret);
234 exit(1);
235 }
236
237 return frame;
238 }
239
240 uint32_t radeonGetAge(radeonContextPtr radeon)
241 {
242 drm_radeon_getparam_t gp;
243 int ret;
244 uint32_t age;
245
246 gp.param = RADEON_PARAM_LAST_CLEAR;
247 gp.value = (int *)&age;
248 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
249 &gp, sizeof(gp));
250 if (ret) {
251 fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
252 ret);
253 exit(1);
254 }
255
256 return age;
257 }
258
259 static void radeonEmitIrqLocked(radeonContextPtr radeon)
260 {
261 drm_radeon_irq_emit_t ie;
262 int ret;
263
264 ie.irq_seq = &radeon->iw.irq_seq;
265 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT,
266 &ie, sizeof(ie));
267 if (ret) {
268 fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__,
269 ret);
270 exit(1);
271 }
272 }
273
274 static void radeonWaitIrq(radeonContextPtr radeon)
275 {
276 int ret;
277
278 do {
279 ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT,
280 &radeon->iw, sizeof(radeon->iw));
281 } while (ret && (errno == EINTR || errno == EBUSY));
282
283 if (ret) {
284 fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__,
285 ret);
286 exit(1);
287 }
288 }
289
290 static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
291 {
292 drm_radeon_sarea_t *sarea = radeon->sarea;
293
294 if (radeon->do_irqs) {
295 if (radeonGetLastFrame(radeon) < sarea->last_frame) {
296 if (!radeon->irqsEmitted) {
297 while (radeonGetLastFrame(radeon) <
298 sarea->last_frame) ;
299 } else {
300 UNLOCK_HARDWARE(radeon);
301 radeonWaitIrq(radeon);
302 LOCK_HARDWARE(radeon);
303 }
304 radeon->irqsEmitted = 10;
305 }
306
307 if (radeon->irqsEmitted) {
308 radeonEmitIrqLocked(radeon);
309 radeon->irqsEmitted--;
310 }
311 } else {
312 while (radeonGetLastFrame(radeon) < sarea->last_frame) {
313 UNLOCK_HARDWARE(radeon);
314 if (radeon->do_usleeps)
315 DO_USLEEP(1);
316 LOCK_HARDWARE(radeon);
317 }
318 }
319 }
320
321 /* wait for idle */
322 void radeonWaitForIdleLocked(radeonContextPtr radeon)
323 {
324 int ret;
325 int i = 0;
326
327 do {
328 ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE);
329 if (ret)
330 DO_USLEEP(1);
331 } while (ret && ++i < 100);
332
333 if (ret < 0) {
334 UNLOCK_HARDWARE(radeon);
335 fprintf(stderr, "Error: R300 timed out... exiting\n");
336 exit(-1);
337 }
338 }
339
340 static void radeonWaitForIdle(radeonContextPtr radeon)
341 {
342 LOCK_HARDWARE(radeon);
343 radeonWaitForIdleLocked(radeon);
344 UNLOCK_HARDWARE(radeon);
345 }
346
347
348 /* Copy the back color buffer to the front color buffer.
349 */
350 void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
351 const drm_clip_rect_t *rect)
352 {
353 radeonContextPtr rmesa;
354 GLint nbox, i, ret;
355 GLboolean missed_target;
356 int64_t ust;
357 __DRIscreenPrivate *psp;
358
359 assert(dPriv);
360 assert(dPriv->driContextPriv);
361 assert(dPriv->driContextPriv->driverPrivate);
362
363 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
364
365 if ( RADEON_DEBUG & DEBUG_IOCTL ) {
366 fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
367 }
368
369 rmesa->vtbl.flush(rmesa->glCtx);
370 LOCK_HARDWARE( rmesa );
371
372 /* Throttle the frame rate -- only allow one pending swap buffers
373 * request at a time.
374 */
375 radeonWaitForFrameCompletion( rmesa );
376 if (!rect)
377 {
378 UNLOCK_HARDWARE( rmesa );
379 driWaitForVBlank( dPriv, & missed_target );
380 LOCK_HARDWARE( rmesa );
381 }
382
383 nbox = dPriv->numClipRects; /* must be in locked region */
384
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;
389 GLint n = 0;
390
391 for ( ; i < nr ; i++ ) {
392
393 *b = box[i];
394
395 if (rect)
396 {
397 if (rect->x1 > b->x1)
398 b->x1 = rect->x1;
399 if (rect->y1 > b->y1)
400 b->y1 = rect->y1;
401 if (rect->x2 < b->x2)
402 b->x2 = rect->x2;
403 if (rect->y2 < b->y2)
404 b->y2 = rect->y2;
405
406 if (b->x1 >= b->x2 || b->y1 >= b->y2)
407 continue;
408 }
409
410 b++;
411 n++;
412 }
413 rmesa->sarea->nbox = n;
414
415 if (!n)
416 continue;
417
418 ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
419
420 if ( ret ) {
421 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
422 UNLOCK_HARDWARE( rmesa );
423 exit( 1 );
424 }
425 }
426
427 UNLOCK_HARDWARE( rmesa );
428 if (!rect)
429 {
430 psp = dPriv->driScreenPriv;
431 rmesa->swap_count++;
432 (*psp->systemTime->getUST)( & ust );
433 if ( missed_target ) {
434 rmesa->swap_missed_count++;
435 rmesa->swap_missed_ust = ust - rmesa->swap_ust;
436 }
437
438 rmesa->swap_ust = ust;
439 rmesa->vtbl.set_all_dirty(rmesa->glCtx);
440
441 }
442 }
443
444 void radeonPageFlip( __DRIdrawablePrivate *dPriv )
445 {
446 radeonContextPtr rmesa;
447 GLint ret;
448 GLboolean missed_target;
449 __DRIscreenPrivate *psp;
450 struct radeon_renderbuffer *rrb;
451 GLframebuffer *fb = dPriv->driverPrivate;
452
453 assert(dPriv);
454 assert(dPriv->driContextPriv);
455 assert(dPriv->driContextPriv->driverPrivate);
456
457 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
458 rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
459
460 psp = dPriv->driScreenPriv;
461
462 if ( RADEON_DEBUG & DEBUG_IOCTL ) {
463 fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
464 rmesa->sarea->pfCurrentPage);
465 }
466
467 rmesa->vtbl.flush(rmesa->glCtx);
468
469 LOCK_HARDWARE( rmesa );
470
471 if (!dPriv->numClipRects) {
472 UNLOCK_HARDWARE(rmesa);
473 usleep(10000); /* throttle invisible client 10ms */
474 return;
475 }
476
477 drm_clip_rect_t *box = dPriv->pClipRects;
478 drm_clip_rect_t *b = rmesa->sarea->boxes;
479 b[0] = box[0];
480 rmesa->sarea->nbox = 1;
481
482 /* Throttle the frame rate -- only allow a few pending swap buffers
483 * request at a time.
484 */
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 );
491 }
492 LOCK_HARDWARE( rmesa );
493
494 ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
495
496 UNLOCK_HARDWARE( rmesa );
497
498 if ( ret ) {
499 fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
500 exit( 1 );
501 }
502
503 rmesa->swap_count++;
504 (void) (*psp->systemTime->getUST)( & rmesa->swap_ust );
505
506 /* Get ready for drawing next frame. Update the renderbuffers'
507 * flippedOffset/Pitch fields so we draw into the right place.
508 */
509 driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
510 rmesa->sarea->pfCurrentPage);
511
512 rmesa->state.color.rrb = rrb;
513
514 if (rmesa->vtbl.update_draw_buffer)
515 rmesa->vtbl.update_draw_buffer(rmesa->glCtx);
516 }
517
518
519 /* Make sure all commands have been sent to the hardware and have
520 * completed processing.
521 */
522 void radeon_common_finish(GLcontext * ctx)
523 {
524 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
525 struct gl_framebuffer *fb = ctx->DrawBuffer;
526 int i;
527
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];
532 if (rrb->bo)
533 radeon_bo_wait(rrb->bo);
534 }
535 } else if (radeon->do_irqs) {
536 LOCK_HARDWARE(radeon);
537 radeonEmitIrqLocked(radeon);
538 UNLOCK_HARDWARE(radeon);
539 radeonWaitIrq(radeon);
540 } else {
541 radeonWaitForIdle(radeon);
542 }
543 }
544
545 /**
546 * Swap front and back buffer.
547 */
548 void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
549 {
550 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
551 radeonContextPtr radeon;
552 GLcontext *ctx;
553
554 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
555 ctx = radeon->glCtx;
556
557 if (ctx->Visual.doubleBufferMode) {
558 _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */
559 if (radeon->doPageFlip) {
560 radeonPageFlip(dPriv);
561 } else {
562 radeonCopyBuffer(dPriv, NULL);
563 }
564 }
565 } else {
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!",
568 __FUNCTION__);
569 }
570 }
571
572 void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
573 int x, int y, int w, int h )
574 {
575 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
576 radeonContextPtr radeon;
577 GLcontext *ctx;
578
579 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
580 ctx = radeon->glCtx;
581
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);
590 }
591 } else {
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!",
594 __FUNCTION__);
595 }
596 }
597
598 /* cmdbuffer */
599 /**
600 * Send the current command buffer via ioctl to the hardware.
601 */
602 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
603 {
604 int ret = 0;
605
606 if (rmesa->cmdbuf.flushing) {
607 fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n");
608 exit(-1);
609 }
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);
614 }
615 radeon_cs_erase(rmesa->cmdbuf.cs);
616 rmesa->cmdbuf.flushing = 0;
617 return ret;
618 }
619
620 int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
621 {
622 int ret;
623
624 radeonReleaseDmaRegion(rmesa);
625
626 LOCK_HARDWARE(rmesa);
627 ret = rcommonFlushCmdBufLocked(rmesa, caller);
628 UNLOCK_HARDWARE(rmesa);
629
630 if (ret) {
631 fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret);
632 _mesa_exit(ret);
633 }
634
635 return ret;
636 }
637
638 /**
639 * Make sure that enough space is available in the command buffer
640 * by flushing if necessary.
641 *
642 * \param dwords The number of dwords we need to be free on the command buffer
643 */
644 void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
645 {
646 if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size ||
647 radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
648 rcommonFlushCmdBuf(rmesa, caller);
649 }
650 }
651
652 void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size)
653 {
654 GLuint size;
655 /* Initialize command buffer */
656 size = 256 * driQueryOptioni(&rmesa->optionCache,
657 "command_buffer_size");
658 if (size < 2 * max_state_size) {
659 size = 2 * max_state_size + 65535;
660 }
661 if (size > 64 * 256)
662 size = 64 * 256;
663
664 size = 64 * 1024 / 4;
665
666 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) {
667 fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n",
668 sizeof(drm_r300_cmd_header_t));
669 fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
670 sizeof(drm_radeon_cmd_buffer_t));
671 fprintf(stderr,
672 "Allocating %d bytes command buffer (max state is %d bytes)\n",
673 size * 4, max_state_size * 4);
674 }
675
676 if (rmesa->radeonScreen->kernel_mm) {
677 int fd = rmesa->radeonScreen->driScreen->fd;
678 rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd);
679 } else {
680 rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa);
681 }
682 if (rmesa->cmdbuf.csm == NULL) {
683 /* FIXME: fatal error */
684 return;
685 }
686 rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
687 assert(rmesa->cmdbuf.cs != NULL);
688 rmesa->cmdbuf.size = size;
689
690 if (!rmesa->radeonScreen->kernel_mm) {
691 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
692 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
693 } else {
694 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
695 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
696 }
697
698 }
699 /**
700 * Destroy the command buffer
701 */
702 void rcommonDestroyCmdBuf(radeonContextPtr rmesa)
703 {
704 radeon_cs_destroy(rmesa->cmdbuf.cs);
705 if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) {
706 radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm);
707 } else {
708 radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm);
709 }
710 }
711
712 void rcommonBeginBatch(radeonContextPtr rmesa, int n,
713 int dostate,
714 const char *file,
715 const char *function,
716 int line)
717 {
718 rcommonEnsureCmdBufSpace(rmesa, n, function);
719 if (!rmesa->cmdbuf.cs->cdw && dostate) {
720 if (RADEON_DEBUG & DEBUG_IOCTL)
721 fprintf(stderr, "Reemit state after flush (from %s)\n", function);
722 rmesa->vtbl.emit_state(rmesa);
723 }
724 radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line);
725 }
726
727
728
729 /* Return various strings for glGetString().
730 */
731 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
732 {
733 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
734 static char buffer[128];
735
736 switch (name) {
737 case GL_VENDOR:
738 if (IS_R300_CLASS(radeon->radeonScreen))
739 return (GLubyte *) "DRI R300 Project";
740 else
741 return (GLubyte *) "Tungsten Graphics, Inc.";
742
743 case GL_RENDERER:
744 {
745 unsigned offset;
746 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
747 radeon->radeonScreen->AGPMode;
748 const char* chipname;
749
750
751
752 if (IS_R300_CLASS(radeon->radeonScreen))
753 chipname = "R300";
754 else
755 chipname = "R200";
756
757 offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
758 agp_mode);
759
760 if (IS_R300_CLASS(radeon->radeonScreen)) {
761 sprintf(&buffer[offset], " %sTCL",
762 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
763 ? "" : "NO-");
764 } else {
765 sprintf(&buffer[offset], " %sTCL",
766 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
767 ? "" : "NO-");
768 }
769
770 if (radeon->radeonScreen->driScreen->dri2.enabled)
771 strcat(buffer, " DRI2");
772
773 return (GLubyte *) buffer;
774 }
775
776 default:
777 return NULL;
778 }
779 }
780
781 /* Initialize the driver's misc functions.
782 */
783 static void radeonInitDriverFuncs(struct dd_function_table *functions)
784 {
785 functions->GetString = radeonGetString;
786 }
787
788 /**
789 * Create and initialize all common fields of the context,
790 * including the Mesa context itself.
791 */
792 GLboolean radeonInitContext(radeonContextPtr radeon,
793 struct dd_function_table* functions,
794 const __GLcontextModes * glVisual,
795 __DRIcontextPrivate * driContextPriv,
796 void *sharedContextPrivate)
797 {
798 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
799 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
800 GLcontext* ctx;
801 GLcontext* shareCtx;
802 int fthrottle_mode;
803
804 /* Fill in additional standard functions. */
805 radeonInitDriverFuncs(functions);
806
807 radeon->radeonScreen = screen;
808 /* Allocate and initialize the Mesa context */
809 if (sharedContextPrivate)
810 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
811 else
812 shareCtx = NULL;
813 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
814 functions, (void *)radeon);
815 if (!radeon->glCtx)
816 return GL_FALSE;
817
818 ctx = radeon->glCtx;
819 driContextPriv->driverPrivate = radeon;
820
821 /* DRI fields */
822 radeon->dri.context = driContextPriv;
823 radeon->dri.screen = sPriv;
824 radeon->dri.drawable = NULL;
825 radeon->dri.readable = NULL;
826 radeon->dri.hwContext = driContextPriv->hHWContext;
827 radeon->dri.hwLock = &sPriv->pSAREA->lock;
828 radeon->dri.fd = sPriv->fd;
829 radeon->dri.drmMinor = sPriv->drm_version.minor;
830
831 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
832 screen->sarea_priv_offset);
833
834 /* Setup IRQs */
835 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
836 radeon->iw.irq_seq = -1;
837 radeon->irqsEmitted = 0;
838 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
839 radeon->radeonScreen->irq);
840
841 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
842
843 if (!radeon->do_irqs)
844 fprintf(stderr,
845 "IRQ's not enabled, falling back to %s: %d %d\n",
846 radeon->do_usleeps ? "usleeps" : "busy waits",
847 fthrottle_mode, radeon->radeonScreen->irq);
848
849 (*sPriv->systemTime->getUST) (&radeon->swap_ust);
850
851 return GL_TRUE;
852 }
853
854 /**
855 * Cleanup common context fields.
856 * Called by r200DestroyContext/r300DestroyContext
857 */
858 void radeonCleanupContext(radeonContextPtr radeon)
859 {
860 FILE *track;
861 struct radeon_renderbuffer *rb;
862 GLframebuffer *fb;
863
864 fb = (void*)radeon->dri.drawable->driverPrivate;
865 rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
866 if (rb && rb->bo) {
867 radeon_bo_unref(rb->bo);
868 rb->bo = NULL;
869 }
870 rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
871 if (rb && rb->bo) {
872 radeon_bo_unref(rb->bo);
873 rb->bo = NULL;
874 }
875 rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
876 if (rb && rb->bo) {
877 radeon_bo_unref(rb->bo);
878 rb->bo = NULL;
879 }
880 fb = (void*)radeon->dri.readable->driverPrivate;
881 rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
882 if (rb && rb->bo) {
883 radeon_bo_unref(rb->bo);
884 rb->bo = NULL;
885 }
886 rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
887 if (rb && rb->bo) {
888 radeon_bo_unref(rb->bo);
889 rb->bo = NULL;
890 }
891 rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
892 if (rb && rb->bo) {
893 radeon_bo_unref(rb->bo);
894 rb->bo = NULL;
895 }
896
897 /* _mesa_destroy_context() might result in calls to functions that
898 * depend on the DriverCtx, so don't set it to NULL before.
899 *
900 * radeon->glCtx->DriverCtx = NULL;
901 */
902
903 /* free the Mesa context */
904 _mesa_destroy_context(radeon->glCtx);
905
906 /* free the option cache */
907 driDestroyOptionCache(&radeon->optionCache);
908
909 if (radeon->state.scissor.pClipRects) {
910 FREE(radeon->state.scissor.pClipRects);
911 radeon->state.scissor.pClipRects = 0;
912 }
913 track = fopen("/tmp/tracklog", "w");
914 if (track) {
915 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
916 fclose(track);
917 }
918 }
919
920 static void
921 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
922 GLframebuffer *draw)
923 {
924 /* if radeon->fake */
925 struct radeon_renderbuffer *rb;
926
927 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
928 if (!rb->bo) {
929 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
930 radeon->radeonScreen->frontOffset,
931 0,
932 0,
933 RADEON_GEM_DOMAIN_VRAM,
934 0);
935 }
936 rb->cpp = radeon->radeonScreen->cpp;
937 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
938 }
939 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
940 if (!rb->bo) {
941 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
942 radeon->radeonScreen->backOffset,
943 0,
944 0,
945 RADEON_GEM_DOMAIN_VRAM,
946 0);
947 }
948 rb->cpp = radeon->radeonScreen->cpp;
949 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
950 }
951 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
952 if (!rb->bo) {
953 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
954 radeon->radeonScreen->depthOffset,
955 0,
956 0,
957 RADEON_GEM_DOMAIN_VRAM,
958 0);
959 }
960 rb->cpp = radeon->radeonScreen->cpp;
961 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
962 }
963 if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) {
964 if (!rb->bo) {
965 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
966 radeon->radeonScreen->depthOffset,
967 0,
968 0,
969 RADEON_GEM_DOMAIN_VRAM,
970 0);
971 }
972 rb->cpp = radeon->radeonScreen->cpp;
973 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
974 }
975 }
976
977 static void
978 radeon_make_renderbuffer_current(radeonContextPtr radeon,
979 GLframebuffer *draw)
980 {
981 int size = 4096*4096*4;
982 /* if radeon->fake */
983 struct radeon_renderbuffer *rb;
984
985 if (radeon->radeonScreen->kernel_mm) {
986 radeon_make_kernel_renderbuffer_current(radeon, draw);
987 return;
988 }
989
990
991 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
992 if (!rb->bo) {
993 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
994 radeon->radeonScreen->frontOffset +
995 radeon->radeonScreen->fbLocation,
996 size,
997 4096,
998 RADEON_GEM_DOMAIN_VRAM,
999 0);
1000 }
1001 rb->cpp = radeon->radeonScreen->cpp;
1002 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
1003 }
1004 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
1005 if (!rb->bo) {
1006 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1007 radeon->radeonScreen->backOffset +
1008 radeon->radeonScreen->fbLocation,
1009 size,
1010 4096,
1011 RADEON_GEM_DOMAIN_VRAM,
1012 0);
1013 }
1014 rb->cpp = radeon->radeonScreen->cpp;
1015 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
1016 }
1017 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
1018 if (!rb->bo) {
1019 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1020 radeon->radeonScreen->depthOffset +
1021 radeon->radeonScreen->fbLocation,
1022 size,
1023 4096,
1024 RADEON_GEM_DOMAIN_VRAM,
1025 0);
1026 }
1027 rb->cpp = radeon->radeonScreen->cpp;
1028 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
1029 }
1030 if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) {
1031 if (!rb->bo) {
1032 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1033 radeon->radeonScreen->depthOffset +
1034 radeon->radeonScreen->fbLocation,
1035 size,
1036 4096,
1037 RADEON_GEM_DOMAIN_VRAM,
1038 0);
1039 }
1040 rb->cpp = radeon->radeonScreen->cpp;
1041 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
1042 }
1043 }
1044
1045
1046 void
1047 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
1048 {
1049 unsigned int attachments[10];
1050 __DRIbuffer *buffers;
1051 __DRIscreen *screen;
1052 struct radeon_renderbuffer *rb;
1053 int i, count;
1054 GLframebuffer *draw;
1055 radeonContextPtr radeon;
1056
1057 if (RADEON_DEBUG & DEBUG_DRI)
1058 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
1059
1060 draw = drawable->driverPrivate;
1061 screen = context->driScreenPriv;
1062 radeon = (radeonContextPtr) context->driverPrivate;
1063 i = 0;
1064 if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
1065 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1066 }
1067 if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
1068 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1069 }
1070 if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
1071 attachments[i++] = __DRI_BUFFER_DEPTH;
1072 }
1073
1074 buffers = (*screen->dri2.loader->getBuffers)(drawable,
1075 &drawable->w,
1076 &drawable->h,
1077 attachments, i,
1078 &count,
1079 drawable->loaderPrivate);
1080 if (buffers == NULL)
1081 return;
1082
1083 /* set one cliprect to cover the whole drawable */
1084 drawable->x = 0;
1085 drawable->y = 0;
1086 drawable->backX = 0;
1087 drawable->backY = 0;
1088 drawable->numClipRects = 1;
1089 drawable->pClipRects[0].x1 = 0;
1090 drawable->pClipRects[0].y1 = 0;
1091 drawable->pClipRects[0].x2 = drawable->w;
1092 drawable->pClipRects[0].y2 = drawable->h;
1093 drawable->numBackClipRects = 1;
1094 drawable->pBackClipRects[0].x1 = 0;
1095 drawable->pBackClipRects[0].y1 = 0;
1096 drawable->pBackClipRects[0].x2 = drawable->w;
1097 drawable->pBackClipRects[0].y2 = drawable->h;
1098 for (i = 0; i < count; i++) {
1099 switch (buffers[i].attachment) {
1100 case __DRI_BUFFER_FRONT_LEFT:
1101 rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
1102 if (rb->bo) {
1103 radeon_bo_unref(rb->bo);
1104 rb->bo = NULL;
1105 }
1106 rb->cpp = buffers[i].cpp;
1107 rb->pitch = buffers[i].pitch;
1108 rb->width = drawable->w;
1109 rb->height = drawable->h;
1110 rb->has_surface = 0;
1111 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1112 buffers[i].name,
1113 0,
1114 0,
1115 RADEON_GEM_DOMAIN_VRAM,
1116 buffers[i].flags);
1117 if (rb->bo == NULL) {
1118 fprintf(stderr, "failled to attach front %d\n",
1119 buffers[i].name);
1120 }
1121 break;
1122 case __DRI_BUFFER_BACK_LEFT:
1123 rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
1124 if (rb->bo) {
1125 radeon_bo_unref(rb->bo);
1126 rb->bo = NULL;
1127 }
1128 rb->cpp = buffers[i].cpp;
1129 rb->pitch = buffers[i].pitch;
1130 rb->width = drawable->w;
1131 rb->height = drawable->h;
1132 rb->has_surface = 0;
1133 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1134 buffers[i].name,
1135 0,
1136 0,
1137 RADEON_GEM_DOMAIN_VRAM,
1138 buffers[i].flags);
1139 break;
1140 case __DRI_BUFFER_DEPTH:
1141 rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer;
1142 if (rb->bo) {
1143 radeon_bo_unref(rb->bo);
1144 rb->bo = NULL;
1145 }
1146 rb->cpp = buffers[i].cpp;
1147 rb->pitch = buffers[i].pitch;
1148 rb->width = drawable->w;
1149 rb->height = drawable->h;
1150 rb->has_surface = 0;
1151 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
1152 buffers[i].name,
1153 0,
1154 0,
1155 RADEON_GEM_DOMAIN_VRAM,
1156 buffers[i].flags);
1157 break;
1158 case __DRI_BUFFER_STENCIL:
1159 break;
1160 case __DRI_BUFFER_ACCUM:
1161 default:
1162 fprintf(stderr,
1163 "unhandled buffer attach event, attacment type %d\n",
1164 buffers[i].attachment);
1165 return;
1166 }
1167 }
1168 radeon = (radeonContextPtr) context->driverPrivate;
1169 driUpdateFramebufferSize(radeon->glCtx, drawable);
1170 }
1171
1172 /* Force the context `c' to be the current context and associate with it
1173 * buffer `b'.
1174 */
1175 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
1176 __DRIdrawablePrivate * driDrawPriv,
1177 __DRIdrawablePrivate * driReadPriv)
1178 {
1179 radeonContextPtr radeon;
1180 GLframebuffer *dfb, *rfb;
1181
1182 if (!driContextPriv) {
1183 if (RADEON_DEBUG & DEBUG_DRI)
1184 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
1185 _mesa_make_current(NULL, NULL, NULL);
1186 return GL_TRUE;
1187 }
1188 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
1189 dfb = driDrawPriv->driverPrivate;
1190 rfb = driReadPriv->driverPrivate;
1191
1192 if (driContextPriv->driScreenPriv->dri2.enabled) {
1193 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
1194 if (driDrawPriv != driReadPriv)
1195 radeon_update_renderbuffers(driContextPriv, driReadPriv);
1196 radeon->state.color.rrb =
1197 (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
1198 radeon->state.depth.rrb =
1199 (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer;
1200 } else {
1201 radeon_make_renderbuffer_current(radeon, dfb);
1202 }
1203
1204
1205 if (RADEON_DEBUG & DEBUG_DRI)
1206 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb);
1207
1208 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
1209 if (driReadPriv != driDrawPriv)
1210 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
1211
1212
1213
1214 _mesa_make_current(radeon->glCtx, dfb, rfb);
1215
1216 if (radeon->dri.drawable != driDrawPriv) {
1217 if (driDrawPriv->swap_interval == (unsigned)-1) {
1218 driDrawPriv->vblFlags =
1219 (radeon->radeonScreen->irq != 0)
1220 ? driGetDefaultVBlankFlags(&radeon->
1221 optionCache)
1222 : VBLANK_FLAG_NO_IRQ;
1223
1224 driDrawableInitVBlank(driDrawPriv);
1225 }
1226 }
1227
1228 radeon->dri.readable = driReadPriv;
1229
1230 if (radeon->dri.drawable != driDrawPriv ||
1231 radeon->lastStamp != driDrawPriv->lastStamp) {
1232 radeon->dri.drawable = driDrawPriv;
1233
1234 radeonSetCliprects(radeon);
1235 radeon->vtbl.update_viewport_offset(radeon->glCtx);
1236 }
1237
1238 _mesa_update_state(radeon->glCtx);
1239
1240 if (!driContextPriv->driScreenPriv->dri2.enabled) {
1241 radeonUpdatePageFlipping(radeon);
1242 }
1243
1244 if (RADEON_DEBUG & DEBUG_DRI)
1245 fprintf(stderr, "End %s\n", __FUNCTION__);
1246 return GL_TRUE;
1247 }
1248
1249
1250 #if defined(USE_X86_ASM)
1251 #define COPY_DWORDS( dst, src, nr ) \
1252 do { \
1253 int __tmp; \
1254 __asm__ __volatile__( "rep ; movsl" \
1255 : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
1256 : "0" (nr), \
1257 "D" ((long)dst), \
1258 "S" ((long)src) ); \
1259 } while (0)
1260 #else
1261 #define COPY_DWORDS( dst, src, nr ) \
1262 do { \
1263 int j; \
1264 for ( j = 0 ; j < nr ; j++ ) \
1265 dst[j] = ((int *)src)[j]; \
1266 dst += nr; \
1267 } while (0)
1268 #endif
1269
1270 static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
1271 {
1272 int i;
1273
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);
1277
1278 if (stride == 4)
1279 COPY_DWORDS(out, data, count);
1280 else
1281 for (i = 0; i < count; i++) {
1282 out[0] = *(int *)data;
1283 out++;
1284 data += stride;
1285 }
1286 }
1287
1288 static void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
1289 {
1290 int i;
1291
1292 if (RADEON_DEBUG & DEBUG_VERTS)
1293 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1294 __FUNCTION__, count, stride, (void *)out, (void *)data);
1295
1296 if (stride == 8)
1297 COPY_DWORDS(out, data, count * 2);
1298 else
1299 for (i = 0; i < count; i++) {
1300 out[0] = *(int *)data;
1301 out[1] = *(int *)(data + 4);
1302 out += 2;
1303 data += stride;
1304 }
1305 }
1306
1307 static void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
1308 {
1309 int i;
1310
1311 if (RADEON_DEBUG & DEBUG_VERTS)
1312 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1313 __FUNCTION__, count, stride, (void *)out, (void *)data);
1314
1315 if (stride == 12) {
1316 COPY_DWORDS(out, data, count * 3);
1317 }
1318 else
1319 for (i = 0; i < count; i++) {
1320 out[0] = *(int *)data;
1321 out[1] = *(int *)(data + 4);
1322 out[2] = *(int *)(data + 8);
1323 out += 3;
1324 data += stride;
1325 }
1326 }
1327
1328 static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
1329 {
1330 int i;
1331
1332 if (RADEON_DEBUG & DEBUG_VERTS)
1333 fprintf(stderr, "%s count %d stride %d out %p data %p\n",
1334 __FUNCTION__, count, stride, (void *)out, (void *)data);
1335
1336 if (stride == 16)
1337 COPY_DWORDS(out, data, count * 4);
1338 else
1339 for (i = 0; i < count; i++) {
1340 out[0] = *(int *)data;
1341 out[1] = *(int *)(data + 4);
1342 out[2] = *(int *)(data + 8);
1343 out[3] = *(int *)(data + 12);
1344 out += 4;
1345 data += stride;
1346 }
1347 }
1348
1349 void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
1350 GLvoid * data, int size, int stride, int count)
1351 {
1352 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1353 uint32_t *out;
1354
1355 if (stride == 0) {
1356 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
1357 count = 1;
1358 aos->stride = 0;
1359 } else {
1360 radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
1361 aos->stride = size;
1362 }
1363
1364 aos->components = size;
1365 aos->count = count;
1366
1367 out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
1368 switch (size) {
1369 case 1: radeonEmitVec4(out, data, stride, count); break;
1370 case 2: radeonEmitVec8(out, data, stride, count); break;
1371 case 3: radeonEmitVec12(out, data, stride, count); break;
1372 case 4: radeonEmitVec16(out, data, stride, count); break;
1373 default:
1374 assert(0);
1375 break;
1376 }
1377 }
1378
1379
1380 void radeon_print_state_atom( struct radeon_state_atom *state )
1381 {
1382 int i;
1383
1384 fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
1385
1386 if (RADEON_DEBUG & DEBUG_VERBOSE)
1387 for (i = 0 ; i < state->cmd_size ; i++)
1388 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
1389
1390 }
1391
1392 /* textures */
1393 /**
1394 * Allocate an empty texture image object.
1395 */
1396 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
1397 {
1398 return CALLOC(sizeof(radeon_texture_image));
1399 }
1400
1401 /**
1402 * Free memory associated with this texture image.
1403 */
1404 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
1405 {
1406 radeon_texture_image* image = get_radeon_texture_image(timage);
1407
1408 if (image->mt) {
1409 radeon_miptree_unreference(image->mt);
1410 image->mt = 0;
1411 assert(!image->base.Data);
1412 } else {
1413 _mesa_free_texture_image_data(ctx, timage);
1414 }
1415 if (image->bo) {
1416 radeon_bo_unref(image->bo);
1417 image->bo = NULL;
1418 }
1419 if (timage->Data) {
1420 _mesa_free_texmemory(timage->Data);
1421 timage->Data = NULL;
1422 }
1423 }
1424
1425 /* Set Data pointer and additional data for mapped texture image */
1426 static void teximage_set_map_data(radeon_texture_image *image)
1427 {
1428 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1429
1430 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
1431 image->base.RowStride = lvl->rowstride / image->mt->bpp;
1432 }
1433
1434
1435 /**
1436 * Map a single texture image for glTexImage and friends.
1437 */
1438 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
1439 {
1440 if (image->mt) {
1441 assert(!image->base.Data);
1442
1443 radeon_bo_map(image->mt->bo, write_enable);
1444 teximage_set_map_data(image);
1445 }
1446 }
1447
1448
1449 void radeon_teximage_unmap(radeon_texture_image *image)
1450 {
1451 if (image->mt) {
1452 assert(image->base.Data);
1453
1454 image->base.Data = 0;
1455 radeon_bo_unmap(image->mt->bo);
1456 }
1457 }
1458
1459 /**
1460 * Map a validated texture for reading during software rendering.
1461 */
1462 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
1463 {
1464 radeonTexObj* t = radeon_tex_obj(texObj);
1465 int face, level;
1466
1467 // assert(texObj->_Complete);
1468 assert(t->mt);
1469
1470 radeon_bo_map(t->mt->bo, GL_FALSE);
1471 for(face = 0; face < t->mt->faces; ++face) {
1472 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
1473 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
1474 }
1475 }
1476
1477 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
1478 {
1479 radeonTexObj* t = radeon_tex_obj(texObj);
1480 int face, level;
1481
1482 // assert(texObj->_Complete);
1483 assert(t->mt);
1484
1485 for(face = 0; face < t->mt->faces; ++face) {
1486 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
1487 texObj->Image[face][level]->Data = 0;
1488 }
1489 radeon_bo_unmap(t->mt->bo);
1490 }
1491
1492 GLuint radeon_face_for_target(GLenum target)
1493 {
1494 switch (target) {
1495 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1496 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1497 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1498 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1499 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1500 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1501 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1502 default:
1503 return 0;
1504 }
1505 }
1506
1507 /**
1508 * Wraps Mesa's implementation to ensure that the base level image is mapped.
1509 *
1510 * This relies on internal details of _mesa_generate_mipmap, in particular
1511 * the fact that the memory for recreated texture images is always freed.
1512 */
1513 void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
1514 struct gl_texture_object *texObj)
1515 {
1516 radeonTexObj* t = radeon_tex_obj(texObj);
1517 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1518 int i, face;
1519
1520
1521 _mesa_generate_mipmap(ctx, target, texObj);
1522
1523 for (face = 0; face < nr_faces; face++) {
1524 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
1525 radeon_texture_image *image;
1526
1527 image = get_radeon_texture_image(texObj->Image[face][i]);
1528
1529 if (image == NULL)
1530 break;
1531
1532 image->mtlevel = i;
1533 image->mtface = face;
1534
1535 radeon_miptree_unreference(image->mt);
1536 image->mt = NULL;
1537 }
1538 }
1539
1540 }
1541
1542 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
1543 {
1544 GLuint face = radeon_face_for_target(target);
1545 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
1546
1547 radeon_teximage_map(baseimage, GL_FALSE);
1548 radeon_generate_mipmap(ctx, target, texObj);
1549 radeon_teximage_unmap(baseimage);
1550 }
1551
1552
1553 /* try to find a format which will only need a memcopy */
1554 static const struct gl_texture_format *radeonChoose8888TexFormat(GLenum srcFormat,
1555 GLenum srcType)
1556 {
1557 const GLuint ui = 1;
1558 const GLubyte littleEndian = *((const GLubyte *)&ui);
1559
1560 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1561 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1562 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1563 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
1564 return &_mesa_texformat_rgba8888;
1565 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1566 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1567 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1568 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
1569 return &_mesa_texformat_rgba8888_rev;
1570 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1571 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1572 return &_mesa_texformat_argb8888_rev;
1573 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1574 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1575 return &_mesa_texformat_argb8888;
1576 } else
1577 return _dri_texformat_argb8888;
1578 }
1579
1580 const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
1581 GLint internalFormat,
1582 GLenum format,
1583 GLenum type)
1584 {
1585 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1586 const GLboolean do32bpt =
1587 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
1588 const GLboolean force16bpt =
1589 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
1590 (void)format;
1591
1592 #if 0
1593 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
1594 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
1595 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
1596 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
1597 #endif
1598
1599 switch (internalFormat) {
1600 case 4:
1601 case GL_RGBA:
1602 case GL_COMPRESSED_RGBA:
1603 switch (type) {
1604 case GL_UNSIGNED_INT_10_10_10_2:
1605 case GL_UNSIGNED_INT_2_10_10_10_REV:
1606 return do32bpt ? _dri_texformat_argb8888 :
1607 _dri_texformat_argb1555;
1608 case GL_UNSIGNED_SHORT_4_4_4_4:
1609 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1610 return _dri_texformat_argb4444;
1611 case GL_UNSIGNED_SHORT_5_5_5_1:
1612 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1613 return _dri_texformat_argb1555;
1614 default:
1615 return do32bpt ? radeonChoose8888TexFormat(format, type) :
1616 _dri_texformat_argb4444;
1617 }
1618
1619 case 3:
1620 case GL_RGB:
1621 case GL_COMPRESSED_RGB:
1622 switch (type) {
1623 case GL_UNSIGNED_SHORT_4_4_4_4:
1624 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1625 return _dri_texformat_argb4444;
1626 case GL_UNSIGNED_SHORT_5_5_5_1:
1627 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1628 return _dri_texformat_argb1555;
1629 case GL_UNSIGNED_SHORT_5_6_5:
1630 case GL_UNSIGNED_SHORT_5_6_5_REV:
1631 return _dri_texformat_rgb565;
1632 default:
1633 return do32bpt ? _dri_texformat_argb8888 :
1634 _dri_texformat_rgb565;
1635 }
1636
1637 case GL_RGBA8:
1638 case GL_RGB10_A2:
1639 case GL_RGBA12:
1640 case GL_RGBA16:
1641 return !force16bpt ?
1642 radeonChoose8888TexFormat(format,
1643 type) : _dri_texformat_argb4444;
1644
1645 case GL_RGBA4:
1646 case GL_RGBA2:
1647 return _dri_texformat_argb4444;
1648
1649 case GL_RGB5_A1:
1650 return _dri_texformat_argb1555;
1651
1652 case GL_RGB8:
1653 case GL_RGB10:
1654 case GL_RGB12:
1655 case GL_RGB16:
1656 return !force16bpt ? _dri_texformat_argb8888 :
1657 _dri_texformat_rgb565;
1658
1659 case GL_RGB5:
1660 case GL_RGB4:
1661 case GL_R3_G3_B2:
1662 return _dri_texformat_rgb565;
1663
1664 case GL_ALPHA:
1665 case GL_ALPHA4:
1666 case GL_ALPHA8:
1667 case GL_ALPHA12:
1668 case GL_ALPHA16:
1669 case GL_COMPRESSED_ALPHA:
1670 return _dri_texformat_a8;
1671
1672 case 1:
1673 case GL_LUMINANCE:
1674 case GL_LUMINANCE4:
1675 case GL_LUMINANCE8:
1676 case GL_LUMINANCE12:
1677 case GL_LUMINANCE16:
1678 case GL_COMPRESSED_LUMINANCE:
1679 return _dri_texformat_l8;
1680
1681 case 2:
1682 case GL_LUMINANCE_ALPHA:
1683 case GL_LUMINANCE4_ALPHA4:
1684 case GL_LUMINANCE6_ALPHA2:
1685 case GL_LUMINANCE8_ALPHA8:
1686 case GL_LUMINANCE12_ALPHA4:
1687 case GL_LUMINANCE12_ALPHA12:
1688 case GL_LUMINANCE16_ALPHA16:
1689 case GL_COMPRESSED_LUMINANCE_ALPHA:
1690 return _dri_texformat_al88;
1691
1692 case GL_INTENSITY:
1693 case GL_INTENSITY4:
1694 case GL_INTENSITY8:
1695 case GL_INTENSITY12:
1696 case GL_INTENSITY16:
1697 case GL_COMPRESSED_INTENSITY:
1698 return _dri_texformat_i8;
1699
1700 case GL_YCBCR_MESA:
1701 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
1702 type == GL_UNSIGNED_BYTE)
1703 return &_mesa_texformat_ycbcr;
1704 else
1705 return &_mesa_texformat_ycbcr_rev;
1706
1707 case GL_RGB_S3TC:
1708 case GL_RGB4_S3TC:
1709 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1710 return &_mesa_texformat_rgb_dxt1;
1711
1712 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1713 return &_mesa_texformat_rgba_dxt1;
1714
1715 case GL_RGBA_S3TC:
1716 case GL_RGBA4_S3TC:
1717 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1718 return &_mesa_texformat_rgba_dxt3;
1719
1720 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1721 return &_mesa_texformat_rgba_dxt5;
1722
1723 case GL_ALPHA16F_ARB:
1724 return &_mesa_texformat_alpha_float16;
1725 case GL_ALPHA32F_ARB:
1726 return &_mesa_texformat_alpha_float32;
1727 case GL_LUMINANCE16F_ARB:
1728 return &_mesa_texformat_luminance_float16;
1729 case GL_LUMINANCE32F_ARB:
1730 return &_mesa_texformat_luminance_float32;
1731 case GL_LUMINANCE_ALPHA16F_ARB:
1732 return &_mesa_texformat_luminance_alpha_float16;
1733 case GL_LUMINANCE_ALPHA32F_ARB:
1734 return &_mesa_texformat_luminance_alpha_float32;
1735 case GL_INTENSITY16F_ARB:
1736 return &_mesa_texformat_intensity_float16;
1737 case GL_INTENSITY32F_ARB:
1738 return &_mesa_texformat_intensity_float32;
1739 case GL_RGB16F_ARB:
1740 return &_mesa_texformat_rgba_float16;
1741 case GL_RGB32F_ARB:
1742 return &_mesa_texformat_rgba_float32;
1743 case GL_RGBA16F_ARB:
1744 return &_mesa_texformat_rgba_float16;
1745 case GL_RGBA32F_ARB:
1746 return &_mesa_texformat_rgba_float32;
1747
1748 case GL_DEPTH_COMPONENT:
1749 case GL_DEPTH_COMPONENT16:
1750 case GL_DEPTH_COMPONENT24:
1751 case GL_DEPTH_COMPONENT32:
1752 #if 0
1753 switch (type) {
1754 case GL_UNSIGNED_BYTE:
1755 case GL_UNSIGNED_SHORT:
1756 return &_mesa_texformat_z16;
1757 case GL_UNSIGNED_INT:
1758 return &_mesa_texformat_z32;
1759 case GL_UNSIGNED_INT_24_8_EXT:
1760 default:
1761 return &_mesa_texformat_z24_s8;
1762 }
1763 #else
1764 return &_mesa_texformat_z16;
1765 #endif
1766
1767 default:
1768 _mesa_problem(ctx,
1769 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
1770 (int)internalFormat);
1771 return NULL;
1772 }
1773
1774 return NULL; /* never get here */
1775 }
1776
1777 /**
1778 * All glTexImage calls go through this function.
1779 */
1780 static void radeon_teximage(
1781 GLcontext *ctx, int dims,
1782 GLint face, GLint level,
1783 GLint internalFormat,
1784 GLint width, GLint height, GLint depth,
1785 GLsizei imageSize,
1786 GLenum format, GLenum type, const GLvoid * pixels,
1787 const struct gl_pixelstore_attrib *packing,
1788 struct gl_texture_object *texObj,
1789 struct gl_texture_image *texImage,
1790 int compressed)
1791 {
1792 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1793 radeonTexObj* t = radeon_tex_obj(texObj);
1794 radeon_texture_image* image = get_radeon_texture_image(texImage);
1795
1796 rmesa->vtbl.flush_vertices(rmesa);
1797
1798 t->validated = GL_FALSE;
1799
1800 /* Choose and fill in the texture format for this image */
1801 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
1802 _mesa_set_fetch_functions(texImage, dims);
1803
1804 if (texImage->TexFormat->TexelBytes == 0) {
1805 texImage->IsCompressed = GL_TRUE;
1806 texImage->CompressedSize =
1807 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
1808 texImage->Height, texImage->Depth,
1809 texImage->TexFormat->MesaFormat);
1810 } else {
1811 texImage->IsCompressed = GL_FALSE;
1812 texImage->CompressedSize = 0;
1813 }
1814
1815 /* Allocate memory for image */
1816 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
1817
1818 if (!t->mt)
1819 radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
1820 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
1821 image->mt = t->mt;
1822 image->mtlevel = level - t->mt->firstLevel;
1823 image->mtface = face;
1824 radeon_miptree_reference(t->mt);
1825 } else {
1826 int size;
1827 if (texImage->IsCompressed) {
1828 size = texImage->CompressedSize;
1829 } else {
1830 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
1831 }
1832 texImage->Data = _mesa_alloc_texmemory(size);
1833 }
1834
1835 /* Upload texture image; note that the spec allows pixels to be NULL */
1836 if (compressed) {
1837 pixels = _mesa_validate_pbo_compressed_teximage(
1838 ctx, imageSize, pixels, packing, "glCompressedTexImage");
1839 } else {
1840 pixels = _mesa_validate_pbo_teximage(
1841 ctx, dims, width, height, depth,
1842 format, type, pixels, packing, "glTexImage");
1843 }
1844
1845 if (pixels) {
1846 radeon_teximage_map(image, GL_TRUE);
1847
1848 if (compressed) {
1849 memcpy(texImage->Data, pixels, imageSize);
1850 } else {
1851 GLuint dstRowStride;
1852 if (image->mt) {
1853 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1854 dstRowStride = lvl->rowstride;
1855 } else {
1856 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
1857 }
1858 if (!texImage->TexFormat->StoreImage(ctx, dims,
1859 texImage->_BaseFormat,
1860 texImage->TexFormat,
1861 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
1862 dstRowStride,
1863 texImage->ImageOffsets,
1864 width, height, depth,
1865 format, type, pixels, packing))
1866 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1867 }
1868
1869 }
1870
1871 /* SGIS_generate_mipmap */
1872 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1873 radeon_generate_mipmap(ctx, texObj->Target, texObj);
1874 }
1875
1876 if (pixels)
1877 radeon_teximage_unmap(image);
1878
1879 _mesa_unmap_teximage_pbo(ctx, packing);
1880
1881
1882 }
1883
1884 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1885 GLint internalFormat,
1886 GLint width, GLint border,
1887 GLenum format, GLenum type, const GLvoid * pixels,
1888 const struct gl_pixelstore_attrib *packing,
1889 struct gl_texture_object *texObj,
1890 struct gl_texture_image *texImage)
1891 {
1892 radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
1893 0, format, type, pixels, packing, texObj, texImage, 0);
1894 }
1895
1896 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1897 GLint internalFormat,
1898 GLint width, GLint height, GLint border,
1899 GLenum format, GLenum type, const GLvoid * pixels,
1900 const struct gl_pixelstore_attrib *packing,
1901 struct gl_texture_object *texObj,
1902 struct gl_texture_image *texImage)
1903
1904 {
1905 GLuint face = radeon_face_for_target(target);
1906
1907 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
1908 0, format, type, pixels, packing, texObj, texImage, 0);
1909 }
1910
1911 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
1912 GLint level, GLint internalFormat,
1913 GLint width, GLint height, GLint border,
1914 GLsizei imageSize, const GLvoid * data,
1915 struct gl_texture_object *texObj,
1916 struct gl_texture_image *texImage)
1917 {
1918 GLuint face = radeon_face_for_target(target);
1919
1920 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
1921 imageSize, 0, 0, data, 0, texObj, texImage, 1);
1922 }
1923
1924 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
1925 GLint internalFormat,
1926 GLint width, GLint height, GLint depth,
1927 GLint border,
1928 GLenum format, GLenum type, const GLvoid * pixels,
1929 const struct gl_pixelstore_attrib *packing,
1930 struct gl_texture_object *texObj,
1931 struct gl_texture_image *texImage)
1932 {
1933 radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
1934 0, format, type, pixels, packing, texObj, texImage, 0);
1935 }
1936
1937 /**
1938 * Update a subregion of the given texture image.
1939 */
1940 static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
1941 GLint xoffset, GLint yoffset, GLint zoffset,
1942 GLsizei width, GLsizei height, GLsizei depth,
1943 GLenum format, GLenum type,
1944 const GLvoid * pixels,
1945 const struct gl_pixelstore_attrib *packing,
1946 struct gl_texture_object *texObj,
1947 struct gl_texture_image *texImage,
1948 int compressed)
1949 {
1950 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1951 radeonTexObj* t = radeon_tex_obj(texObj);
1952 radeon_texture_image* image = get_radeon_texture_image(texImage);
1953
1954 rmesa->vtbl.flush_vertices(rmesa);
1955
1956 t->validated = GL_FALSE;
1957 pixels = _mesa_validate_pbo_teximage(ctx, dims,
1958 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
1959
1960 if (pixels) {
1961 GLint dstRowStride;
1962 radeon_teximage_map(image, GL_TRUE);
1963
1964 if (image->mt) {
1965 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
1966 dstRowStride = lvl->rowstride;
1967 } else {
1968 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
1969 }
1970
1971 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
1972 texImage->TexFormat, texImage->Data,
1973 xoffset, yoffset, zoffset,
1974 dstRowStride,
1975 texImage->ImageOffsets,
1976 width, height, depth,
1977 format, type, pixels, packing))
1978 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1979
1980
1981 }
1982
1983 /* GL_SGIS_generate_mipmap */
1984 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1985 radeon_generate_mipmap(ctx, texObj->Target, texObj);
1986 }
1987 radeon_teximage_unmap(image);
1988
1989 _mesa_unmap_teximage_pbo(ctx, packing);
1990
1991
1992 }
1993
1994 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1995 GLint xoffset,
1996 GLsizei width,
1997 GLenum format, GLenum type,
1998 const GLvoid * pixels,
1999 const struct gl_pixelstore_attrib *packing,
2000 struct gl_texture_object *texObj,
2001 struct gl_texture_image *texImage)
2002 {
2003 radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
2004 format, type, pixels, packing, texObj, texImage, 0);
2005 }
2006
2007 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
2008 GLint xoffset, GLint yoffset,
2009 GLsizei width, GLsizei height,
2010 GLenum format, GLenum type,
2011 const GLvoid * pixels,
2012 const struct gl_pixelstore_attrib *packing,
2013 struct gl_texture_object *texObj,
2014 struct gl_texture_image *texImage)
2015 {
2016 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
2017 1, format, type, pixels, packing, texObj, texImage,
2018 0);
2019 }
2020
2021 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
2022 GLint level, GLint xoffset,
2023 GLint yoffset, GLsizei width,
2024 GLsizei height, GLenum format,
2025 GLsizei imageSize, const GLvoid * data,
2026 struct gl_texture_object *texObj,
2027 struct gl_texture_image *texImage)
2028 {
2029 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
2030 format, 0, data, 0, texObj, texImage, 1);
2031 }
2032
2033
2034 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
2035 GLint xoffset, GLint yoffset, GLint zoffset,
2036 GLsizei width, GLsizei height, GLsizei depth,
2037 GLenum format, GLenum type,
2038 const GLvoid * pixels,
2039 const struct gl_pixelstore_attrib *packing,
2040 struct gl_texture_object *texObj,
2041 struct gl_texture_image *texImage)
2042 {
2043 radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
2044 format, type, pixels, packing, texObj, texImage, 0);
2045 }
2046
2047 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
2048 GLuint numrows, GLuint rowsize)
2049 {
2050 assert(rowsize <= dststride);
2051 assert(rowsize <= srcstride);
2052
2053 if (rowsize == srcstride && rowsize == dststride) {
2054 memcpy(dst, src, numrows*rowsize);
2055 } else {
2056 GLuint i;
2057 for(i = 0; i < numrows; ++i) {
2058 memcpy(dst, src, rowsize);
2059 dst += dststride;
2060 src += srcstride;
2061 }
2062 }
2063 }
2064
2065
2066 /**
2067 * Ensure that the given image is stored in the given miptree from now on.
2068 */
2069 static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
2070 {
2071 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
2072 unsigned char *dest;
2073
2074 assert(image->mt != mt);
2075 assert(dstlvl->width == image->base.Width);
2076 assert(dstlvl->height == image->base.Height);
2077 assert(dstlvl->depth == image->base.Depth);
2078
2079
2080 radeon_bo_map(mt->bo, GL_TRUE);
2081 dest = mt->bo->ptr + dstlvl->faces[face].offset;
2082
2083 if (image->mt) {
2084 /* Format etc. should match, so we really just need a memcpy().
2085 * In fact, that memcpy() could be done by the hardware in many
2086 * cases, provided that we have a proper memory manager.
2087 */
2088 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
2089
2090 assert(srclvl->size == dstlvl->size);
2091 assert(srclvl->rowstride == dstlvl->rowstride);
2092
2093 radeon_bo_map(image->mt->bo, GL_FALSE);
2094
2095 memcpy(dest,
2096 image->mt->bo->ptr + srclvl->faces[face].offset,
2097 dstlvl->size);
2098 radeon_bo_unmap(image->mt->bo);
2099
2100 radeon_miptree_unreference(image->mt);
2101 } else {
2102 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
2103
2104 // if (mt->tilebits)
2105 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
2106
2107 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
2108 image->base.Height * image->base.Depth, srcrowstride);
2109
2110 _mesa_free_texmemory(image->base.Data);
2111 image->base.Data = 0;
2112 }
2113
2114 radeon_bo_unmap(mt->bo);
2115
2116 image->mt = mt;
2117 image->mtface = face;
2118 image->mtlevel = level;
2119 radeon_miptree_reference(image->mt);
2120 }
2121
2122 int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
2123 {
2124 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2125 radeonTexObj *t = radeon_tex_obj(texObj);
2126 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
2127 int face, level;
2128
2129 if (t->validated || t->image_override)
2130 return GL_TRUE;
2131
2132 if (RADEON_DEBUG & DEBUG_TEXTURE)
2133 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
2134
2135 if (baseimage->base.Border > 0)
2136 return GL_FALSE;
2137
2138 /* Ensure a matching miptree exists.
2139 *
2140 * Differing mipmap trees can result when the app uses TexImage to
2141 * change texture dimensions.
2142 *
2143 * Prefer to use base image's miptree if it
2144 * exists, since that most likely contains more valid data (remember
2145 * that the base level is usually significantly larger than the rest
2146 * of the miptree, so cubemaps are the only possible exception).
2147 */
2148 if (baseimage->mt &&
2149 baseimage->mt != t->mt &&
2150 radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
2151 radeon_miptree_unreference(t->mt);
2152 t->mt = baseimage->mt;
2153 radeon_miptree_reference(t->mt);
2154 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
2155 radeon_miptree_unreference(t->mt);
2156 t->mt = 0;
2157 }
2158
2159 if (!t->mt) {
2160 if (RADEON_DEBUG & DEBUG_TEXTURE)
2161 fprintf(stderr, " Allocate new miptree\n");
2162 radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
2163 if (!t->mt) {
2164 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
2165 return GL_FALSE;
2166 }
2167 }
2168
2169 /* Ensure all images are stored in the single main miptree */
2170 for(face = 0; face < t->mt->faces; ++face) {
2171 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
2172 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
2173 if (RADEON_DEBUG & DEBUG_TEXTURE)
2174 fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
2175 if (t->mt == image->mt) {
2176 if (RADEON_DEBUG & DEBUG_TEXTURE)
2177 fprintf(stderr, "OK\n");
2178 continue;
2179 }
2180
2181 if (RADEON_DEBUG & DEBUG_TEXTURE)
2182 fprintf(stderr, "migrating\n");
2183 migrate_image_to_miptree(t->mt, image, face, level);
2184 }
2185 }
2186
2187 return GL_TRUE;
2188 }
2189
2190
2191 GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb,
2192 GLint x, GLint y)
2193 {
2194 GLubyte *ptr = rrb->bo->ptr;
2195 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2196 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2197 GLint offset;
2198 GLint nmacroblkpl;
2199 GLint nmicroblkpl;
2200
2201 x += dPriv->x;
2202 y += dPriv->y;
2203
2204 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2205 offset = x * rrb->cpp + y * rrb->pitch;
2206 } else {
2207 offset = 0;
2208 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2209 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2210 nmacroblkpl = rrb->pitch >> 5;
2211 offset += ((y >> 4) * nmacroblkpl) << 11;
2212 offset += ((y & 15) >> 1) << 8;
2213 offset += (y & 1) << 4;
2214 offset += (x >> 5) << 11;
2215 offset += ((x & 31) >> 2) << 5;
2216 offset += (x & 3) << 2;
2217 } else {
2218 nmacroblkpl = rrb->pitch >> 6;
2219 offset += ((y >> 3) * nmacroblkpl) << 11;
2220 offset += (y & 7) << 8;
2221 offset += (x >> 6) << 11;
2222 offset += ((x & 63) >> 3) << 5;
2223 offset += (x & 7) << 2;
2224 }
2225 } else {
2226 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2227 offset += (y * nmicroblkpl) << 5;
2228 offset += (x >> 3) << 5;
2229 offset += (x & 7) << 2;
2230 }
2231 }
2232 return &ptr[offset];
2233 }
2234
2235 GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
2236 GLint x, GLint y)
2237 {
2238 GLubyte *ptr = rrb->bo->ptr;
2239 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2240 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2241 GLint offset;
2242 GLint nmacroblkpl;
2243 GLint nmicroblkpl;
2244
2245 x += dPriv->x;
2246 y += dPriv->y;
2247
2248 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2249 offset = x * rrb->cpp + y * rrb->pitch;
2250 } else {
2251 offset = 0;
2252 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2253 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2254 nmacroblkpl = rrb->pitch >> 6;
2255 offset += ((y >> 4) * nmacroblkpl) << 11;
2256 offset += ((y & 15) >> 1) << 8;
2257 offset += (y & 1) << 4;
2258 offset += (x >> 6) << 11;
2259 offset += ((x & 63) >> 3) << 5;
2260 offset += (x & 7) << 1;
2261 } else {
2262 nmacroblkpl = rrb->pitch >> 7;
2263 offset += ((y >> 3) * nmacroblkpl) << 11;
2264 offset += (y & 7) << 8;
2265 offset += (x >> 7) << 11;
2266 offset += ((x & 127) >> 4) << 5;
2267 offset += (x & 15) << 2;
2268 }
2269 } else {
2270 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2271 offset += (y * nmicroblkpl) << 5;
2272 offset += (x >> 4) << 5;
2273 offset += (x & 15) << 2;
2274 }
2275 }
2276 return &ptr[offset];
2277 }
2278
2279 GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
2280 GLint x, GLint y)
2281 {
2282 GLubyte *ptr = rrb->bo->ptr;
2283 const __DRIdrawablePrivate *dPriv = rrb->dPriv;
2284 uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
2285 GLint offset;
2286 GLint microblkxs;
2287 GLint macroblkxs;
2288 GLint nmacroblkpl;
2289 GLint nmicroblkpl;
2290
2291 x += dPriv->x;
2292 y += dPriv->y;
2293
2294 if (rrb->has_surface || !(rrb->bo->flags & mask)) {
2295 offset = x * rrb->cpp + y * rrb->pitch;
2296 } else {
2297 offset = 0;
2298 if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
2299 if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
2300 microblkxs = 16 / rrb->cpp;
2301 macroblkxs = 128 / rrb->cpp;
2302 nmacroblkpl = rrb->pitch / macroblkxs;
2303 offset += ((y >> 4) * nmacroblkpl) << 11;
2304 offset += ((y & 15) >> 1) << 8;
2305 offset += (y & 1) << 4;
2306 offset += (x / macroblkxs) << 11;
2307 offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
2308 offset += (x & (microblkxs - 1)) * rrb->cpp;
2309 } else {
2310 microblkxs = 32 / rrb->cpp;
2311 macroblkxs = 256 / rrb->cpp;
2312 nmacroblkpl = rrb->pitch / macroblkxs;
2313 offset += ((y >> 3) * nmacroblkpl) << 11;
2314 offset += (y & 7) << 8;
2315 offset += (x / macroblkxs) << 11;
2316 offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
2317 offset += (x & (microblkxs - 1)) * rrb->cpp;
2318 }
2319 } else {
2320 microblkxs = 32 / rrb->cpp;
2321 nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
2322 offset += (y * nmicroblkpl) << 5;
2323 offset += (x / microblkxs) << 5;
2324 offset += (x & (microblkxs - 1)) * rrb->cpp;
2325 }
2326 }
2327 return &ptr[offset];
2328 }
2329
2330
2331 static void map_buffer(struct gl_renderbuffer *rb, GLboolean write)
2332 {
2333 struct radeon_renderbuffer *rrb = (void*)rb;
2334 int r;
2335
2336 if (rrb->bo) {
2337 r = radeon_bo_map(rrb->bo, write);
2338 if (r) {
2339 fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
2340 __FUNCTION__, r);
2341 }
2342 }
2343 }
2344
2345 static void unmap_buffer(struct gl_renderbuffer *rb)
2346 {
2347 struct radeon_renderbuffer *rrb = (void*)rb;
2348
2349 if (rrb->bo) {
2350 radeon_bo_unmap(rrb->bo);
2351 }
2352 }
2353
2354 void radeonSpanRenderStart(GLcontext * ctx)
2355 {
2356 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2357 int i;
2358
2359 rmesa->vtbl.flush_vertices(rmesa);
2360
2361 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
2362 if (ctx->Texture.Unit[i]._ReallyEnabled)
2363 ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
2364 }
2365
2366 /* color draw buffers */
2367 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
2368 map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE);
2369 }
2370
2371 map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE);
2372
2373 if (ctx->DrawBuffer->_DepthBuffer) {
2374 map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE);
2375 }
2376 if (ctx->DrawBuffer->_StencilBuffer)
2377 map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE);
2378
2379 /* The locking and wait for idle should really only be needed in classic mode.
2380 * In a future memory manager based implementation, this should become
2381 * unnecessary due to the fact that mapping our buffers, textures, etc.
2382 * should implicitly wait for any previous rendering commands that must
2383 * be waited on. */
2384 LOCK_HARDWARE(rmesa);
2385 radeonWaitForIdleLocked(rmesa);
2386 }
2387
2388 void radeonSpanRenderFinish(GLcontext * ctx)
2389 {
2390 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2391 int i;
2392 _swrast_flush(ctx);
2393 UNLOCK_HARDWARE(rmesa);
2394
2395 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
2396 if (ctx->Texture.Unit[i]._ReallyEnabled)
2397 ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
2398 }
2399
2400 /* color draw buffers */
2401 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
2402 unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
2403
2404 unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer);
2405
2406 if (ctx->DrawBuffer->_DepthBuffer)
2407 unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
2408 if (ctx->DrawBuffer->_StencilBuffer)
2409 unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
2410 }
2411
2412 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
2413 {
2414 struct radeon_cs_space_check bos[1];
2415 int flushed, ret;
2416
2417 size = MAX2(size, MAX_DMA_BUF_SZ * 16);
2418
2419 if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
2420 fprintf(stderr, "%s\n", __FUNCTION__);
2421
2422 if (rmesa->dma.flush) {
2423 rmesa->dma.flush(rmesa->glCtx);
2424 }
2425
2426 if (rmesa->dma.nr_released_bufs > 4) {
2427 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2428 rmesa->dma.nr_released_bufs = 0;
2429 }
2430
2431 if (rmesa->dma.current) {
2432 radeon_bo_unref(rmesa->dma.current);
2433 rmesa->dma.current = 0;
2434 }
2435
2436 again_alloc:
2437 rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
2438 0, size, 4, RADEON_GEM_DOMAIN_GTT,
2439 0);
2440
2441 if (!rmesa->dma.current) {
2442 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2443 rmesa->dma.nr_released_bufs = 0;
2444 goto again_alloc;
2445 }
2446
2447 rmesa->dma.current_used = 0;
2448 rmesa->dma.current_vertexptr = 0;
2449
2450 bos[0].bo = rmesa->dma.current;
2451 bos[0].read_domains = RADEON_GEM_DOMAIN_GTT;
2452 bos[0].write_domain =0 ;
2453 bos[0].new_accounted = 0;
2454
2455 again:
2456 ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1);
2457 if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
2458 fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
2459 assert(0);
2460 } else if (ret == RADEON_CS_SPACE_FLUSH) {
2461 rcommonFlushCmdBuf(rmesa, __FUNCTION__);
2462 if (flushed) {
2463 fprintf(stderr,"flushed but still no space\n");
2464 assert(0);
2465 }
2466 flushed = 1;
2467 goto again;
2468 }
2469
2470
2471 radeon_bo_map(rmesa->dma.current, 1);
2472 }
2473
2474 /* Allocates a region from rmesa->dma.current. If there isn't enough
2475 * space in current, grab a new buffer (and discard what was left of current)
2476 */
2477 void radeonAllocDmaRegion(radeonContextPtr rmesa,
2478 struct radeon_bo **pbo, int *poffset,
2479 int bytes, int alignment)
2480 {
2481 if (RADEON_DEBUG & DEBUG_IOCTL)
2482 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
2483
2484 if (rmesa->dma.flush)
2485 rmesa->dma.flush(rmesa->glCtx);
2486
2487 assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr);
2488
2489 alignment--;
2490 rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
2491
2492 if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size)
2493 radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
2494
2495 *poffset = rmesa->dma.current_used;
2496 *pbo = rmesa->dma.current;
2497 radeon_bo_ref(*pbo);
2498
2499 /* Always align to at least 16 bytes */
2500 rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
2501 rmesa->dma.current_vertexptr = rmesa->dma.current_used;
2502
2503 assert(rmesa->dma.current_used <= rmesa->dma.current->size);
2504 }
2505
2506 void radeonReleaseDmaRegion(radeonContextPtr rmesa)
2507 {
2508 if (RADEON_DEBUG & DEBUG_IOCTL)
2509 fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current);
2510 if (rmesa->dma.current) {
2511 rmesa->dma.nr_released_bufs++;
2512 radeon_bo_unmap(rmesa->dma.current);
2513 radeon_bo_unref(rmesa->dma.current);
2514 }
2515 rmesa->dma.current = NULL;
2516 }
2517
2518
2519 /* Flush vertices in the current dma region.
2520 */
2521 void rcommon_flush_last_swtcl_prim( GLcontext *ctx )
2522 {
2523 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2524 struct radeon_dma *dma = &rmesa->dma;
2525
2526
2527 if (RADEON_DEBUG & DEBUG_IOCTL)
2528 fprintf(stderr, "%s\n", __FUNCTION__);
2529 dma->flush = NULL;
2530
2531 if (dma->current) {
2532 GLuint current_offset = dma->current_used;
2533
2534 assert (dma->current_used +
2535 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
2536 dma->current_vertexptr);
2537
2538 radeon_bo_unmap(dma->current);
2539 if (dma->current_used != dma->current_vertexptr) {
2540 dma->current_used = dma->current_vertexptr;
2541
2542 rmesa->vtbl.swtcl_flush(ctx, current_offset);
2543 }
2544 radeonReleaseDmaRegion(rmesa);
2545 rmesa->swtcl.numverts = 0;
2546 }
2547 }
2548 /* Alloc space in the current dma region.
2549 */
2550 void *
2551 rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize )
2552 {
2553 GLuint bytes = vsize * nverts;
2554 void *head;
2555
2556 if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) {
2557 radeonRefillCurrentDmaRegion( rmesa, bytes);
2558 }
2559
2560 if (!rmesa->dma.flush) {
2561 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
2562 rmesa->dma.flush = rcommon_flush_last_swtcl_prim;
2563 }
2564
2565 ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
2566 ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim );
2567 ASSERT( rmesa->dma.current_used +
2568 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
2569 rmesa->dma.current_vertexptr );
2570
2571 // fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
2572 // rmesa->radeon.dma.current_vertexptr);
2573 head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr);
2574 rmesa->dma.current_vertexptr += bytes;
2575 rmesa->swtcl.numverts += nverts;
2576 return head;
2577 }